Connectors

Telegram

Wire Laraclaw up to a Telegram bot for direct messages and group chats.

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's secret_token parameter and adding your own middleware that checks the X-Telegram-Bot-Api-Secret-Token header.

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.

Copyright © 2026