Repository navigation
feat(telegram): inbound stickers/animations/non-file text, media identity, mention regex, allowlist, early typing (#225) - #269
Conversation
…tity, mention regex, allowlist, early typing (#225) Ports vercel/chat 4ee187ac (#612), 2531a422 (#621, Telegram half), 0701679e (#706, regex cache), 54eea715 (#742), 53bf73db (#752), a0ba9868 (#835), a18e7922 (#836) and the Telegram half of b6fa24c6 (#865). - message.text is non-empty for stickers, venues, locations, contacts, polls, dice, games, invoices and stories - stickers and animations become attachments; the animation's document twin is suppressed; photos report image/jpeg; fetch_metadata carries fileUniqueId when present - @mybot-dev no longer mentions @Mybot; the pattern is cached per username - allowed_user_ids / TELEGRAM_ALLOWED_USER_IDS gate updates before dispatch - private, non-bot messages and slash commands start typing on receipt - file downloads are capped at 25 MB with a 30 s total timeout
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 29 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (8)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… allowed_user_ids, pin allowlist gate before slash/typing (#225)
… video attachment
|
Merge gate: CI green (Lint & Type Check, test (3.12), test (3.13), Analyze (python), Analyze (actions), CodeQL) on b57ecfa; local Codex review (gpt-6-astra, xhigh, --base origin/main) on fdf7d52: "No actionable regressions were found relative to the supplied merge base. All 476 Telegram tests passed, and targeted Ruff checks and diff whitespace checks passed."; 4 astra rounds. b57ecfa only merges origin/main (#270, #220, #212, #266); the merge was clean with disjoint files, and the PR diff under src/ tests/ scripts/ is byte-identical to what astra reviewed, so no re-review was needed. Local full validation: 6546 passed, strict fidelity 730/730 + 3 absorbers, pyrefly 0 errors, fidelity target delta +0. CodeRabbit is rate-limited (no review). Merging with --admin (Protect Main requires a code-owner approval). |
Summary
Brings Telegram inbound parsing up to chat@4.41.1.
text == "".documentcopy Telegram sends alongside an animation is no longer reported a second time.image/jpeg. Every attachment'sfetch_metadataincludesfileUniqueIdwhen Telegram sends one.@mybot-devno longer counts as a mention of@mybot. The mention pattern is compiled once per username.allowed_user_ids/TELEGRAM_ALLOWED_USER_IDS.Upstream commits mapped
4ee187ac(#612, chat@4.32.0)_start_typing_for_private_message, called fromhandle_incoming_message_updateandhandle_slash_command_update2531a422(#621, Telegram half, chat@4.34.0)@{user}(?![\w-])_get_mention_regex(re.IGNORECASE | re.ASCII)0701679e(#706, chat@4.35.0)_mention_regex/_mention_regex_username(the abortable-sleep half is N/A)54eea715(#742, chat@4.35.0)TelegramAdapterConfig.allowed_user_ids,process_updategate,_update_user_id53bf73db(#752, chat@4.36.0)fileUniqueId, photoimage/jpegcreate_attachment(file_unique_id=...), top-level andrich.pyphoto MIMEa0ba9868(#835, chat@4.39.0)parse_telegram_message,_sticker_attachment_format, animationvideoattachment with itsdocumentcopy suppresseda18e7922(#836, chat@4.39.0)_describe_non_file_content,_format_invoice_amountb6fa24c6(#865, Telegram half, chat@4.39.0)download_file+_read_telegram_fileTests ported (
packages/adapter-telegram/src/index.test.ts→tests/test_telegram_webhook.py)process_*stand-in that schedules a task, the way the realChatdoes.re.compilecalls.sticker messages(3),sticker and animation attachments(5),non-file content(10)Python-specific tests:
Content-Lengthover the cap is rejected before any read. A body with no length is stopped by the running count, and the chunk after the cap is never read. A body exactly at the cap is accepted. A malformedContent-Lengthfalls back to the running count. A timeout raisesNetworkError. The request passesClientTimeout(total=30).re.ASCIIcases (@mybotжmentions,@mybot_xdoes not)._js_number_strmatches JSString(). Integral and tiny float coordinates render as in JS. An empty caption still takes precedence over the non-file description. An emptyfile_unique_idis omitted.Existing expectations updated:
fetch_metadatanow includesfileUniqueId, and rich photos reportmime_type="image/jpeg". Both match the upstream 4.41 tests. Two test helpers now mocktelegram_fetch, because private messages fire a typing request. A local net-guard run confirmed that no Telegram test reaches the real HTTP session.Mutation-checked: removing
re.ASCII, reverting to\b, moving typing after dispatch, dropping the regex cache, reporting the animation'sdocumentcopy again, formatting floats withrepr, and always addingfileUniqueIdeach fail at least one test.Fidelity
adapter-telegram/src/index.test.tsis not fidelity-mapped (#78), so the target report is unchanged:(
scripts/fidelity_target.jsonwas regenerated and came out byte-identical, so the PR does not include it.) Strict: 733/733 atchat@4.31.0.Divergences
None. The Python-specific adaptations are recorded in a new parity row in
docs/UPSTREAM_SYNC.md:_js_number_strformats coordinates, dice values and allowlist ids the way JSString()does.re.ASCII.ClientTimeout(total=30)anditer_chunked.The download deliberately does not use
chat_sdk.shared.download(#204), for two reasons. Its HTTPS and public-address checks would break self-hosted Bot API servers, which upstream also leaves unchecked. Andread_attachment_bodydecodesContent-Encodingitself, while the shared aiohttp session already decompresses. The PR reuses onlyDEFAULT_LIMITandDEFAULT_TIMEOUT_MS.Consumer impact (Telegram only; none for Slack or Teams)
message.textis now non-empty for the kinds listed above.mime_typeis nowimage/jpeg(it wasNone).fetch_metadatagainsfileUniqueId.videoattachment instead of onefileattachment.sendChatActionrequest per private message or slash command.allowed_user_idsoption. When it is unset, behavior is unchanged.NetworkError.Out of scope, each with its own issue:
pollingGroupallowlist check ([4.41/TG3] Telegram polling & media: await handlers before advancing offset, media groups, multi-file uploads #227)reply_to_messageandmentionOnReply([4.41/TG4] Telegram replies: replied-to context, reply-to-bot as mention, native replies, portable file data #228)business_message.fromin the allowlist chain ([4.41/DEF1] Deferred upstream 4.32–4.41 features (demand-gated backlog) #189)Closes #225
Part of #184
Merge gate
Independent review findings (4 reported; 4 fixed, 0 declined), all in commit
bfbaa2b:re.ASCIIturned off non-ASCII case folding. The pattern is now(?![A-Za-z0-9_-])withre.IGNORECASE, so@БОТИКmentionsботик, as JS/idoes. The lookahead still accepts only ASCII characters, like JS\w. The docstring and thedocs/UPSTREAM_SYNC.mdrow are corrected, and the row now records the remaining Kelvin sign / long s folding difference. Test:test_mention_regex_case_folds_non_ascii_usernames_like_js_i, which fails on the old pattern./pingand a DM from a disallowed user. It asserts thatprocess_slash_commandis not called and that nosendChatActionis sent. Mutation check: moving the gate afterhandle_slash_command_updatemakes the test fail.allowed_user_idsas a bare string. A string was iterated character by character. A value that is not a list, tuple or set now raisesValidationError. This guard is Python-only, since upstream's.mapalready throws on a string. Test:test_non_list_allowed_user_ids_raise.gpt-6-astra: 4 rounds. Final verdict on
fdf7d52: clean.bfbaa2b), [P2]: receipt-typing tasks still pending atdisconnect()could reopen the aiohttp session after it was closed. This was a real bug (Python session lifecycle). Fixed in103b21c:disconnect()now cancels and awaits pending typing tasks. The new testtest_disconnect_cancels_pending_typing_so_the_session_is_not_reopenedfails without the fix.103b21c): clean.b89102a, after mergingorigin/main), [P2]: a re-posted GIF animation is sent throughsendVideo. Rebutted as upstream parity. chat@4.41.1adapter-telegram/src/index.ts:2798-2809mapsanimationto a"video"attachment, andATTACHMENT_UPLOADS.video(index.ts:154) usessendVideo. There is no Python-specific hazard, sofdf7d52adds a comment noting the parity and leaves behavior unchanged.fdf7d52): clean.Bots: CodeRabbit was rate-limited and posted no review. The PR has no inline or review comments.
CI: all checks green on
fdf7d52(Lint & Type Check, test 3.12 and 3.13, CodeQL).Local validation: full run green:
--check-docsand--strict(4.31.0 pin)Fidelity target delta:
missing 242 -> 242 (+0).