In short: An MPChat bot today is a command + MiniApp product, not a Telegram-style in-bubble button product. answerCallbackQuery, editMessageReplyMarkup, and answerInlineQuery are not exposed. Put stateful interaction in a MiniApp, then have the bot update the original chat message with editMessageText.
Overview
This page is the product-facing companion to What is an MPChat bot?. That article lists limits. This one shows what you can ship by combining the methods currently documented at core.mp.net/bots.
Do not copy a Telegram bot 1:1. The method names look familiar; the interaction model is not. Read the core pattern first, then pick a scenario.
Capability building blocks
Group today's methods by what they let the product do, not by OpenAPI category:
Block | What it is for | Primary methods |
Outbound messages | Text, media, MiniApp entry, group @, link-preview control |
|
Message ops | Edit in place, pin, forward, copy, recall vs delete |
|
Group moderation | Mute (not kick), lift mute, edit group profile |
|
Group reads | Chat / member / admin metadata |
|
Command menu | Slash-command list the client shows |
|
MiniApp identity | Open the app, verify the user, route a screen |
|
Media methods accept a public URL or multipart upload. Existing file_id reuse is not supported. sendChatAction, sendLocation, and sendPoll currently return 501.
Core pattern: commands and MiniApps, not in-bubble buttons
Telegram's default UX is a button on the message that stays in the chat: the user taps callback_data, the bot receives callback_query, answers with answerCallbackQuery, and rewrites the keyboard with editMessageReplyMarkup.
On MPChat those three methods are listed under Common Bot API methods not currently exposed. MiniApp client return flows (web_app_data / sendData / answerWebAppQuery) are also not available. The replacement pattern is:
The user sends a command, or taps a
web_appbutton, or openshttps://mp.net/{botUsername}/{shortName}?startapp=….The MiniApp loads. Your frontend reads raw
window.MpChat.WebApp.initDataand posts it to your backend — never put the bot token in the WebView.The backend verifies
hashandauth_date, then trustsuser.id,miniapp_id, andstart_param.After the user finishes in the MiniApp, the backend calls Bot API
editMessageText(or sends a new message) so the chat reflects the result.
Use setMyCommands for the discoverable entry points (/start, /help, /status). Use the MiniApp for anything that needs a form, a list, or more than two choices.
Scenario: group ops and pinned broadcasts
A community bot that greets joiners and pins today's notice.
Receive
Update.message.new_chat_members(polling or webhook).sendMessagea welcome that @-mentions the new member withentitiestypetext_mention(see the invite scenario below).pinChatMessagethe daily notice. Group chats only; missing permission returns 403.Next day:
unpinChatMessage, thenrecallMessagethe stale notice so the timeline stays clean.recallMessageis an MPChat extension;deleteMessageremains the compatible delete.
Leave events arrive as Update.message.left_chat_member. Pins arrive as Update.message.pinned_message when the bot can see the message.
Scenario: approvals and tickets
Do not try to put Approve / Reject on the chat bubble. Open a MiniApp instead, then write the decision back into the original message.
When a request is created,
sendMessagea summary plus aweb_appbutton whoseurlis the MiniAppentryUrl. The server resolves that URL to the current bot's MiniApp; you do not sendminiapp_id.To land on one ticket, also include a direct link in the text:
https://mp.net/{botUsername}/{shortName}?startapp=ticket_123.startappbecomes signedinitData.start_param. Do not bakestartappinto the MiniApp's savedentryUrl.The MiniApp shows Approve / Reject. After verify, your backend records the decision and calls
editMessageTexton the originalmessage_id:Approved by @Chen.
If the message should stay text-only (no MiniApp card), set link_preview_options.is_disabled = true on the same sendMessage. The server still checks that web_app.url belongs to an enabled MiniApp owned by this bot.
{
"chat_id": "12345",
"text": "Leave request ticket_123 — open to review",
"link_preview_options": { "is_disabled": true },
"reply_markup": {
"inline_keyboard": [[
{
"text": "Review",
"web_app": { "url": "https://mini.example.com/demo" }
}
]]
}
}
Scenario: event invites with group mentions
A MiniApp collects who to invite; the bot then @-mentions them in the group so they get a reminder. Official shape:
{
"chat_id": "12345",
"text": "@Chen @Lei invites you to this activity",
"entities": [
{
"type": "text_mention",
"offset": 0,
"length": 5,
"user": { "id": "2000000154" }
},
{
"type": "text_mention",
"offset": 6,
"length": 4,
"user": { "id": "2000000168" }
}
]
}
Rules that matter in production:
entitiescurrently supports onlytext_mention. The official reference does not state which encodingoffset/lengthcount in, and every example uses ASCII names — test with a non-ASCII display name before you ship, or the highlight will land on the wrong characters.Each target must already be in the group. @all is not supported. Nicknames and fuzzy matches are not inferred.
If a group
sendMessageomitsentitiesentirely, the server tries to resolve raw@usernametext by unique group-member username and auto-fillstext_mention. Ambiguous text stays plain.Do not combine
entitieswith aweb_appMiniApp entry card.web_appmessages also skip username auto-fill.
Scenario: a refreshable status board
Keep one message and overwrite it instead of flooding the chat.
sendMessagethe first snapshot. Storechat_id+message_id.On each refresh,
editMessageTextthat same message. Only text messages are editable; 404 if missing, 403 if the bot does not own it.For a chart,
sendPhotowith a public image URL (or multipart). You cannot reuse a previousfile_id, so host the image yourself and send a new URL each time.
There is no sendChatAction typing indicator (501). If generation takes a few seconds, send a short placeholder first, then editMessageText the final copy.
Scenario: content moderation
An admin bot that cleans spam and mutes repeat offenders.
recallMessage/recallMessages(MPChat extension) or the compatibledeleteMessage/deleteMessages.In groups, an administrator bot with the Recall messages permission can recall regular members' messages. It cannot recall messages from the owner or other administrators — that returns 403.
Batch recall / delete is all-or-nothing: if any id fails the precondition, the whole request errors and nothing is partially applied.
banChatMembermutes the member; it does not remove them from the chat.until_date=0or omitted means until you callunbanChatMember.
There is no createChatInviteLink / kick-and-unban cycle. To grow a group, share a MiniApp direct link with ?startapp= as your attribution tag, then have a human (or a separate product flow) add people.
Scenario: support routing and membership tiers
A support MiniApp that already knows who opened it.
Verify raw
initDatabefore you read any user field.initDataUnsafeis display-only.user.emailis an MPChat extension: it appears in the signeduserJSON only when the user has authorized and an Email exists; otherwise the field is omitted. Never treat a missing Email as a failed signature.user.is_premium(when present) is the hook for a paid-tier queue vs a free-tier queue.After the agent closes the ticket in the MiniApp,
editMessageTextorsendMessagea transcript line back into the chat so the thread stays auditable.
Telegram initData has no Email field. Do not assume a Telegram MiniApp sample will parse user.email.
What you cannot ship today — and the workaround
Telegram-style play | MP today | What to do instead |
In-bubble multi-step buttons |
|
|
Inline query |
|
|
Polls |
| MiniApp ballot; bot posts the result |
Location / check-in |
| Collect location inside the MiniApp |
"Typing…" indicator |
| Placeholder text, then |
Read a file the user sent |
| Ask them to upload inside the MiniApp |
Invite-link growth loops |
| MiniApp direct link + |
Kick a member |
| Mute via API; remove via a human admin |
Payments, Stars, gifts, stickers, reactions, persistent reply keyboard | Not exposed | No Bot API substitute in this phase |
Related
This page describes the method set published on core.mp.net/bots today. Confirm that page before you depend on a method that is not listed above.







