Telegram plugin¶
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: 14 total; see the complete catalog below
- ingress adapter:
telegram.update- poller:
telegram.updates
Supported actions: complete catalog¶
The Telegram plugin currently registers 14 actions. This list is intended to be the authoritative enumeration of the supported Call Baxter Telegram action surface.
Messaging and media¶
| Action | Purpose | Required args | Optional args |
|---|---|---|---|
telegram.send_message |
Send a text message. Also serves as the normal reply/respond action. | chat_id, text |
reply_to_message_id, reply_markup |
telegram.send_photo |
Upload and send a photo. | chat_id, filename, data |
caption |
telegram.send_document |
Upload and send a document. | chat_id, filename, data |
caption |
For telegram.send_photo and telegram.send_document, data is a latin-1 string
whose code points represent the original byte values. This matches the binary-string
convention used by other Call Baxter plugin actions.
There is no separate reply action because a Telegram reply is a normal
telegram.send_message with reply_to_message_id set:
- kind: telegram.send_message
args:
chat_id: "{{ event.attrs.chat_id }}"
reply_to_message_id: "{{ event.attrs.message_id }}"
text: "Received."
Message mutation and moderation¶
| Action | Purpose | Required args | Optional args |
|---|---|---|---|
telegram.edit_message_text |
Edit a bot-authored text message in place. | chat_id, message_id, text |
reply_markup |
telegram.set_message_reaction |
Set an emoji reaction on a message. | chat_id, message_id, emoji |
is_big |
telegram.delete_message |
Delete a message when the bot has permission. | chat_id, message_id |
— |
telegram.pin_chat_message |
Pin a message when the bot has permission. | chat_id, message_id |
disable_notification |
telegram.unpin_chat_message |
Unpin a specific message. | chat_id, message_id |
— |
Example reaction rule action:
- kind: telegram.set_message_reaction
args:
chat_id: "{{ event.attrs.chat_id }}"
message_id: "{{ event.attrs.message_id }}"
emoji: "👍"
Callback and structured operator interaction¶
| Action | Purpose | Required args | Optional args |
|---|---|---|---|
telegram.answer_callback_query |
Acknowledge/respond to an inline-keyboard callback query. | callback_query_id |
text, show_alert |
telegram.request_decision |
Send a deterministic multi-option decision prompt with inline buttons. | chat_id, text, correlation_id, source, options |
timeout_seconds, default_action, reply_to_message_id |
telegram.request_confirmation |
Send an auditable approve/reject confirmation prompt. | chat_id, text, correlation_id, source |
timeout_seconds, default_action, approve_label, reject_label, reply_to_message_id |
telegram.send_progress |
Send a structured progress/phase tracker message. | chat_id, title, phases, current_phase |
status, detail, reply_to_message_id |
telegram.update_progress |
Update an existing structured progress tracker in place. | chat_id, message_id, title, phases, current_phase |
status, detail |
Projection/storage¶
| Action | Purpose | Required args | Optional args |
|---|---|---|---|
telegram.persist_update |
Persist a raw Telegram update into the tg-agent-cli projection database. |
database_url, update |
bot_ref, source, bot_token, api_base, media_storage_mode, media_base_dir |
The first 13 actions above mutate Telegram remotely and therefore use Call Baxter's
external/non-idempotent action execution contract. telegram.persist_update is a
projection/storage action and has a separate execution contract.
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 messaging, replies, media, reactions, edits, deletion, pinning, callbacks, confirmations, decisions, and progress/status messages
- 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