Skip to content

Updating visuals

If you see any images containing outdated UI, please bear with us.

We are updating all content as quickly as possible to mirror our new UI.

Telegram integration

Telegram lets your app message users through a Telegram bot: send texts, photos, documents and inline keyboards, edit or delete messages, and react to incoming messages and button taps via webhook triggers.

Use cases

  • Send notifications to users or groups (order updates, alerts, reminders)
  • Build a support or assistant bot that replies to incoming messages
  • Send interactive messages with inline keyboard buttons and react to taps
  • Deliver files and images (reports, invoices, media) from backend workflows

Setup

  1. Open @BotFather in Telegram and send the /newbot command.
  2. Choose a name and a username for your bot — BotFather replies with an API token.
  3. In WeWeb, open the Data & API tab, then the Integrations subtab. Select Telegram, then click Add Connection.
  4. Paste the Bot Token and click Verify — WeWeb confirms which bot the token belongs to. The connection applies to all environments (Editor, Staging, Production); to use different values per environment, override the generated environment variables.
  5. Test by sending a message: open a chat with your bot in Telegram, send it any message (a bot cannot message you first), then use Send Message with your chat ID.

Enabling triggers (webhook)

The two triggers (see below) require the connection's webhook:

  1. On the connection, set Telegram Webhook to Enabled and keep (or adjust) the Webhook Path (default /telegram/webhook).
  2. Save the connection and publish your project — the webhook route only exists after publishing.
  3. Click Set webhook on the connection. WeWeb registers the webhook with Telegram, including a secret token used to verify incoming requests.

ONE BOT TOKEN PER ENVIRONMENT

A Telegram bot holds a single webhook URL. Clicking Set webhook from one environment overwrites the webhook of the others and silently kills their triggers. If you use triggers in more than one environment, create a separate bot (and token) per environment.

Triggers

With the webhook enabled and set, two backend triggers become available:

On message received

Runs each time someone sends a message to your bot — e.g. reply with Send Message bound to event.chat.id.

Example event

json
{
  "message_id": 2,
  "from": { "id": 123456789, "is_bot": false, "first_name": "Jane", "language_code": "en" },
  "chat": { "id": 123456789, "first_name": "Jane", "type": "private" },
  "date": 1787574749,
  "text": "Hello"
}

On button tapped

Runs when someone taps an inline keyboard button (with callback_data) sent by your bot. Answer it with Answer Callback Query bound to event.id — until answered, the user sees a loading spinner on the button. Branch on event.data (the button's callback_data) to route different buttons in one workflow.

Example event

json
{
  "id": "4382156871125391245",
  "from": { "id": 123456789, "is_bot": false, "first_name": "Jane", "language_code": "en" },
  "message": {
    "message_id": 5,
    "chat": { "id": 123456789, "first_name": "Jane", "type": "private" },
    "date": 1787574749,
    "text": "Pick an option"
  },
  "data": "confirm"
}

Common pitfalls (setup & usage)

Bots cannot message a user first

Sending to a user who never started your bot fails with 403 bot can't initiate conversation with a user, and an unknown chat ID fails with 400 chat not found. The user must have started the bot (or share a group with it). Chat IDs usually come from trigger events (event.chat.id) — there is no API to list a bot's chats.

MarkdownV2 formatting errors

MarkdownV2 requires escaping special characters (., !, -, (, ), #, etc.) with \, and unescaped characters fail with a 400 error — the most common send failure. For dynamic content, prefer HTML formatting (<b>, <i>, <a href>) or plain text.

Media URL fails to load

Telegram fetches photo and document URLs server-side. Auth-gated links or URLs that return an HTML page fail with 400 failed to get HTTP URL content. Use a publicly accessible direct file URL (max 5 MB for photos, 20 MB for documents by URL), or reuse the file_id of an already-sent file.

Group privacy mode

By default, a bot in a group only receives commands, replies to its own messages, and messages that mention it. To receive all group messages, disable privacy mode via @BotFather with /setprivacy.

Callback queries expire in seconds

Answer every On button tapped trigger with Answer Callback Query first, then do slower work. Late answers fail with 400 query is too old, and unanswered buttons show a spinner to the user for ~30 seconds.

All Actions

This integration provides seven actions mapped to the Telegram Bot API.

ActionDescription
Send MessageSend a text message, optionally formatted and with an inline keyboard
Send PhotoSend a photo by public URL or Telegram file_id
Send DocumentSend a file of any type by public URL or Telegram file_id
Edit Message TextEdit the text (and inline keyboard) of a message the bot sent
Delete MessageDelete a message
Get ChatGet up-to-date information about a chat
Answer Callback QueryAnswer an inline keyboard button tap

Action details

Send Message

Send a text message from the bot to a chat, optionally formatted (MarkdownV2/HTML) and with an inline keyboard.

Inputs

Display KeyExample InputDescriptionRestrictions
Chat ID"123456789"Unique identifier of the target chat, or a channel username (@channelusername). Usually bound from a trigger event (event.chat.id).Required; the user must have started the bot
Text"Your order has shipped!"Text of the message.1–4096 characters after parsing
Formatting
Optional
"HTML"How Telegram parses the text. Empty = plain text.Valid: MarkdownV2, HTML
Reply to message ID
Optional
42Send this message as a reply to another message in the same chat.Number
Inline keyboard
Optional
{"inline_keyboard":[[{"text":"Confirm","callback_data":"confirm"}]]}Raw InlineKeyboardMarkup object: rows of buttons, each with a text and a url or callback_data. Tapping a callback_data button fires the On button tapped trigger.Valid InlineKeyboardMarkup object
Send silently
Optional
falseUsers receive the message without a notification sound.Boolean
Protect content
Optional
falsePrevents the message from being forwarded or saved.Boolean

Example output

json
{
  "message_id": 2,
  "chat": { "id": 123456789, "type": "private" },
  "date": 1787574749,
  "text": "Your order has shipped!"
}

Documentation of API endpoint that powers action: Telegram Bot API – sendMessage (POST /sendMessage)

Send Photo

Send a photo from the bot to a chat, by public URL or Telegram file_id.

Inputs

Display KeyExample InputDescriptionRestrictions
Chat ID"123456789"Unique identifier of the target chat, or a channel username.Required
Photo"https://example.com/image.jpg"A publicly accessible image URL (Telegram fetches it server-side) or a Telegram file_id of an already-sent photo.Max 5 MB by URL
Caption
Optional
"Our new office!"Photo caption.0–1024 characters after parsing
Formatting
Optional
"HTML"How Telegram parses the caption. Empty = plain text.Valid: MarkdownV2, HTML
Reply to message ID
Optional
42Send as a reply to another message in the same chat.Number
Inline keyboard
Optional
{"inline_keyboard":[[{"text":"View","url":"https://example.com"}]]}Raw InlineKeyboardMarkup object.Valid object
Send silently
Optional
falseNo notification sound.Boolean
Protect content
Optional
falsePrevents forwarding or saving.Boolean

Example output

json
{
  "message_id": 3,
  "chat": { "id": 123456789, "type": "private" },
  "date": 1787574749,
  "photo": [ { "file_id": "AgADAgADwqcxGy…", "width": 320, "height": 320 } ],
  "caption": "Our new office!"
}

Documentation of API endpoint that powers action: Telegram Bot API – sendPhoto (POST /sendPhoto)

Send Document

Send a file (any type) from the bot to a chat, by public URL or Telegram file_id.

Inputs

Display KeyExample InputDescriptionRestrictions
Chat ID"123456789"Unique identifier of the target chat, or a channel username.Required
Document"https://example.com/report.pdf"A publicly accessible file URL (Telegram fetches it server-side) or a Telegram file_id of an already-sent file.Max 20 MB by URL
Caption
Optional
"Monthly report attached"Document caption.0–1024 characters after parsing
Formatting
Optional
"HTML"How Telegram parses the caption. Empty = plain text.Valid: MarkdownV2, HTML
Reply to message ID
Optional
42Send as a reply to another message in the same chat.Number
Inline keyboard
Optional
{"inline_keyboard":[[{"text":"Open","url":"https://example.com"}]]}Raw InlineKeyboardMarkup object.Valid object
Send silently
Optional
falseNo notification sound.Boolean
Protect content
Optional
falsePrevents forwarding or saving.Boolean

Example output

json
{
  "message_id": 4,
  "chat": { "id": 123456789, "type": "private" },
  "date": 1787574749,
  "document": { "file_id": "BQADAgADy6cxGy…", "file_name": "report.pdf", "mime_type": "application/pdf" },
  "caption": "Monthly report attached"
}

Documentation of API endpoint that powers action: Telegram Bot API – sendDocument (POST /sendDocument)

Edit Message Text

Edit the text (and optionally the inline keyboard) of a message previously sent by the bot.

Inputs

Display KeyExample InputDescriptionRestrictions
Chat ID"123456789"The chat containing the message.Required
Message ID42Identifier of the target message (message_id from a sent or received message).Required
New text"Order status: shipped ✅"New text of the message.1–4096 characters after parsing
Formatting
Optional
"HTML"How Telegram parses the new text. Empty = plain text.Valid: MarkdownV2, HTML
Inline keyboard
Optional
{"inline_keyboard":[[{"text":"Track","url":"https://example.com"}]]}Replace the message's inline keyboard.Valid object

Editing a message with identical content fails with 400 message is not modified — guard workflows that might re-apply the same edit.

Example output

json
{
  "message_id": 42,
  "chat": { "id": 123456789, "type": "private" },
  "date": 1787574749,
  "text": "Order status: shipped ✅"
}

Documentation of API endpoint that powers action: Telegram Bot API – editMessageText (POST /editMessageText)

Delete Message

Delete a message. Only works within 48 hours of the message being sent (including the bot's own messages); deleting others' messages additionally requires the bot to be a group admin.

Inputs

Display KeyExample InputDescriptionRestrictions
Chat ID"123456789"The chat containing the message.Required
Message ID42Identifier of the message to delete.Required; within 48h of sending

Example output

json
true

Documentation of API endpoint that powers action: Telegram Bot API – deleteMessage (POST /deleteMessage)

Get Chat

Get up-to-date information about a chat (private chat, group, supergroup or channel).

Inputs

Display KeyExample InputDescriptionRestrictions
Chat ID"123456789"Unique identifier of the chat, or a channel username.Required

Example output

json
{
  "id": 123456789,
  "type": "private",
  "first_name": "Jane",
  "username": "janed"
}

Documentation of API endpoint that powers action: Telegram Bot API – getChat (POST /getChat)

Answer Callback Query

Answer a callback query from an inline keyboard button tap. Call it after every On button tapped trigger — until answered, the user sees a loading spinner on the button.

Inputs

Display KeyExample InputDescriptionRestrictions
Callback query ID"4382156871125391245"Identifier of the query to answer — bind event.id from the On button tapped trigger.Required; queries expire within seconds
Notification text
Optional
"Done!"Text shown to the user as a notification at the top of the chat. Empty = just stop the spinner.0–200 characters
Show as alert
Optional
falseShow the text as a modal alert instead of a passing notification.Boolean
Cache time (seconds)
Optional
0Maximum time Telegram clients may cache this answer, in seconds.Number

Example output

json
true

Documentation of API endpoint that powers action: Telegram Bot API – answerCallbackQuery (POST /answerCallbackQuery)

Error handling

Error code and typeReason
400 Bad RequestUnknown chat (chat not found), unreachable media URL (failed to get HTTP URL content), unescaped MarkdownV2 characters, identical edit (message is not modified), or late callback answer (query is too old).
401 UnauthorizedInvalid bot token.
403 ForbiddenThe user never started the bot (bot can't initiate conversation with a user), or the bot was blocked or lacks group permissions.
429 Too Many RequestsRate limited — the response includes parameters.retry_after (seconds to wait). Telegram allows roughly 1 message/second per chat, 20/minute per group, and ~30/second overall.

FAQs

How do I find my chat ID?

Enable the webhook, send a direct message to your bot, and read event.chat.id from the On message received trigger event. There is no API to list a bot's chats.

Why don't my triggers fire?

Check, in order: the webhook is Enabled on the connection, the project has been published (the webhook route only exists after publishing), and you clicked Set webhook afterwards. Also note a bot has a single webhook URL — setting the webhook from another environment overwrites it.

Should I use MarkdownV2 or HTML formatting?

For dynamic content, prefer HTML (<b>, <i>, <a href>): MarkdownV2 requires escaping many special characters with \ and unescaped input fails with a 400 error. If you don't need styling, leave Formatting empty for plain text.

Why doesn't my bot see group messages?

Group privacy mode is on by default: the bot only receives commands, replies to its own messages, and mentions. Disable privacy via @BotFather with /setprivacy to receive all group messages.

How do I send interactive buttons and react to taps?

Send a message with an Inline keyboard whose buttons carry callback_data. When a user taps one, the On button tapped trigger fires with the button's callback_data in event.data — answer it with Answer Callback Query (bound to event.id) first, then run your logic.

Can I upload a file directly from a workflow?

No — media is sent by public URL (or by reusing a Telegram file_id from a previously sent file). Binary upload from workflows is not supported.