Skip to content

fix(scheduler): deliver portal-chat reminders to the owner's Telegram DM - #164

Merged
chinkan merged 2 commits into
mainfrom
fix/portal-chat-reminder-163
Oct 6, 2026
Merged

chinkan merged 2 commits into
mainfrom
fix/portal-chat-reminder-163

Conversation

@chinkan

@chinkan chinkan commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Closes #163

Root cause

Portal web chat builds its turn with chat_id = user_id = "web" on bot default. schedule_task stored those values, and at fire time the runner failed chat_id.parse::<i64>() ("Unparseable chat_id"), so nothing was sent.

Fix

  • SchedulingTools::with_telegram_owner(shim bot id, first allowed user id), wired in main.rs from Config::shim_bot. Any turn whose chat_id is not numeric is scoped to that bot and owner DM before the tool runs, so create, list, cancel, history and reruns all see the same rows. Telegram turns are unchanged.
  • Boot migration adopt_web_schedules: existing rows with a non-numeric chat_id move to the shim bot owner DM, with a warn log of the count. Idempotent.
  • telegram::not_started_hint: when the final send is refused, the run is marked failed with a hint, plus a warn log. Three cases get separate text:
    • bot can't initiate conversation (403): Not delivered: open Telegram and send /start to @<username>
    • bot was blocked by the user (403): Not delivered: you blocked @<username> in Telegram; unblock it to get reminders
    • chat not found (400): Not delivered: Telegram can't find this chat; check the user id in allowed_user_ids, then send /start to @<username>
    • @<username> comes from getMe, called only on this failure path; it falls back to the '<id>' bot.
  • The portal Tasks run history already shows failed and the error text, so no UI change.

Tests

  • web_turn_schedules_on_owner_dm_and_can_list_and_cancel: web turn row lands on main/owner, web list and cancel find it; a Telegram turn keeps its own bot and chat.
  • adopt_web_schedules_moves_non_numeric_chats_to_owner: web rows move, DM and negative group ids stay, second run is a no-op, empty allowlist moves nothing.
  • not_started_hint_only_for_unstarted_chats: one hint per error kind, None for anything else.

cargo fmt --check, cargo clippy --locked --all-targets -- -D warnings, cargo test --locked: 926 passed.

QA matrix

  • AC1: from portal chat, "remind me in 1 minute" arrives in live Telegram; asking portal chat "what reminders do I have" lists it, and cancel works.
  • AC2: an old chat_id=web row is moved at boot with the warn log, then fires to Telegram.
  • AC3: with a shim bot the owner never sent /start, the portal run shows failed with the /start hint, plus a warn log. Optional: blocked bot shows the unblock hint; a wrong owner id shows the check-user-id hint.

… DM (#163)

Portal web-chat turns have a non-numeric chat_id, so reminders they created
could never be sent. Scheduling tools now scope such turns to the shim bot
and its first allowed user, for create, list, cancel and history alike.
Boot moves existing non-numeric-chat rows to that owner with a warn log.
When Telegram refuses the DM because /start was never sent, the run is
marked failed with a hint naming @username (or the bot id).

chinkan commented Oct 6, 2026

Copy link
Copy Markdown
Owner Author

TL ACCEPT at fc0e16e (comment — same-account Approve blocked).

Matches locked AC: web turns scoped to shim+owner for create/list/cancel; adopt_web_schedules for old non-numeric chat_ids; three separate undelivered hints with @username via on-demand getMe (boot cache not required). Tests cover the matrix.

Merge after Product GO + QA GO (incl. live AC1) + CI (Analyze (rust) green; AI findings 402 non-block). No tag.

@chinkan
chinkan merged commit 318d203 into main Oct 6, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Portal web-chat reminders use chat_id=web and never reach Telegram

1 participant