Telegram plugin sketch¶
The Telegram plugin in this scaffold contributes:
- event definitions:
telegram.message.newtelegram.message.editedtelegram.channel_post.newtelegram.channel_post.editedtelegram.business_message.newtelegram.business_message.editedtelegram.callback_query.newtelegram.media.presenttelegram.message.reaction- action definitions:
telegram.send_messagetelegram.answer_callback_querytelegram.persist_update- ingress adapter:
telegram.update- poller:
telegram.updates
Why this matters¶
If the runtime already exposes HTTP ingress, a Telegram webhook can hit the callback runtime directly. That means a dedicated Telegram daemon is no longer required for event-driven automation.
Webhook ingress and polling both flow through the same Telegram plugin update pipeline:
raw update
-> optional projection persistence into tg-agent-cli db
-> normalized telegram.* events
-> generic call-baxter rule matching
What telegram.callback_query.new does¶
This event represents an incoming callback query, typically triggered by a user pressing an inline keyboard button. It carries:
callback_query_idcallback_ref- callback
data - optional
from_user_id - the raw update payload
- optional originating
chat_ref/message_ref
That makes it the event to match when you want to:
- answer the callback query
- branch on button payload data
- correlate the button press with the message that contained the inline keyboard
Message events also expose optional from_is_bot. This is useful when a callback
update includes the original bot-authored message and a rule must avoid recursively
processing that synthetic parent message.
Inline keyboards¶
telegram.send_message accepts an optional structured reply_markup object. For
example:
- kind: telegram.send_message
args:
chat_id: "{{ event.attrs.chat_id }}"
text: Choose an action
reply_markup:
inline_keyboard:
- - text: Status
callback_data: cmd:status
The Telegram API client also accepts a JSON string for compatibility, validates that it decodes to an object, and sends it as a JSON object in the Bot API request.
The client validates Telegram text boundaries before making a request:
telegram.send_messagerequires 1–4096 characters;telegram.answer_callback_queryaccepts at most 200 characters.
This makes invalid rules fail as audited action results locally instead of depending on a remote Bot API rejection.
What can move into call-baxter¶
Good fits for the generic runtime:
- webhook ingestion of raw Telegram updates
getUpdatespolling through the Telegram poller- normalization of updates into events
- outbound actions like
sendMessageandanswerCallbackQuery - YAML rules reacting to normalized message or callback-query events
Still valuable as a source-specific projection when needed:
- rich browse-first chat history UI
- Telegram-specific media storage policies
- advanced message/thread/entity indexing
- high-fidelity Bot API coverage across all update and media variants
So the pragmatic split is:
- use
call-baxteras the event runtime and control plane - keep
tg-agent-clias a separate browse/projection tool - let the Telegram plugin persist into the Telegram projection DB directly when configured
- keep
telegram.persist_updateavailable as an explicit action for unusual flows