fix(gateway): preserve Telegram DM topic routing metadata in synthetic notifications - #36028
Merged
kshitijk4poor merged 2 commits intoMay 31, 2026
Conversation
Follow-up to the synthetic-notification DM-topic routing fix. The new _is_telegram_dm_topic_target probed the adapter's _get_dm_topic_info via instance-level getattr, which a MagicMock auto-creates as a truthy callable — so any test double with a non-dm chat_type and a thread_id would be misclassified as a DM topic lane and have the fallback routing keys injected. Resolve the method on type(adapter) and treat only dict-shaped returns as an operator-declared topic, mirroring the existing guard in _rename_telegram_topic_for_session_title. Update the home-channel startup test to declare _get_dm_topic_info on a real adapter subclass instead of patching a MagicMock onto the instance.
kshitijk4poor
enabled auto-merge (rebase)
May 31, 2026 18:49
Collaborator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Salvage of #34144 (@Dusk1e) onto current
main, plus a hardening follow-up.Synthetic gateway notifications —
/update,/restart, shutdown warnings, and home-channel startup pings — built their Telegram send metadata inline as{"thread_id": thread_id}, bypassing the richer DM-topic routing metadata that normal replies carry. For Telegram private DM topic lanes, a thread-id-only payload with no reply anchor is rejected by the Bot API send path:so the notification was silently dropped (observed on
/restartand home-channel startup).What changed
_thread_metadata_for_target()helper (the existing_thread_metadata_for_source()now delegates to it, with byte-identical behavior for its 18 callers).chat_typein the/updateand/restartmarker payloads so post-restart paths can reconstruct DM-topic routing.telegram_dm_topic_reply_fallback,direct_messages_topic_id). The Telegram adapter's_is_private_dm_topic_send()short-circuits toFalsewhendirect_messages_topic_idis present, so the send routes via the topic id and no longer requires a reply anchor.thread_id.Follow-up commit (hardening)
The contributor's
_is_telegram_dm_topic_targetprobedadapter._get_dm_topic_infovia instance-levelgetattr. AMagicMockauto-creates that attribute as a truthy callable, so any test double with a non-dmchat_type+ athread_idwould be misclassified as a DM topic lane and get the fallback keys injected. The follow-up resolves the method ontype(adapter)and treats only dict-shaped returns as an operator-declared topic — mirroring the existing guard in_rename_telegram_topic_for_session_title. The home-channel test is updated to declare_get_dm_topic_infoon a real adapter subclass instead of patching aMagicMockonto the instance.Why no
message_idanchor was neededThe reported root cause suggested storing
event.message_idas a reply anchor. That works, but the adapter already supports an anchorless routing path for synthetic sends (introduced in #27937): whendirect_messages_topic_idis present,_is_private_dm_topic_send()returnsFalseand_thread_kwargs_for_send()returns{"message_thread_id": None, "direct_messages_topic_id": <tid>}. This fix uses that path, which is the correct mechanism for sends that have no originating message to reply to.Testing
main(+121/-25, matching the original PR).tests/gateway/test_update_command.py+tests/gateway/test_restart_notification.py: 53 passed.py_compileclean..restart_notify.jsonmarker for a DM topic (thread777,chat_typedm), ran_send_restart_notification(), fed the resulting metadata into the realTelegramAdapterdecision logic. Onmain_is_private_dm_topic_send→True(→ the error); with this PR →False, routing viadirect_messages_topic_id. Confirmed the notification now delivers.MagicMockadapter with a non-dmchat_typeis no longer misclassified; real adapters returning a dict /Nonebehave correctly.Closes #34144
Co-authored-by: Dusk1e yusufalweshdemir@gmail.com