Appearance
Telegram Bot Quickstart
This is the shortest path for a fresh agent session that only knows a Hooka server URL (for example https://hooka.example.com) and needs to build a Telegram bot.
Hooka is the bus:
- Telegram input is captured into an input topic.
- An external worker reads that topic over SSE.
- The worker calls the model/runtime.
- The worker publishes replies to an output topic.
- Hooka delivers the replies to Telegram.
Keep model execution outside the Hooka server. Hooka owns delivery, history, routes, retries, chat actions, and Telegram metadata; the bridge owns sessions, tools, prompts, and workspace mutation.
What You Need
From the Hooka server you use:
HOOKA_URL=https://hooka.example.comHOOKA_API_KEY: a master key or scoped token that can read the input topic and publish to the output topic- a Telegram chat ID, usually discovered by inviting the Hooka bot and sending
/chatid; in forum groups the reply also shows the current thread ID and any hooka topics bound to the chat/thread./webhookmints an anonymous POST URL that delivers into the current chat without an API key.
To run the server yourself (see the README quickstart), you also need:
TELEGRAM_BOT_TOKENfrom BotFatherDATABASE_URLAPI_KEY
If you do not have a Hooka API key, stop and ask the operator for one. The public URL intentionally does not mint credentials by itself.
Topic Shape
Use one pair of topics per bot:
bash
export HOOKA_URL="https://hooka.example.com"
export HOOKA_API_KEY="<scoped-read-publish-token>"
export BOT_IN_TOPIC="telegram-bot-in"
export BOT_OUT_TOPIC="telegram-bot-out"
export TELEGRAM_CHAT_ID="-1001234567890"Recommended token scope:
json
{
"name": "telegram-bot",
"can_publish": true,
"can_read": true,
"topic_pattern": "telegram-bot-*"
}1. Verify Access
bash
curl -sS "$HOOKA_URL/health"
curl -sS "$HOOKA_URL/topics/$BOT_OUT_TOPIC/routes" \
-H "Authorization: Bearer $HOOKA_API_KEY"The second command may return an empty route list. A 401 means the token is missing, invalid, or not scoped for the topic.
2. Connect Telegram Output
Route bot replies to the Telegram chat:
bash
curl -sS -X POST "$HOOKA_URL/topics/$BOT_OUT_TOPIC/routes" \
-H "Authorization: Bearer $HOOKA_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"provider\":\"telegram\",\"chat_id\":\"$TELEGRAM_CHAT_ID\",\"parse_mode\":\"HTML\"}"Send a test reply:
bash
curl -sS -X POST "$HOOKA_URL/publish/$BOT_OUT_TOPIC" \
-H "Authorization: Bearer $HOOKA_API_KEY" \
-H "Idempotency-Key: quickstart-output-test" \
-H "Content-Type: application/json" \
-d '{"title":"Bot online","text":"Hooka can deliver replies to this chat.","priority":3,"tags":["bot","smoke"]}'Do not continue until the Telegram chat receives the message.
3. Connect Telegram Input
If inbound capture is enabled on the server, configure the current chat from Telegram:
text
/capture telegram-bot-in
/capture_statusThen send a normal Telegram message in that chat. Verify Hooka stored it:
bash
curl -sS "$HOOKA_URL/topics/$BOT_IN_TOPIC/messages?limit=5&include_payload=true" \
-H "Authorization: Bearer $HOOKA_API_KEY"For groups and forum topics, Telegram privacy mode matters. If /capture works but normal messages never appear, turn privacy mode off in BotFather, promote the bot to admin, or remove and re-add the bot after changing privacy.
If inbound capture is not available, publish prompts into the input topic from your own Telegram adapter or test manually:
bash
curl -sS -X POST "$HOOKA_URL/publish/$BOT_IN_TOPIC" \
-H "Authorization: Bearer $HOOKA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"User message","text":"hello","priority":3,"tags":["telegram","inbound","user"]}'4. Run A Bridge
Use the Go bridge when you want the standard Hooka-to-agent loop:
bash
hooka-agent-bridge \
--hooka-url "$HOOKA_URL" \
--hooka-api-key "$HOOKA_API_KEY" \
--input-topic "$BOT_IN_TOPIC" \
--output-topic "$BOT_OUT_TOPIC" \
--include-payload \
--forward-telegram-target \
--backend opencodeUse --backend pi for Pi RPC mode. See AGENT_BRIDGE.md for backend flags and deployment options.
The standard bridge streams input and publishes replies. Typing indicators, inline keyboards, and session commands are custom-bridge responsibilities unless your selected backend/bridge layer implements them.
At minimum, any custom bridge must do this:
- Open
GET /topics/{input}/stream?include_payload=true. - Dedupe messages by
StoredMessage.id. - Send
POST /send-chat-actionwith{"topic":"<output-topic>","action":"typing"}when Telegram metadata containschat_id; thetopicfield matters when using a scoped token. - Call the model/runtime with the inbound
text. - Publish the answer to
POST /publish/{output}. - Preserve Telegram
chat_idandmessage_thread_idwhen replying to the originating chat/thread.
5. Fluent Telegram UX Checklist
For a bot that feels good in Telegram:
- Show
typingwhile work is in progress in a custom bridge. - Reply to the originating chat and forum thread, not only the default route.
- Use
/new,/stop, and/statusas session controls. - Keep input and output topics separate to avoid loops.
- Add deterministic
Idempotency-Keyvalues when retrying. - Use
reply_markup.inline_keyboardfor obvious actions. - Keep messages under Telegram limits; split long outputs.
- Return friendly errors to Telegram and write full errors to logs.
- Store session memory in the bridge/runtime, not in Hooka core.
Smoke Test
After the bridge starts, send this through Telegram or publish it manually:
bash
curl -sS -X POST "$HOOKA_URL/publish/$BOT_IN_TOPIC" \
-H "Authorization: Bearer $HOOKA_API_KEY" \
-H "Idempotency-Key: quickstart-input-test" \
-H "Content-Type: application/json" \
-d '{"title":"User message","text":"Reply with one short sentence confirming the bot loop works.","tags":["telegram","inbound","smoke"]}'Then check the output:
bash
curl -sS "$HOOKA_URL/topics/$BOT_OUT_TOPIC/messages?limit=5" \
-H "Authorization: Bearer $HOOKA_API_KEY"The PR-quality definition of done is: the output topic has a reply, Telegram received it, duplicate smoke-test retries do not create duplicate replies, and the bridge logs show no unhandled stream reconnect or Telegram delivery errors.