PHPackages                             padosoft/laravel-rebel-channel-telegram - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. padosoft/laravel-rebel-channel-telegram

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

padosoft/laravel-rebel-channel-telegram
=======================================

Telegram bot delivery channel for Laravel Rebel Channels: deliver OTP codes and security alerts to a Telegram chat. Part of padosoft/laravel-rebel-\*.

v0.1.1(1mo ago)06MITPHPPHP ^8.3CI passing

Since Jun 4Pushed 1mo agoCompare

[ Source](https://github.com/padosoft/laravel-rebel-channel-telegram)[ Packagist](https://packagist.org/packages/padosoft/laravel-rebel-channel-telegram)[ Docs](https://github.com/padosoft/laravel-rebel-channel-telegram)[ RSS](/packages/padosoft-laravel-rebel-channel-telegram/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (20)Versions (4)Used By (0)

Laravel Rebel — Telegram Channel
================================

[](#laravel-rebel--telegram-channel)

> Official documentation:

> **Deliver OTP codes and security alerts straight to Telegram, the Rebel way.** This package plugs the [Telegram Bot API](https://core.telegram.org/bots/api) into [`laravel-rebel-channels`](https://github.com/padosoft/laravel-rebel-channels) as a `MessageDeliveryChannel` — so a Telegram chat becomes a first-class, **free**, self-hosted delivery target for verification codes and alerts, *plus* Rebel's HMAC'd audit trail and graceful fallback on top. Part of the `padosoft/laravel-rebel-*` suite.

 [![Laravel Rebel](resources/screenshoots/Laravel-Rebel-banner.png)](resources/screenshoots/Laravel-Rebel-banner.png)

 [![Laravel 12|13](https://camo.githubusercontent.com/9e9b743bcbf97a29fe735334a4a8e906d05d60310969905af6607cef8da30138/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d313225323025374325323031332d4646324432303f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/9e9b743bcbf97a29fe735334a4a8e906d05d60310969905af6607cef8da30138/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d313225323025374325323031332d4646324432303f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465) [![PHP 8.3+](https://camo.githubusercontent.com/6aa777dd33ef43fbef727d8187b578003a61e5dc41bbc958b0938c996cdc92f2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e33253230253743253230382e34253230253743253230382e352d3737374242343f7374796c653d666c61742d737175617265266c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/6aa777dd33ef43fbef727d8187b578003a61e5dc41bbc958b0938c996cdc92f2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e33253230253743253230382e34253230253743253230382e352d3737374242343f7374796c653d666c61742d737175617265266c6f676f3d706870266c6f676f436f6c6f723d7768697465) [![PHPStan max](https://camo.githubusercontent.com/4b9a3c97d76534abb905e64bd9e5bb9f13fe68e962071e0ccbbe7b629112f11c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6d61782d3241364644423f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/4b9a3c97d76534abb905e64bd9e5bb9f13fe68e962071e0ccbbe7b629112f11c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6d61782d3241364644423f7374796c653d666c61742d737175617265) [![Pest 4](https://camo.githubusercontent.com/9b9da1d7d243a7465ab338e9374e47300a7fe2e26b5c291e7e3c95b53153789a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d50657374253230342d3232433535453f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/9b9da1d7d243a7465ab338e9374e47300a7fe2e26b5c291e7e3c95b53153789a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d50657374253230342d3232433535453f7374796c653d666c61742d737175617265) [![Telegram Bot API](https://camo.githubusercontent.com/c36df0984ec39ea9e64cffa251c4987f87630309aee3f75c3c635fe849e53a17/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54656c656772616d2d426f742532304150492d3236413545343f7374796c653d666c61742d737175617265266c6f676f3d74656c656772616d266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/c36df0984ec39ea9e64cffa251c4987f87630309aee3f75c3c635fe849e53a17/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54656c656772616d2d426f742532304150492d3236413545343f7374796c653d666c61742d737175617265266c6f676f3d74656c656772616d266c6f676f436f6c6f723d7768697465) [![MIT](https://camo.githubusercontent.com/ac049ef4e7a0b7196b09add6ac2d4f180e544c0ac779c2b2ac2fd2723a209579/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75653f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/ac049ef4e7a0b7196b09add6ac2d4f180e544c0ac779c2b2ac2fd2723a209579/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75653f7374796c653d666c61742d737175617265)

---

Table of contents
-----------------

[](#table-of-contents)

- [What it is](#what-it-is)
- [Quick glossary](#quick-glossary)
- [Why this package](#why-this-package)
- [Rebel + Telegram vs the alternatives](#rebel--telegram-vs-the-alternatives)
- [Telegram bot setup (step by step)](#telegram-bot-setup-step-by-step)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
- [Telemetry (audit events)](#telemetry-audit-events)
- [Live tests against the real API](#live-tests-against-the-real-api)
- [`.env.example`](#envexample)
- [Security notes](#security-notes)
- [Testing &amp; License](#testing--license)

---

What it is
----------

[](#what-it-is)

A thin, well-tested **Telegram bot** delivery channel for Rebel Channels. It implements the Channels `MessageDeliveryChannel` contract, so once registered it can deliver any message — an OTP code, a "new login from a new device" alert, a step-up prompt — to a Telegram chat.

A small **gateway seam** (`TelegramGateway`) wraps the Telegram Bot API over plain HTTP, so the whole thing is unit-testable offline and has a real **live** test-suite for the actual API.

> **No phone number on Telegram.** Telegram identifies a destination by **chat\_id** (a user, group or channel), not a phone. This package reuses the recipient's `PhoneIdentifier` normalized value as the chat\_id — so the same Channels API works unchanged. See [Telegram bot setup](#telegram-bot-setup-step-by-step)for how to get a chat\_id.

Depends on [`padosoft/laravel-rebel-core`](https://github.com/padosoft/laravel-rebel-core)and [`padosoft/laravel-rebel-channels`](https://github.com/padosoft/laravel-rebel-channels).

---

Quick glossary
--------------

[](#quick-glossary)

TermIn plain words**Bot**A Telegram account driven by your code, created via [@BotFather](https://t.me/BotFather).**Bot token**The secret that authenticates your bot (e.g. `123456789:AAE...`). Keep it out of logs.**chat\_id**Where a message goes: a user, a group (negative id) or a channel (`@name` or id). The "recipient".**parse\_mode**Optional message formatting: `MarkdownV2`, `HTML`, or plain text (default).**Delivery channel**A Rebel `MessageDeliveryChannel`: it `send()`s a message and reports success/failure.---

Why this package
----------------

[](#why-this-package)

★WhatIn short★★★**OTP + alerts over Telegram**Deliver verification codes and security alerts to any Telegram chat via a bot.★★★**Free + self-hosted**No per-message cost, no third-party SaaS — your bot, your token, the public Bot API.★★★**Rebel guarantees for free**Inherits the Channels routing/fallback and a full HMAC'd audit trail.★★**Never throws out**Any transport/API error becomes a clean `provider_error`, so the router can fall back.★★**Offline-testable**A gateway seam + fake means your tests don't hit Telegram; a separate live suite does.★★**Safe by default**No bot token → nothing registers, and no unauthenticated gateway is ever built.★**Token never leaks**The bot token lives only inside the gateway and is excluded from every error message.---

Rebel + Telegram vs the alternatives
------------------------------------

[](#rebel--telegram-vs-the-alternatives)

Delivering an OTP / security alert to Telegram, four ways:

Capability**Rebel + this package**Shopify`telegram-bot/api` SDK (direct)Raw `curl` to the Bot APISelf-hosted Telegram OTP / alert channel✅❌➖ (you wire it yourself)➖ (you wire it yourself)Free (no per-message SaaS cost)✅❌✅✅Implements a unified delivery contract✅❌❌❌**Provider fallback** to another channel✅❌❌❌Unified audit trail (chat\_id HMAC'd)✅❌❌❌Telemetry into a Channel-Performance panel✅➖❌❌Graceful failure → router fallback✅❌❌❌Bot token kept out of logs by design✅➖❌❌> Legend: ✅ built-in · ➖ partial / hosted-only / DIY · ❌ not available. **Shopify** is a closed, hosted commerce platform: it sends its own customer OTPs over SMS/email and gives you **no** self-hosted Telegram channel, no way to deliver your app's alerts to a Telegram chat, no provider fallback, and no developer-facing audit of delivery — a black box, not a delivery library. The raw SDK / `curl` options can talk to Telegram, but you build the contract, fallback, audit and token-hygiene yourself — which is exactly what this package gives you for free.

---

Telegram bot setup (step by step)
---------------------------------

[](#telegram-bot-setup-step-by-step)

1. **Create a bot.** Open Telegram, start a chat with [@BotFather](https://t.me/BotFather), send `/newbot`, pick a display name and a username ending in `bot`. BotFather replies with your **bot token** (e.g. `123456789:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`). Keep it secret.
2. **Get a chat\_id.** Telegram won't let a bot message a user who hasn't contacted it first.
    - **1:1 chat:** have the user send `/start` to your bot, then call `https://api.telegram.org/bot/getUpdates` and read `result[].message.chat.id`.
    - **Group:** add the bot to the group, post any message, then read the (negative) `chat.id`from `getUpdates`.
    - **Channel:** add the bot as an admin and use `@channelusername` (or the numeric id).
3. Put the token in your `.env` (see below). Done — the channel auto-registers.

> **Tip:** a dedicated "security alerts" group with your bot as a member is a great place to fan out alerts; set its id as `TELEGRAM_DEFAULT_CHAT_ID` for your host app to reuse.

---

Installation
------------

[](#installation)

```
composer require padosoft/laravel-rebel-channel-telegram
php artisan vendor:publish --tag="rebel-channel-telegram-config"
```

Add your bot token to `.env`:

```
TELEGRAM_BOT_TOKEN=123456789:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

That's it — the delivery channel registers itself under the key `telegram` (bound to the `MessageDeliveryChannel` contract and tagged `rebel-channels.delivery`).

---

Configuration
-------------

[](#configuration)

File `config/rebel-channel-telegram.php`:

KeyDefaultWhat it does`bot_token``env(TELEGRAM_BOT_TOKEN)`The @BotFather token. Required for the channel to register.`default_chat_id``env(TELEGRAM_DEFAULT_CHAT_ID)`Optional fallback chat\_id (e.g. an alerts group) for the host app.`register_provider``true`Auto-register the channel (only when a bot token is also present).`parse_mode``null`Telegram formatting: `null` (plain), `MarkdownV2` or `HTML`.`timeout``10`HTTP timeout (seconds) for the Bot API before a send fails gracefully.---

Usage
-----

[](#usage)

The channel is resolvable from the container under the `MessageDeliveryChannel` contract (or the `rebel-channels.delivery` tag, so multiple delivery channels can coexist):

```
use Padosoft\Rebel\Channels\Contracts\MessageDeliveryChannel;
use Padosoft\Rebel\Channels\Enums\Channel;
use Padosoft\Rebel\Core\Context\SecurityContext;
use Padosoft\Rebel\Core\Identifiers\PhoneIdentifier;

$telegram = app(MessageDeliveryChannel::class);

// The "recipient" is the Telegram chat_id, carried by a PhoneIdentifier.
$chat = PhoneIdentifier::from('123456789');           // a user/group/channel id

$result = $telegram->send(
    $chat,
    "Your login code is 123456. It expires in 5 minutes.",
    Channel::Telegram,
    new SecurityContext('req-1'),                      // or SecurityContext::fromRequest($request, $hasher)
);

if ($result->accepted()) {
    // delivered — $result->reference is the Telegram message_id
}
```

To resolve **all** registered delivery channels (e.g. to pick by `supports()`):

```
use Padosoft\Rebel\Channel\Telegram\RebelTelegramServiceProvider;

foreach (app()->tagged(RebelTelegramServiceProvider::DELIVERY_TAG) as $channel) {
    if ($channel->supports(Channel::Telegram)) {
        $channel->send($chat, $message, Channel::Telegram, $context);
    }
}
```

> The send is **synchronous**: when `send()` returns `accepted()`, Telegram has accepted the message — the send *is* the receipt, so there is no separate status webhook to wire.

---

Telemetry (audit events)
------------------------

[](#telemetry-audit-events)

Every send records exactly one Rebel audit event through the core `AuditLogger`, so the admin panel's **Channel Performance** reflects real Telegram delivery. The chat\_id is stored **only as a keyed HMAC**, never in clear, and the bot token never appears anywhere.

OutcomeAudit `event_type`Message accepted by Telegram`channel.delivery.sent`Transport / API error (graceful failure)`channel.delivery.failed`Each event carries `channel: 'telegram'`, `provider: 'telegram'`, the HMAC'd chat\_id, and a `metadata`object:

```
{
  "message_status": "sent",
  "error_code": null,
  "message_id": "4242"
}
```

On failure, `message_status` is `"failed"`, `error_code` is `"provider_error"`, and `message_id` is `null`.

---

Live tests against the real API
-------------------------------

[](#live-tests-against-the-real-api)

The offline suite uses a fake gateway. To exercise the **real** Telegram Bot API (`tests/Live`), opt in explicitly — it **sends a real message**:

```
# .env (or shell env)
REBEL_TELEGRAM_LIVE=1
TELEGRAM_BOT_TOKEN=123456789:AAE...
TELEGRAM_TEST_CHAT_ID=123456789     # a chat that has /start-ed your bot

vendor/bin/pest --group=live
```

Without `REBEL_TELEGRAM_LIVE=1` or with any value missing, the live tests **self-skip**, so `composer test` and external PRs never trigger a send. In CI, supply the values as **secrets** and set `REBEL_TELEGRAM_LIVE=1` on a dedicated job.

---

`.env.example`
--------------

[](#envexample)

```
TELEGRAM_BOT_TOKEN=123456789:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TELEGRAM_DEFAULT_CHAT_ID=
REBEL_TELEGRAM_REGISTER=true
TELEGRAM_PARSE_MODE=
TELEGRAM_TIMEOUT=10

# Live tests (opt-in: SENDS A REAL MESSAGE)
REBEL_TELEGRAM_LIVE=0
TELEGRAM_TEST_CHAT_ID=
```

---

Security notes
--------------

[](#security-notes)

- **No unauthenticated gateway**: the Telegram gateway is only constructed when a bot token is present.
- **Token never logged**: the bot token lives only inside `HttpTelegramGateway` (and the request URL it builds) and is excluded from every error message surfaced to your app.
- **No exception leakage**: transport/API errors are caught and returned as a generic `provider_error`, so the router can fall back to another channel.
- **chat\_id is HMAC'd**: the recipient is stored in the audit trail only as a keyed HMAC, never in clear.
- **Plain text by default**: `MarkdownV2` / `HTML` parse modes require escaping special characters in the message body — that escaping is the caller's responsibility.

---

🔋 Vibe coding with batteries included
-------------------------------------

[](#-vibe-coding-with-batteries-included)

This package ships **AI batteries** — so you (and your AI agent) can extend it correctly on the first try:

- **`CLAUDE.md`** — a concise AI working guide (purpose, conventions, architecture, how to extend, Definition of Done). Plain Markdown, so Claude Code, Cursor, Copilot and Codex all read it.
- **`AGENTS.md`** — the agent/workflow contract (branch → PR → CI → tag/release, the gates).
- **`.claude/skills/`** — invocable skills (at least `rebel-package-dev`) encoding the suite's TDD loop, the **PHPStan-level-max** recipes, the security/telemetry rules, and the release discipline.

Open the repo in your AI editor and just start — the rules, guardrails and extension recipes come with it. PRs that follow the shipped `CLAUDE.md` pass CI (PHPStan max + Pest + Pint) and review the first time around.

Testing &amp; License
---------------------

[](#testing--license)

```
composer test      # Pest (delivery channel + gateway + registration; live suite self-skips)
composer phpstan   # static analysis, level max
composer pint      # code style
```

**License:** MIT — see [LICENSE](LICENSE). Part of the [`padosoft/laravel-rebel`](https://github.com/padosoft) suite.

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance91

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

51d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/10467699?v=4)[Lorenzo](/maintainers/lopadova)[@lopadova](https://github.com/lopadova)

---

Top Contributors

[![lopadova](https://avatars.githubusercontent.com/u/10467699?v=4)](https://github.com/lopadova "lopadova (5 commits)")

---

Tags

laravelotpAuthenticationalertsbottelegrampadosoftRebel

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/padosoft-laravel-rebel-channel-telegram/health.svg)

```
[![Health](https://phpackages.com/badges/padosoft-laravel-rebel-channel-telegram/health.svg)](https://phpackages.com/packages/padosoft-laravel-rebel-channel-telegram)
```

###  Alternatives

[defstudio/telegraph

A laravel facade to interact with Telegram Bots

813336.8k3](/packages/defstudio-telegraph)[harris21/laravel-fuse

Circuit breaker for Laravel queue jobs. Protect your workers from cascading failures.

45955.7k](/packages/harris21-laravel-fuse)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3914.8k](/packages/rawilk-profile-filament-plugin)[masterix21/laravel-licensing

Laravel licensing package with polymorphic assignment to any model, activation keys, expirations/renewals, and seat control via LicenseUsage. Supports offline verification with public-key–signed tokens, a CLI to generate/rotate/revoke keys, and an extensible architecture via config and contracts.

1613.3k4](/packages/masterix21-laravel-licensing)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.6k](/packages/simplestats-io-laravel-client)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
