Skip to content

Ephemeral messages: don't drop them when the sender isn't known locally - #2415

Open
dallo28 wants to merge 1 commit into
TelegramMessenger:masterfrom
dallo28:fix/ephemeral-unknown-bot
Open

dallo28 wants to merge 1 commit into
TelegramMessenger:masterfrom
dallo28:fix/ephemeral-unknown-bot

Conversation

@dallo28

@dallo28 dallo28 commented Oct 28, 2026

Copy link
Copy Markdown

Fixes https://bugs.telegram.org/c/67210: tapping a bot's button under a channel post does nothing unless you have opened that bot before. The bot gets the callback and sendMessage with ephemeral parameters returns ok, but the ephemeral message never appears. Searching for the bot once fixes it. Android and Desktop show it every time.

Cause

The server sends the bot's reply as updateShort(updateNewEphemeralMessage). updateShort carries no users, so the bot's user record isn't included.

apiEphemeralMessagePeerIds added the sender, the receiver and the reply peers to the peer ids of the update. verifyTransaction requires every one of them to be stored locally. With an unknown bot it fails, the whole update batch is dropped, and the client falls back to getDifference, as it does for regular messages. getDifference never returns ephemeral messages, so this one is lost.

From the reporter's log (13.1.1, channel 3824268692, bot 9120613204):

19:22:19.951 received Updates.updateShort(update: Update.updateNewEphemeralMessage(message: EphemeralMessage.ephemeralMessage(... fromId: Peer.peerUser(userId: 9120613204), peerId: Peer.peerChannel(channelId: 3824268692), ... message: the post is now unlocked, ... anchorMsgId: 5)), ...)
19:22:19.953 [State] missing peers [0:Id(rawValue: 9120613204)]
19:22:19.953 [State] failed to verify final state

The same three lines repeat on every tap.

Change

apiEphemeralMessagePeerIds now returns only the chat the message belongs to (Api.EphemeralMessage.peerId). It is used only for updateNewEphemeralMessage and updateEditEphemeralMessage. Regular messages, other updates in the same batch and verifyTransaction itself are unchanged, and an unknown chat still fails the check as before.

This matches the other clients. Android passes updateShort straight to processUpdateArray, and EphemeralUpdates.apply never looks up users. Desktop passes it to feedUpdate, and EphemeralMessages::applyOrDefer only waits for a missing ephemeral reply target, never for a user.

When the bot isn't stored locally, the message is shown without it: the "via bot" badge falls back to "bot", and a standalone ephemeral bubble in a group has no author name. The bot stays unknown until the user opens it, because the update has no access hash to fetch it with. Android and Desktop have the same limit.

Testing

Simulator (iPhone 17e, iOS 27), debug build, account freshly signed in that never opened @BugTelegramDemoBot: opened @bruninoittest, joined it, tapped "unlock it". The post was replaced with "the post is now unlocked". The log shows the same updateShort with no missing peers / failed to verify final state. Not tested on a device.

A bot's ephemeral reply to a callback button can arrive as updateShort,
which carries no users. The sender, receiver and reply peers were all
required by verifyTransaction, so an unknown bot made the whole update
batch fail. The fallback getDifference never returns ephemeral messages,
so the message was lost until the user opened the bot once.

Only require the chat peer for ephemeral updates, as Android and Desktop do.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants