A Telegram bot in n8n: inline buttons, menus and a Mini App button
In n8n a bot is built from a Telegram Trigger, a branch by event type and a send node. Inline button presses arrive as callback_query and need an answer. A button that opens a Mini App is easiest to send through HTTP Request, and a bot can have only one webhook.
In n8n you can build a bot without separate code: receiving messages, a menu, buttons and replies. Here is the workflow layout, button handling and a button that opens a Mini App.
What a bot in n8n consists of
- Telegram Trigger: receives updates (messages and button presses).
- A branch (Switch or IF): decides what arrived: a command, text or a button press.
- Processing nodes: database queries, APIs, calculations.
- A Telegram send node or HTTP Request: sends the reply to the user.
For the trigger to work permanently the workflow must be activated: test mode is only for checking, and the production webhook is registered on activation. n8n needs a public HTTPS address for that.
Commands and menu
Commands like /start arrive as ordinary messages, so check the beginning of the text in your branch. Command hints in the Telegram interface are set in @BotFather (the /setcommands command): that is just a list for the user, your workflow handles the logic.
Inline buttons
Inline buttons are sent in the message node through the keyboard setting (Reply Markup, Inline Keyboard). Each button has text and either callback_data or a link.
When a user presses a button with callback_data, Telegram sends a callback_query update, not a message. It contains the button data and a query identifier.
Important rules:
- Answer the press. You must call the answer to the callback query (in the Telegram node this is the Answer Query operation), otherwise the user sees a loading spinner on the button.
- Parse
callback_datawith a branch: for examplecatalog:next,sub:on,sub:off. Keep the values short: Telegram limits their length. - Edit the original message instead of sending a new one when it is a page or state switch. That keeps the chat clean.
A button that opens a Mini App
The easiest way to send a button that opens a Mini App is the HTTP Request node, calling the Bot API directly. The address is https://api.telegram.org/bot<token>/sendMessage, with a JSON body:
{
"chat_id": "{{ $json.message.chat.id }}",
"text": "Open the catalog",
"reply_markup": {
"inline_keyboard": [[
{ "text": "Catalog", "web_app": { "url": "https://example.com/app" } }
]]
}
}
The Mini App address must be reachable over HTTPS. Keep the bot token in n8n credentials, not in the node text.
Pitfalls
- One webhook per bot. A bot can have only one active webhook. If you run a Telegram Trigger in n8n and also poll
getUpdatesfrom code or register another webhook, you get conflicts and lost messages. - Test and production addresses. In test mode the webhook has a different address. Do not leave a test URL on the bot.
- Repeated messages. Telegram retries delivery if it did not get a quick reply. Avoid long operations before replying and protect critical actions from repeats (remember the
update_id). - Sending limits. Do not send many messages in a row: use pauses and a queue.
- User-facing errors. If a database query fails, send a clear message instead of leaving the bot silent.
Where this is used
n8n runs, for example, the HotTrip AI consultant: n8n receives messages, calls tools and APIs, and replies arrive in Telegram. In projects with a Mini App the bot's buttons lead into the app. Details are in the HotTrip and Da Nang House projects and in Telegram bots and Mini Apps and Process automation.
FAQ
Do I need code to build a bot in n8n?
For a typical bot, no: the menu, buttons, replies and API requests are built from nodes. You need code for non-standard logic or features the Telegram node does not have.
Why does a button “hang” after a press?
The answer to the callback query was not sent. Add the answer operation to your workflow.
Can I build a bot and a Mini App together?
Yes. The bot sends a button with `web_app`, the Mini App opens inside Telegram and calls your API. User data must be verified by the `initData` signature.
What if the bot stopped receiving messages?
Check that the workflow is activated, that the bot has the right webhook set and that no other process uses the same token.
Plain version for AI and reading without styling: Markdown.