DEV Community

unifyport for UnifyPort

Posted on • Originally published at unifyport.ai

Telegram Bot API 10.2 Migration Guide: Rich Messages, Ephemeral Edits, and Communities

Telegram Bot API 10.2 looks like a small version bump, but it changes several parts of a production bot at once:

  • Rich Messages gain typed blocks and embedded media
  • Ephemeral messages gain a complete edit and delete lifecycle
  • Communities introduce new topology events and metadata
  • Mini Apps receive stricter origin protection

Telegram released Bot API 10.2 on July 14, 2026. The safest upgrade is not to enable every new feature immediately. First update your data model and event dispatcher, then test each outbound capability behind a feature flag.

This guide turns the official Bot API 10.2 changelog into an implementation checklist.

Start with an impact map

Before changing code, separate the upgrade into four areas.

Area Main change Primary risk
Rich Messages media, blocks, and new InputRichBlock* types Invalid payloads or incomplete SDK serialization
Ephemeral messages Send, reply, edit, and delete lifecycle Losing the user-specific message identifiers
Communities New lifecycle fields and ChatFullInfo.community Dropping topology events in a default handler
Mini Apps Cross-origin method protection Previously working cross-origin calls being rejected

You do not have to enable every feature during the same deployment.

A reasonable rollout order is:

  1. Upgrade the library and types
  2. Accept and store the new fields
  3. Add dispatcher coverage
  4. Run regression tests
  5. Enable outbound features separately

1. Pin a compatible Bot API library

Check whether your Telegram library has released a version compatible with Bot API 10.2.

Before updating production, inspect:

  • Generated API types
  • Serialization of optional fields
  • Method names and parameter casing
  • Webhook update types
  • Retry and error behavior
  • Support for unknown message fields

Do not assume that upgrading the package automatically enables the new behavior. Some libraries may expose new types before fully supporting every method.

Pin the selected version instead of using an open-ended dependency range:

{
  "dependencies": {
    "your-telegram-library": "PINNED_COMPATIBLE_VERSION"
  }
}
Enter fullscreen mode Exit fullscreen mode

Run the upgrade in a branch and keep the previous dependency version available for rollback.

2. Audit Rich Message construction

Bot API 10.2 adds:

  • InputRichMessageMedia
  • InputMediaVoiceNote
  • media on InputRichMessage
  • blocks on InputRichMessage
  • A full set of InputRichBlock* builders

According to the Bot API reference, an InputRichMessage must use exactly one of these content representations:

  • html
  • markdown
  • blocks

If you generate payloads dynamically, validate that rule before making the API call.

function validateRichMessage(input: {
  html?: string;
  markdown?: string;
  blocks?: unknown[];
  media?: unknown[];
}) {
  const representations = [
    input.html,
    input.markdown,
    input.blocks,
  ].filter((value) => value !== undefined);

  if (representations.length !== 1) {
    throw new Error(
      "A rich message must contain exactly one of html, markdown, or blocks",
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

The new media field is used with media references embedded in HTML or Markdown, such as:

tg://photo?id=product_photo
Enter fullscreen mode Exit fullscreen mode

Review the following before enabling media:

  • Media identifiers are unique inside the payload
  • Referenced media actually exists in the media array
  • The bot has permission to send that media type
  • A plain-text fallback is available
  • Your SDK preserves every new field during serialization

Do not silently convert an existing Markdown builder into a block builder during the dependency upgrade. Treat that as a separate feature change.

3. Preserve the ephemeral message identity

Bot API 10.2 completes the ephemeral-message lifecycle with:

  • editEphemeralMessageText
  • editEphemeralMessageMedia
  • editEphemeralMessageCaption
  • editEphemeralMessageReplyMarkup
  • deleteEphemeralMessage

It also adds receiver_user and ephemeral_message_id to Message.

A normal message ID is not enough to manage an ephemeral message. Store the complete routing identity:

type EphemeralMessageReference = {
  chatId: string;
  receiverUserId: number;
  ephemeralMessageId: number;
};
Enter fullscreen mode Exit fullscreen mode

A library call may look similar to this, although the exact method naming depends on your SDK:

await bot.editEphemeralMessageText({
  chat_id: chatId,
  receiver_user_id: receiverUserId,
  ephemeral_message_id: ephemeralMessageId,
  text: "Your request has been updated.",
});
Enter fullscreen mode Exit fullscreen mode

Also review reply construction. In Bot API 10.2, ReplyParameters.message_id becomes optional when ephemeral_message_id is present.

Your implementation should test:

  • Sending to the intended user
  • Editing text
  • Editing media or captions
  • Updating reply markup
  • Deleting the message
  • Rejecting edits from the wrong user context
  • Handling an expired or unknown identifier
  • Preventing a retry from creating a duplicate reply

Ephemeral messages are user-specific. Never treat them as a group broadcast mechanism.

4. Add Community events to the dispatcher

Communities link supergroups, channels, and bots around a shared topic or audience.

Bot API 10.2 introduces:

  • Community
  • CommunityChatAdded
  • CommunityChatRemoved
  • message.community_chat_added
  • message.community_chat_removed
  • ChatFullInfo.community

A handler that only checks message.text may silently discard these service messages.

Add explicit branches:

function handleMessage(message: TelegramMessage) {
  if (message.community_chat_added) {
    recordCommunityChatAdded(message);
    return;
  }

  if (message.community_chat_removed) {
    recordCommunityChatRemoved(message);
    return;
  }

  if (message.text) {
    handleTextMessage(message);
    return;
  }

  handleUnknownMessageType(message);
}
Enter fullscreen mode Exit fullscreen mode

Do not use the Community ID as a replacement for the original chat ID.

A Community describes topology. Messages still need to be stored and routed according to their original chat identity.

A practical metadata model can retain both:

type CommunityChatRelation = {
  communityId: string;
  chatId: string;
  relationStatus: "active" | "removed";
  observedAt: string;
};
Enter fullscreen mode Exit fullscreen mode

When topology changes:

  1. Persist the lifecycle event
  2. Update the relation state
  3. Reconcile current information with getChat
  4. Keep an audit record
  5. Continue routing messages by their original chat ID

5. Handle the additional update type

Bot API 10.2 also adds BotSubscriptionUpdated and the subscription field on Update.

Even if your bot does not currently use payment subscriptions, make sure the webhook decoder does not reject an update merely because this field is present.

The safe pattern is:

  • Parse known top-level fields
  • Preserve unknown fields where possible
  • Log the event category without sensitive payload data
  • Route unsupported updates to an observable fallback
  • Avoid failing the entire webhook request

Returning a non-success response for every unknown update can create unnecessary retries.

6. Recheck Mini App origins

Telegram automatically enabled stricter Mini App origin protection on July 20, 2026, unless the bot opted out through BotFather.

Audit:

  • The configured Mini App domain
  • Redirect destinations
  • Embedded authentication pages
  • Payment or support pages
  • Calls made after navigation
  • Third-party content opened inside the Mini App
  • Development and staging domains

Do not solve an origin failure by broadly disabling protection without understanding which page initiated the call.

Test the production domain and each allowed non-production environment separately.

7. Avoid an unnecessary inbound rewrite

The new InputRichMessage builders primarily affect the outbound path.

They do not mean that every ordinary incoming user message must suddenly be parsed as a tree of rich blocks.

Your inbound work should focus on:

  • Recognizing the new Community service-message fields
  • Accepting subscription updates
  • Preserving new optional fields
  • Keeping an observable unknown-event fallback
  • Maintaining the existing text, media, and callback handling

This is a compatibility update, not a reason to replace a working inbound normalization pipeline.

8. Deploy behind separate feature flags

Use independent flags instead of one global “Bot API 10.2” switch.

const telegramFeatures = {
  richMessageBlocks: false,
  richMessageMedia: false,
  ephemeralEdits: false,
  communityTopology: true,
};
Enter fullscreen mode Exit fullscreen mode

This lets you accept Community events immediately while delaying new outbound formatting.

A safe rollout looks like this:

Upgrade dependency
        ↓
Accept new webhook fields
        ↓
Deploy with outbound flags disabled
        ↓
Verify normal inbound traffic
        ↓
Enable one outbound feature internally
        ↓
Monitor errors and payloads
        ↓
Expand gradually
Enter fullscreen mode Exit fullscreen mode

Monitor at least:

  • Telegram API error codes
  • Serialization failures
  • Unknown update counts
  • Community topology changes
  • Ephemeral edit/delete failures
  • Rich-message fallback usage
  • Webhook retry volume

9. Build a rollback path

Before production rollout, record:

  • Previous library version
  • New database fields
  • Feature-flag defaults
  • Payload format differences
  • Reversible and irreversible migrations
  • Rollback owner
  • Monitoring thresholds

If new fields are optional, prefer additive database changes. Do not make the previous application version unable to read records created during the rollout.

The rollback should disable new sends while still accepting already-delivered webhook fields.

Final upgrade checklist

  • [ ] Bot API library version is pinned
  • [ ] New SDK types and serialization have been inspected
  • [ ] Existing inbound regression tests pass
  • [ ] Exactly one Rich Message representation is enforced
  • [ ] Rich Message media references are validated
  • [ ] Plain-text fallbacks are available
  • [ ] Ephemeral message identifiers are persisted
  • [ ] Ephemeral edit and delete failure paths are tested
  • [ ] Community lifecycle events have explicit handler branches
  • [ ] Community topology is stored separately from chat routing
  • [ ] subscription updates do not break webhook decoding
  • [ ] Mini App production and staging origins have been checked
  • [ ] Outbound features use separate flags
  • [ ] Unknown updates remain observable
  • [ ] Dependency and feature rollback steps are documented

Bot API 10.2 is manageable when it is treated as several small migrations instead of one large feature launch.

Update the compatibility layer first. Enable Rich Messages, ephemeral editing, and Community-aware behavior only after the underlying fields, routing rules, and rollback path are ready.

Official references


Originally published on UnifyPort.

This article was prepared with AI assistance for language and structure, then technically reviewed and verified by the author.

Top comments (0)