Status: design plan, 29 September 2026. No Telegram implementation has been added.
Add a Telegram source for the user's own private chats and groups. The first version reads new text messages only. In groups, it considers messages that mention the account or reply to one of its messages. It excludes broadcast channels, media-only messages, and Secret Chats. Hafi saves reply suggestions locally and never sends Telegram messages.
This requires a Telegram user session through MTProto. A Bot API token sees the bot's conversations, not the user's ordinary inbox. Telegram requires an api_id and api_hash for a user client, and login may ask for a phone number, code, and two-step verification password. The saved session is a full account credential, not a read-only grant. Telegram app setup, user authorization, Bot FAQ.
Hafi currently sends source content to Jev and Codex. Telegram's API terms and content licensing terms restrict using platform data with AI systems and describe a narrow consent exception. Confirm that Hafi's intended message processing is permitted before routing Telegram content to either service or shipping this source. If that cannot be established, stop the Telegram source release; a successful login alone does not clear this gate.
- Check the client library in the shipped runtime. Try the maintained teleproto client in Bun and a compiled Hafi binary. Verify login, saved-session reuse,
updates.getDifference, group updates, and clean process exit. Do not add the dependency until that check passes. The older GramJS repository is archived. - Add account connection. Extend
hafi onboardwithConnect Telegram? [y/N]and addhafi connect telegram. ReadHAFI_TELEGRAM_API_IDandHAFI_TELEGRAM_API_HASHat connection time. Prompt locally for the phone number, login code, and two-step password when required. Never echo the code or password. Save the session and app credentials under the account alias inBun.secrets; keep them out of YAML, JSON output, and logs. Verify the account before reportingconnected: true. Makedoctorcheck the saved session. - Wire one source adapter into the existing interface. Add
telegramto the workflow provider schema, CLI choices,doctor, and the source selection insrc/core.ts. Implementsrc/telegram.tsbehind the existingInboxSource.fetchNew()andload()interface. Keep Telegram transport, login, synchronization, and message normalization inside that file. The runner and draft action need no Telegram-specific branch. - Make polling loss-aware. On first activation, save Telegram's current common update state and each selected supergroup's state, and create no work from older chats. On later
run-oncecalls, fetch offline updates withupdates.getDifference; consume everydifferenceSliceand the indicated supergroup differences before returning the new cursor. OndifferenceTooLong, do a bounded recovery from the last successful time and record a visible sync-gap code if complete recovery is impossible. Queue message references and advance the cursor together in SQLite. Close the MTProto connection so the one-shot cron process exits. Telegram update guide. - Preserve message identity and reply context. Telegram message IDs can repeat across chats. Change the
work_itemsuniqueness key to include the chat ID, with a migration that preserves existing Gmail and Lark work. Use chat and topic or reply-root IDs for conversation grouping. Load at most 12 relevant context messages, distinguish the account's own messages, and detect a later reply in the same conversation. For group intake, include only direct mentions or replies to the account. Omit a message URL when a stable link cannot be formed. - Verify the end-to-end path. Test login and code/password cancellation on Telegram's test servers, then run the compiled binary against an authorized test account. Confirm that first activation imports no old chat, a new private message and a group mention each produce one local result, an unrelated group message produces none, a repeat run creates no duplicate, a reply by the owner suppresses a draft, and an offline interval is recovered. Check that Hafi never sends a Telegram message or silently changes message read status. Keep the existing Gmail and Lark checks green.
Ship only after the terms gate, compiled-runtime check, and live account checks pass. Until then, onboard should not offer Telegram as a working source.