Add short code store, bot commands (/start, /status, /help), and
POST /telegram/connect-code endpoint for Desktop to create QR codes.
Users scan a QR → Telegram opens → /start {code} → auto-connects.
- ShortCodeStore: in-memory Map with TTL for connection info
- Bot commands registered via setMyCommands
- Refactor handleConnectionLink into shared connectUser method
- Fetch bot username via getMe() for deep link URL
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When TELEGRAM_WEBHOOK_URL is not set, the bot automatically starts in
long-polling mode (bot.start()) instead of waiting for webhook calls.
This allows local development without ngrok or a public URL.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Group chats have unresolved issues in the Gateway context:
- Per-user deviceId causes context overwrites across groups
- Reply chains across users route to wrong Hubs
- Welcome messages are noisy in groups
Restrict to private chats only until a proper group model is designed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Port all 7 features from the Desktop long-polling Telegram channel plugin
to the Gateway webhook-based Telegram bot:
- Markdown → Telegram HTML formatting with parse-error fallback
- Text chunking for messages >4096 chars (paragraph-boundary split)
- Reply-to original message + 👀 ack reaction lifecycle
- Group chat support (mention/reply filtering, @mention stripping)
- Per-chat message serialization (prevents race conditions)
- Inbound media handling (voice/audio/photo/video/document)
with transcription (Whisper) and description (Vision API)
- Outbound file captions with HTML formatting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add common generateEncryptedId() utility in @multica/utils
- All Device IDs now use same encryption algorithm (40 hex chars)
- Web: store encrypted format directly in localStorage
- Desktop: use shared utility, accept encrypted ID from Web
- Hub: use shared utility for hub-id generation
- Telegram: use shared utility for device ID generation
- Gateway hook: use encrypted format for client connections
Algorithm: sha256(sha256(uuid).slice(0,32)).slice(0,8) + sha256(uuid).slice(0,32)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add sendFileToTelegram method that decodes base64 file data and sends
it via grammy's InputFile API. Handle send_file RoutedMessage action
in the virtual device sendCallback.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Send "typing" chat action while LLM generates a response, with 5s
interval refresh and 60s safety timeout. Stop on message_end,
agent_error, or generic error events.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Gateway source moved out of src/ subdirectory but Dockerfile still
referenced old paths, breaking docker build. Rewrite to use tsx runtime
(no tsc/esbuild compile step), copy all workspace package.json for
lockfile compatibility, and filter install to gateway deps only (616 vs
1911 packages). Also update build-and-push script to tag latest.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>