Receiving messages
Every message the bot is to get becomes an update. The bot either fetches its updates (long polling) or gets them posted to its address (webhook), one or the other.
Long polling
The bot calls GET /updates in a loop:
- The first request:
offset=0&timeout=30. - If there are updates, the answer comes at once. If not, the server holds the request for up to 30 seconds and answers as soon as an update appears, or with an empty array
[]when the time is up. - Having handled the updates, the bot passes
offset= the highestupdate_idreceived + 1 in the next request. The server deletes the updates below it.
Until the bot passes an offset above an update's id, that update comes in every answer again: a bot that crashed gets what it had not handled after a restart. Updates are kept for 24 hours. A bot's update_ids grow without gaps in the order the messages appeared.
Keep one poll per bot. The HTTP client must wait longer than timeout: with timeout=30, at least 40 seconds.
Webhook
After POST /webhook Marx posts every update to the address set:
POST /marx HTTP/1.1
Host: bot.example.org
Content-Type: application/json
User-Agent: marx-bot-webhook
X-Marx-Bot-Secret: Zr4q-8NnYtV2
{"update_id": 7, "chat": {"id": 812, "type": "group", "title": "Dacha"}, "message": {…}}
- The body is one update, the same as an item of the
GET /updatesanswer. - Compare
X-Marx-Bot-Secretwith the secret given toPOST /webhook, and answer 403 to anything else. - A 2xx answer means the update is delivered and deleted. Any other status, no answer within 10 seconds or a connection error: the same update is posted again after 1 second, then 2, 4 and so on, at least once every 60 seconds.
- One bot's updates go one at a time and in order: the next one is not posted until the previous one is accepted.
- The address is
https://only, with a valid certificate and a public IP address; redirects are not followed. - An update can come again after the bot has handled it (for example, when the answer was lost), so reply through
POST /messageswith aclient_idbuilt from theupdate_id.
DELETE /webhook returns the bot to long polling; updates not yet posted stay and come through GET /updates.
Update
| Field | Meaning |
|---|---|
update_id | The update's id for this bot |
chat.id | Chat id: the chat_id to reply to |
chat.type | direct or group |
chat.title | The group's title |
message | The message |
Message
The same object the app gets about a new message. A full example is in the answer of GET /updates. The fields a bot needs:
| Field | Meaning |
|---|---|
id | Message id: the message_id for POST /reactions |
chat_id | Chat id |
sender_id | The sender's account id |
author | The sender: id, display_name, username (may be null), avatar_url, is_bot |
type | text, image, video, file, voice, poll and others |
body | The message text; for a poll, its description in JSON |
caption | Caption of a picture, video or file |
created_at | When it was sent, ISO 8601 in UTC |
media_url, media, attachments | Attachments: the file's address and description |
file_name, file_size, duration_ms | File name and size, length of a video or voice message |
reply_to_message_id, quote | The message this one replies to, and its quote |
poll | A poll: question, options, votes |
forwarded_from_user_id, forwarded_from_chat_id, forwarded_from_name | Where it was forwarded from |
The other fields are for the app's display and are usually empty in messages to a bot. New fields may appear: do not reject an answer with an unknown field.
What a bot sees
| Chat | What the bot gets |
|---|---|
| Direct, with a person | Every message of the person |
| Group | Messages that start with a command: /command or /command@this_bot (but not /command@another_bot); messages that mention the bot, @bot_username; replies to this bot's messages |
| Channel | Nothing: in a channel a bot only publishes |
Never delivered: the bot's own messages, messages of other bots, the chat's service lines (a member joined, the chat was renamed). A bot does not see a group's ordinary conversation.
Commands
A command is a message that starts with /: /today, /today@dacha_weather_bot, /today Moscow. In a group with several bots, the name after @ says which bot it is for.
The app shows the command list with descriptions in the menu of a chat with the bot. It is set with PUT /commands or with /setcommands at @marxbot.
- Up to 100 commands.
- A command is 1 to 32 characters of
a-z,0-9,_, without/; no command twice. - A description is not empty and up to 256 characters.
Parsing a command is up to the bot's program: the update carries the message text as it is.