Triggers
A trigger decides when a flow runs. Every flow declares exactly one. This page is an overview of all trigger kinds with a quick example each; for the precise argument and filter reference, see Statement Reference β Triggers.
Commandβ
Runs when a user sends a slash command.
flow help on command "/help" {
send.text("Here's how I workβ¦")
}
Message (with filters)β
Runs on incoming messages. An optional filter restricts it to a content type.
// Any text message
flow echo on message [text] {
send.text(`You said: ${message.text}`)
}
// Only photos
flow on_photo on message [photo] {
send.text("Nice photo!")
}
Filters: text, photo, video, audio, voice, document, sticker, animation, contact, location, poll, dice, any.
Callback (and prefix)β
Runs when an inline keyboard button is tapped. The string matches the button's callback_data. A trigger ending in : is a prefix match β it catches any payload starting with that prefix.
flow open_menu on callback "menu" {
send.text("Main menu")
}
// Prefix: matches "buy:coffee", "buy:tea", β¦
flow buy on callback "buy:" {
set { flow.item = str.split(callback.data, ":")[1] }
send.text(`You picked ${flow.item}`)
}
See Dynamic keyboards for prefix routing patterns.
Schedule (cron)β
Runs on a cron schedule. The flow has no chat in scope, so send to an explicit chat_id.
// Every day at 09:00
flow daily on schedule "0 9 * * *" {
send.text("Good morning! βοΈ", chat_id: shared.group_chat_id)
}
Webhookβ
Runs when an external system sends an HTTP request to your bot's webhook URL β used for payment confirmations, third-party callbacks, and integrations.
flow ping on webhook "health" {
respond.text("ok")
}
Webhooks support signature verification, typed bodies, and custom responses. See Statement Reference β Webhooks and Payments & webhooks.
Group eventsβ
For bots in groups and channels, these fire on membership changes:
flow greet on join {
set { flow.name = member.new_chat_member.user.first_name }
send.text(`π Welcome, ${flow.name}!`)
}
flow farewell on leave {
send.text("Someone left the group.")
}
flow review on join_request {
send.text(`Join request from ${request.from.first_name}`)
}
flow added on bot_added {
send.text("Thanks for adding me! Admin: run /setup here.")
}
flow removed on bot_removed { /* cleanup */ }
There's also a filtered member trigger for fine-grained membership events:
flow on_ban on member [banned] {
set { flow.name = member.new_chat_member.user.first_name }
send.text(`π¨ ${flow.name} was banned.`)
}
member filters: joined, left, banned, unbanned, promoted, demoted, restricted.
See Groups & admin and Groups & moderation for the full toolkit.
Payments (Telegram Stars)β
A Stars purchase fires two triggers: on pre_checkout validates the order (the runtime auto-approves so the charge proceeds), then on successful_payment delivers the goods.
flow precheck on pre_checkout {
// Validate; runtime auto-approves the pre_checkout_query.
debug.log(`Order: ${pre_checkout.invoice_payload} for β${pre_checkout.total_amount}`)
}
flow paid on successful_payment {
send.text(`β
Paid β${payment.total_amount} β unlocked!`)
}
Read pre_checkout.* (invoice_payload, total_amount, currency, id) and payment.* (total_amount, invoice_payload, telegram_payment_charge_id). Start an invoice with send.invoice.
Telegram Businessβ
For bots connected to a Telegram Business account. send.* inside these flows replies as the account owner.
flow concierge on business_message {
send.text(`Thanks! You said: ${business.text}`)
}
Triggers: on business_connection, on business_message, on edited_business_message, on deleted_business_messages. Read business.* (connection_id, text, from, can_reply, is_enabled, user).
Mini Apps, reactions, and inline modeβ
// Data sent from a Mini App (authenticate first)
flow on_webapp on web_app_data {
when crypto.verifyInitData(web_app.data, global.bot_token) {
send.text("Verified Mini App request.")
}
}
// A user adds/removes an emoji reaction
flow on_react on reaction {
when reaction.added { send.text(`Reacted: ${reaction.emoji}`) }
}
// Inline mode: @yourbot <query>
flow inline on inline_query {
answer_inline(inline.id, [{ id: "1", title: "Result", text: "Hi" }])
}
Read web_app.* (data, button_text), reaction.* (emoji, added, message_id, user), and inline.* (id, query, offset, from).
Trigger referenceβ
| Trigger | Fires when⦠|
|---|---|
on command "/x" | A user sends /x |
on message [filter] | A message of that content type arrives |
on callback "data" | A matching inline button is tapped (: = prefix) |
on schedule "cron" | The cron expression matches |
on webhook("name", β¦) | An HTTP request hits the webhook URL |
on join / on leave | A user joins / leaves a group |
on join_request | A user requests to join |
on bot_added / on bot_removed | The bot is added to / removed from a chat |
on member [filter] | A membership sub-event occurs |
on pre_checkout | A Stars purchase reaches pre-checkout |
on successful_payment | A Stars payment completes |
on business_connection | A Business account connects/disconnects the bot |
on business_message | A customer DMs a connected Business account |
on edited_business_message | A message in a connected Business chat is edited |
on deleted_business_messages | Messages in a connected Business chat are deleted |
on web_app_data | A Mini App sends data to the bot |
on reaction | A user adds/removes an emoji reaction |
on inline_query | A user types @yourbot <query> |