Telegram duty gateway: phone-message task loop on a dedicated duty session, global approval forwarding while on duty, duty/local toggle, zh/en messages.
Install
# from npm (prebuilt)
dsh plugin --profile web add @luzhengyangtx/dsh-telegram-duty
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:luzhengyangtx/dsh-telegram-duty
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time. Only install sources you trust, and pin a commit (github:owner/repo#sha).
README
Turn DeepSeek Harness (DSH) into your always-on pocket duty office: message a Telegram bot from your phone, the duty agent gets to work, and the result comes back to your phone. Idle cost is zero tokens — the plugin long-polls getUpdates and only wakes an agent when a message arrives.
Features
- 📱 Task loop — Telegram message → dedicated "duty" DSH session (its agent has the standard tool set) → final reply back to Telegram; long replies are split under Telegram's message limit.
- 🔐 Whitelist — only your own chat id is served; other senders are logged and ignored.
- ✅ Global approval forwarding — in duty mode, approval requests from all sessions go to your phone with [✅ Approve] [⛔ Reject] buttons (tap to answer; typing
3 approve / 3 rejectstill works). Unanswered approvals time out to rejected (fail-closed, 10 minutes by default). - ❓ telegram_ask tool — when an agent needs you to choose between options, confirm something, or supply missing information, it pushes the question to your phone with one button per option; the duty agent is prompted to prefer it.
- 🔀 Duty / local toggle
- Enter duty: send any phone message, send
/away, or flipwatchModein the web settings. - Back to local: send any message in the web UI, or send
/back. - In local mode approvals stay in the web popup; in duty mode the popup is paused.
- Enter duty: send any phone message, send
- 🚩 Duty banner — while on duty, a frame-wide web banner shows "approvals are on your phone" with a one-click switch back.
- 🗂 Durable — the
getUpdatescursor and the watch mode persist across restarts; backlog is fast-forwarded on the very first run only. - 🌐 English & Chinese — every Telegram message respects the
languagesetting (zh|en, defaulten). - 🌍 Direct-connection friendly — connects directly by default; configure
proxyonly when Telegram is blocked in your network (see the table below).
Requirements
- A built DeepSeek Harness checkout with
dshCLI working, and a configured model. - A Telegram bot token (from @BotFather) and your chat id.
- Node ^22.19.0 || >=24.0.0 (the built-in
proxyEnvsupport of Node ≥ 24.5 is used when a proxy is configured).
Install
This package is a DSH plugin bundle: it ships its own cordis.patch.yml and mounts one plugin row (id: telegram-duty).
From inside a DeepSeek Harness checkout (workspace member):
# 1. place this package under packages/interaction/telegram-duty
pnpm install
node_modules\.bin\tsc.cmd -b packages/interaction/telegram-duty/tsconfig.json
# 2. edit your profile patch, e.g. C:\Users\<you>\.dsh\profiles\web\cordis.patch.yml:
# - insert:
# - id: telegram-duty
# name: '@luzhengyangtx/dsh-telegram-duty'
# config:
# token: '123456:YOUR-BOT-TOKEN' # or omit and set credentialsFile
# chatId: 123456789 # your chat id (whitelist)
# language: en # or zh
# 3. restart dsh web
pnpm dsh web
Outside the checkout (standalone folder), the plugin resolves its @deepseek-ai/* imports from its own node_modules, so install the two published packages first:
pnpm add @deepseek-ai/cordis @deepseek-ai/schemastery
Configuration
All fields live in the telegram-duty settings namespace (the web Settings page shows it, or put them under the patch row's config:).
| Field | Default | Meaning |
|---|---|---|
token |
— | Bot token (marked secret; never shown in settings UIs). Alternatively set credentialsFile to a JSON file with token / chat_id / proxy. |
chatId |
— | Whitelisted chat id. |
proxy |
(empty) | HTTP proxy used for Bot API calls. Leave empty for a direct connection — only set a local proxy (e.g. http://127.0.0.1:7890) when Telegram is blocked in your network. |
sessionId |
telegram-duty |
Stable DSH session id; created on first message. |
dutyCwd |
process cwd | Workspace directory of the duty session. |
approvalTimeoutMinutes |
10 |
Unanswered approvals are rejected after this. |
watchMode |
local |
local (web popups) or duty (approvals to Telegram). |
language |
en |
Language of all Telegram messages: en or zh. |
dataDir |
<DSH_HOME>/storages/telegram-duty |
Offset persistence directory. |
credentialsFile |
— | Optional JSON file { token, chat_id, proxy } for credentials defaults. |
replyChunkChars |
3800 |
Split threshold for long replies (Telegram limit 4096). |
Phone commands
/help— usage/away— enter duty mode (approvals go to the phone)/back— return to local mode3 approve/3 reject— answer approval #3; with a single pending approval, bareapprove/rejectworks too.
Dev
pnpm --filter "@luzhengyangtx/dsh-telegram-duty" run typecheck
node_modules\.bin\vitest.cmd run packages/interaction/telegram-duty/tests
# channel self-check against a real bot:
$env:TG_CREDS='C:\path\to\config.json'
node --import tsx/esm packages/interaction/telegram-duty/scripts/check-telegram.ts
License
MIT. The session-driving pattern (resume/create + summarize) follows @kriskwok/dsh-feishu-gateway (MIT) — see LICENSE.
Links
More in this category
omdsh-dev/dsh-notification★ 42
Desktop notifications for turn completions, with per-outcome controls and keyword rules.
omdsh-dev/dsh-open-in-vscode★ 40
Open DSH workspace directories in VS Code directly from the web GUI.
whyihaveyou/dsh-suite#plugin-notify★ 19
IM webhook and local notifications on turn completion, errors, or approval (Feishu/WeCom/DingTalk/Slack/Discord/custom).
bill9109/dsh-web-ui-notify★ 12
Desktop notification reminders.
bobleer/dsh-acp-for-bitfun★ 9
ACP bridge between BitFun and DSH.
openma-ai/deepseek-harness-acp★ 7
ACP profile plugin and standalone stdio server for using the full DSH agent from Zed and other ACP clients while sharing DSH credentials and sessions.