Telegram
Introduction
The Telegram connector receives messages from a Telegram bot, in direct chats with the owner and in any group the bot has been added to. It uses irazasyed/telegram-bot-sdk.
Setup
Create a bot with @BotFather to get a token. Then run:
php artisan laraclaw:setup-connector telegram
The wizard asks for the bot token and your Telegram chat ID, and writes:
LARACLAW_TELEGRAM_ENABLED=true
LARACLAW_TELEGRAM_TOKEN=...
It also creates a laraclaw_accounts row mapping your chat ID to the owner user.
Registering the Webhook
Laraclaw exposes the webhook at POST /telegram/webhook. Register it with Telegram by sending a setWebhook request:
curl -X POST "https://api.telegram.org/bot{TOKEN}/setWebhook" \
-d "url=https://your-app.com/telegram/webhook"
You may also do this from php artisan tinker:
Telegram::setWebhook(['url' => 'https://your-app.com/telegram/webhook']);
Webhook Authentication
Laraclaw does not verify a Telegram secret token on inbound webhook requests. Authentication is identity-based: every incoming chat ID is checked against laraclaw_accounts for DMs, and group messages are accepted on the assumption that whoever added the bot to the group is the owner.
This means anyone who guesses or learns your webhook URL can hit it with a forged update. The validation that follows will silently drop messages from unknown chat IDs, but the URL itself is unauthenticated.
If your install is exposed to the public internet, mitigate this by:
- Picking an unguessable URL path for the webhook (Telegram does not require
/telegram/webhook— you can route the package controller anywhere). - Restricting the route at the load balancer or WAF to Telegram's published IP ranges.
- Using
setWebhook'ssecret_tokenparameter and adding your own middleware that checks theX-Telegram-Bot-Api-Secret-Tokenheader.
Direct Messages
Direct messages have a positive chat ID. Only the registered owner may DM the bot. Messages from any other account are dropped during validation.
Each DM is one persistent conversation, keyed by the chat ID.
Groups
Group chats have a negative chat ID. The bot responds to anyone in the group, but tools always run as the owner regardless of who sent the message.
Each group is one persistent conversation, keyed by the group's chat ID.
Attachments
Inbound photos, voice notes, and documents are downloaded to inbound/{message_uuid}/ on the attachments disk. Voice messages are transcribed by the global TranscribeAudio agent middleware before the agent sees the message.
Outbound files are sent as the appropriate Telegram type:
- Audio →
sendVoice - Images →
sendPhoto - Everything else →
sendDocument
Confirmation Flow
When a tool requires confirmation, the agent asks yes/no in chat. The pending confirmation is stored in Redis. The next inbound message on that thread is parsed as the answer, and the tool either runs or is cancelled.