Documentation

@catalogicus-international/n8n-nodes-telegram-advance

An n8n community package for Telegram-native human-in-the-loop workflows.
It sends a question and waits for the user to respond inside Telegram with an
inline button or a reply. No n8n approval page, redirect link, or external
response form is opened.

The action nodes can also send documents, photos, videos, audio, voice messages,
and animations. A media file can come from an n8n binary field, a public HTTP(S)
URL, or an existing Telegram file_id. Binary uploads preserve the source
filename and MIME type and work with n8n's external binary storage.

Use Send Media for a fire-and-forget attachment. Use Media as the
Question Content in Send and Wait for Response to put the question in the
media caption and attach the inline buttons or force-reply markup to that same
Telegram message. Telegram limits media captions to 1024 characters.

Use Download File to turn an incoming Telegram file into n8n binary data.
The node can detect a document, photo, video, audio, voice message, or animation
from a trigger update (the largest available photo is selected), or accept an
explicit file_id. The output JSON contains Telegram getFile metadata and the
downloaded content is written to the configured binary field (data by default).
The cloud Telegram Bot API currently downloads files up to 20 MB; a local Bot API
server can support larger files.

Nodes

Telegram Advance

Use this node to send a regular Telegram message or wait until a human responds.
When asking a question, the node sends the message and then polls Telegram
(getUpdates) itself until the user answers or the wait limit is reached — all
within a single execution. The send-and-wait operation supports:

  • Approval — approve and decline inline buttons;
  • Choice — custom inline buttons, for example a product or delivery option;
  • Linked List — select one item, open its URL, then finish the workflow;
  • Radio Buttons — select one item, then confirm with a submit button;
  • Checkboxes — select any number of items, then confirm with a submit button;
  • Free Text — the user replies directly to the bot message.

Approval questions can also show a non-clickable, left-aligned list above the
approve and decline buttons. Set Display List to an expression returning an
array of strings, numbers, or objects with a label field:

{{ $json.items.map((item) => ({
  label: item.name + ' — ' + item.price
})) }}

Choice, radio-button, and checkbox options can be defined manually or generated
from an expression. Select Expression as the choice source and return an
array of objects containing label and value, for example:

{{ $json.items.map((item, index) => ({
  label: item.name + ' — ' + item.price,
  value: index
})) }}

For radio buttons, checkboxes, and linked lists, label may contain line
breaks. Add optional price and currencyCode fields to show a highlighted
right-side price in radio/checkbox rows. Linked lists show the same price on a
separate line inside the selectable row so long product names do not hide it:

{{ $json.items.map((item, index) => ({
  label: item.name + '\n' + item.package,
  value: index,
  price: item.price,
  currencyCode: item.currency
})) }}

Linked lists use the same source modes, but every item also needs a link
field. Each row shows a multi-line selectable item with an inline Перейти
URL button on the right, and the ✅ Завершить button returns the selected
item to the next workflow step:

{{ $json.items.map((item) => ({
  label: item.name,
  value: item.sku,
  link: item.url,
  price: item.price,
  currencyCode: item.currency
})) }}

The node resumes with data shaped like:

{
  "response": {
    "type": "choice",
    "value": "sku-123",
    "label": "Product A",
    "user": {
      "id": 123456789,
      "username": "example"
    },
    "chat": {
      "id": 123456789
    },
    "questionMessageId": 42,
    "receivedAt": "2026-06-21T12:00:00.000Z"
  }
}

Approval responses also contain approved: true or approved: false.
Free-text responses contain text and return the same value in value.
Radio and checkbox responses return zero-based selected option indexes in
value and selectedIndices, plus the configured option values and labels:

{
  "response": {
    "type": "checkbox",
    "value": [0, 2],
    "selectedIndices": [0, 2],
    "values": ["sku-123", "sku-789"],
    "labels": ["Product A", "Product C"]
  }
}

Linked-list responses return the selected item and the pressed finish button:

{
  "response": {
    "type": "linkedList",
    "value": "cement-akkermann-m500-50",
    "label": "Цемент AKKERMANN М500 50 кг 670 ₽",
    "link": "https://example.com/cement-akkermann-m500-50",
    "selectedIndex": 0,
    "buttonValue": "finish",
    "buttonLabel": "✅ Завершить"
  }
}

Wait settings

  • Wait Limit Amount / Unit — how long the node keeps polling before giving
    up. The node holds the execution open for this whole time, so prefer minutes
    for interactive approvals.
  • On Timeout — return a { "timedOut": true } item so you can branch on it,
    or throw an error.

Telegram Advance Trigger

Use this trigger to start a workflow from incoming Telegram messages, edited
messages, channel posts, or callback queries. It uses long polling, so it does
not require a public webhook URL. You can optionally restrict events by chat or
sender ID.

The trigger shares the same per-bot update stream as waiting questions. This
lets one bot receive ordinary updates while also handling Telegram Advance
approval, choice, and reply waits.

Telegram Advance AI Webhook

Use this node when an n8n AI Agent should call Telegram as a tool while answers
arrive through Telegram webhooks. It exposes the same send and send-and-wait
surface as Telegram Advance Webhook, declares usableAsTool, and relies on an
active Telegram Advance Webhook Trigger on the same bot to deliver button
presses and free-text replies to the waiting execution.

Setup

  1. Create a bot with BotFather and copy its token.
  2. Create Telegram Advance API credentials in n8n.
  3. Add Telegram Advance where the workflow should send a message or ask a
    question, and select the credentials.

No public URL, inbound HTTPS, or separate trigger is required — only outbound
access to api.telegram.org.

For free-text questions, the user must reply to the bot's question message.
This lets the node distinguish its own awaited answer from unrelated chat
messages.

Reliability notes

While a question is waiting, the node polls getUpdates from inside the running
execution, so the execution stays active (and holds a worker) until the user
answers or the wait limit elapses. Keep wait limits short for interactive
approvals.

Telegram permits only one getUpdates consumer per bot. Telegram Advance uses
one shared poller per bot inside an n8n process, so concurrent waiting questions
and trigger subscriptions in that process can coexist. Do not run another
Telegram poller for the same bot. Before polling, the node clears any existing
webhook so getUpdates can take over.

In queue mode, configure Redis in the credentials. Redis elects one polling
worker per bot and fans its updates out to the other workers, preventing
cross-worker 409 Conflict errors. It also keeps completed responses briefly
for first-answer-wins deduplication and pickup by concurrent executions. The
first Redis URL and namespace used in a process become process-wide, so use the
same Redis configuration for every Telegram Advance credential in that process.

A pending wait still lives in the worker that started it and does not survive
that worker restarting. If Redis is unavailable, the package logs a warning and
falls back to process-local polling.

Development

pnpm install
pnpm run lint
pnpm test

Resources

License

MIT

Discussion