|
88API Token Aggregation Platform sponsors this project! Operated by a Hong Kong company, 88API is an all-in-one, multi-model API platform for developers, creators, and AI application users. Its unified interface connects text, image, speech, and video models for workflows including AI coding, translation, content creation, voiceovers, image generation, and video generation. It offers high-quality, discounted access to official DeepSeek inference services and self-hosted DeepSeek inference on its own B300 clusters. It supports major international payment methods, provides invoices, and offers enterprise-grade reliable service. Sign up through this link to receive exclusive bonus credits! |
|
DeepSeek Harness |
DSH-IM has received official sponsorship from DeepSeek Harness in the form of token credits. Thank you to the DeepSeek Harness team for supporting this project!
This project is independently developed and maintained by community developers. |
## Built-in channels
| Channel | Setup | Messaging and replies |
| --- | --- | --- |
| Feishu | Create a bot by QR code, or bind one with App ID + App Secret | Persistent connection for incoming messages; choose a native live process, one live process card, or step-by-step messages; each bot can enable voice interaction (optional channel capability, off by default): voice messages are transcribed into the normal text pipeline, and the answer is also sent as a voice reply |
| WeChat | Scan a QR code to bind a WeChat bot | Tencent iLink long polling; shows a typing indicator while Harness works, then sends the final reply in 1,800-character chunks |
| DingTalk | Create a bot by QR code, or bind one with Client ID + Client Secret | DingTalk Stream connection; streaming replies through AI Cards |
| WeCom | Create an intelligent bot by QR code, or bind one with Bot ID + Secret | Official WebSocket connection; native thinking state, tool progress, and streaming replies |
| QQ | Create a bot with mobile QQ QR scanning, or bind one with AppID + AppSecret | WebSocket connection; private chats show typing and receive one Markdown reply, while mentioned group chats receive only the final answer |
| Slack | Create an app from the bundled App Manifest, then enter a Bot Token (`xoxb-`) and App Token (`xapp-`) | Socket Mode connection; direct DM replies, mention-only channel replies, and preferred native streaming API |
| Telegram | Enter a Bot Token generated by @BotFather | Bot API long polling; DMs work by default and groups respond to mentions or replies, while each bot can optionally enable a private-DM allowlist; with thinking traces off, private chats, groups, and Topics edit a placeholder for progress and finalize rich replies in place, avoiding Drafts that block the Android private-chat composer; unsupported Rich delivery falls back to ordinary text |
| Discord | Enter a Bot Token generated in the Developer Portal | Gateway v10 connection; direct DM replies; the first mention in a server text or announcement channel creates a native Thread, where follow-up messages no longer need to mention the bot; replies stream through message edits |
| WhatsApp | Scan a QR code with mobile WhatsApp to link a device | WhatsApp Web connection; self-chat only by default, with optional selected-contact and open-response modes; groups require a mention or a reply to a bot message, including for the linked account; read receipt and typing indicator, with tool progress and incremental answers shown by editing one message at one-second intervals; long replies split automatically and failed edits fall back to a complete text reply |
| iMessage | Sign in to iMessage in macOS Messages.app and grant the local permissions described in the [channel notes](docs/imessage.md) | Native macOS Messages.app transport for text DMs; no BlueBubbles or third-party gateway; one local iMessage identity per macOS user account |
| Matrix (experimental) | Enter the homeserver URL plus an access token, or a user id with a password | CS API long polling; DMs are answered directly and rooms answer when the bot is @-mentioned, with thread replies, allowlisted HTML, edit-based streaming, and image/result-file delivery; includes experimental room-message encryption/decryption, subject to the limits below |
WhatsApp retains the identifiers of the latest 2,000 bot messages sent to groups, so replies to those messages still work after a restart. Replies to older messages outside that history, including unrecorded messages sent before upgrading, do not wake the bot; mention the bot or reply to one of its new messages instead.
Matrix encryption is currently for non-sensitive testing only. The default optional mode attempts to start the crypto engine and skips incoming encrypted messages if it fails; required mode refuses to connect when crypto startup fails. Interactive device verification, key backup, SSSS, and attachment-content encryption are not implemented. This release has not been validated against a live homeserver/Element setup; do not treat it as a complete end-to-end confidentiality guarantee.
Other IM platforms can be added through the same channel-adapter structure.
The iMessage contribution is documented separately in [the iMessage channel
notes](docs/imessage.md); it uses the native macOS Messages.app and requires no
third-party gateway.
New Feishu and QQ bots connected through the QR flow allow all users to chat and execute built-in commands in both direct and group chats by default. Allowlists and command permissions remain configurable in each bot's access settings. Existing bots keep their saved access settings.
Feishu group chats accept messages from other bots that explicitly mention the current bot by default, with no extra setting. Messages without that mention, mentions of only other members or everyone, self-sent messages, and bot DMs are still ignored, even in all-message mode. Group allowlists and command permissions still apply. The app needs the `im:message.group_at_msg.include_bot:readonly` tenant scope. New apps request it through the QR flow; existing or manually connected apps can use **Complete permissions** or `/repair` in a direct chat, scan the QR code, and complete any publication or approval required by Feishu. See the [Feishu message-event permissions](https://open.feishu.cn/document/server-docs/im-v1/message/events/receive).
Built-in channels with image input support can send JPEG, PNG, and WebP images, plus GIFs sent as image files, with optional captions to Harness. By default, original images can be up to 30 MB each, with up to 20 images per message. Originals are saved in the Session workspace; model copies are resized or compressed to 5 MB each and 20 MB total. Images that still exceed the budget, or are rejected by a non-vision model, are delivered as workspace files. These four limits can be changed under General settings → Attachments → Image input for subsequent messages. Originals follow attachment retention settings. Higher model limits increase request size, latency and model cost, and remain subject to platform and Host limits. iMessage's MVP supports text DMs only. Downloading images or files from Feishu user messages requires the `im:message:readonly` tenant scope, shown on the confirmation page as **Read direct and group messages**; Feishu currently offers no narrower image-only scope for that download endpoint. Apps created through the built-in QR flow request it by default; for existing or manually connected apps, click **Complete permissions** on the IM Bot settings page and scan the QR code to incrementally add that scope, `im:resource` for uploading bot-sent images or files, `application:app_slash_command:read` / `write` for the native command panel, and the card callback.
### Shared group messages and files
WhatsApp, Feishu, Telegram, Discord, Slack, and QQ can automatically save received group messages and attachments, including messages without mentions when the platform permits delivery. Recording is enabled by default and does not itself trigger a model reply. Mention a bot in the group to search records, summarize discussions, or read files on demand.
Records are shared by group, independently of bots, AI Sessions, and workspaces. Retention defaults to a rolling **14 days**, configurable under **DSH Settings → IM Bots → gear icon, General settings → General**. Only received content is saved; full history is not backfilled. QQ archives are currently isolated by app, and Discord threads have separate archives.
See the [group history and shared files guide](docs/group-history.en.md) for all six platforms' permissions and setup steps, query examples, storage, file limits, and troubleshooting. Live tests passed for text and text-file attachments on WhatsApp, Feishu, and QQ. Telegram text passed, with files still untested; Discord and Slack await live group verification.
### Results after a reply timeout
Connected IM channels share deferred task tracking. After a model reply timeout, the plugin keeps checking the original task and delivers its final text to the original chat or thread. Checks resume after a plugin restart or reconnection. `/stop` only stops the matching turn submitted by that chat; changing the bound Session prevents old results from being delivered there. No new setting is required, and normal replies keep their existing flow.
Channel permissions and quotas still apply. Definite send failures allow up to three attempts; uncertain delivery is retained without automatic retries to avoid duplicate messages. Recovery covers final text and terminal notices, without replaying questions, approvals, or file-tool calls. See the [deferred delivery notes](docs/deferred-delivery.md).
### Result-file and image delivery
Built-in channels with file delivery support can return any file readable by Harness as a native channel attachment. Existing files and files created by the current task can both be sent directly. The capability is available to every connected bot by default, with no switch or per-bot allowlist, while existing text, image, streaming, command, and Session behavior remains unchanged. iMessage's MVP does not support files or attachments.
After the model calls the file-return tool, the plugin hands the specified file to the channel's native API. Images prefer native image messages; if a channel does not support or definitively rejects image delivery, the plugin falls back to a file attachment, while an uncertain result never triggers a duplicate fallback. The plugin adds no rules for file origin, creation time, workspace boundary, extension, content, count, size, or lifetime; the file only needs to exist and be readable. A channel may still reject delivery according to its own permissions, quota, file capability, or account tier, and the plugin reports that provider result.
| Channel | Platform requirements |
| --- | --- |
| WeChat | The current binding protocol and conversation must support native file messages; the WeChat API response determines the actual range. |
| Feishu | Feishu's file-upload API requires a non-empty file no larger than the platform's 30 MB limit. The app needs the `im:resource` tenant scope (**Read and upload images or other files**). Apps created through the built-in QR flow request it by default; existing or manually connected apps can add it incrementally through **Complete permissions** or `/repair` in a direct chat, followed by any approval Feishu requires. The Feishu developer console currently has no separate `im:resource:upload` scope. |
| DingTalk | The app needs `qyapi_base`, and the bot must support file messages. The current OAPI and bot capability determine the accepted formats and sizes. |
| WeCom | The app needs media-upload and file-message capability; the WeCom API response determines the actual range. |
| QQ | The bot needs file-message capability and remains subject to QQ's daily upload quota; the bot reports when the quota is exhausted. |
| Slack | The Bot Token needs `files:read`, `files:write`, and `reactions:write`; the Workspace's current policy determines the actual file-size limit. After changing scopes, re-authorize/reinstall the App and reconnect the bot. |
| Telegram | The bot must be allowed to send documents in the current chat; the Bot API response determines the actual range. |
| Discord | Enable **Message Content Intent** in the Developer Portal. The bot needs **Send Messages**, **Create Public Threads**, **Send Messages in Threads**, and **Read Message History**; result-file delivery also requires **Attach Files**. The current account and server capability determine the actual attachment allowance. |
| WhatsApp | The linked session must support Document Messages; the WhatsApp/Baileys response determines the actual range. |
| Matrix | The homeserver must allow media uploads; its media repository configuration decides the real per-file limit. When an upload is rejected, the plugin asks you to check the media size limit and upload permissions. |
## AI Office Connector
[Read the AI Office Connector guide](docs/AI-Office-Connector.en.md)
## Installation
Install the published stable release of **`@xmanrui/dsh-im`** from npm (recommended). Choose the command for the application you use:
**DSH Desktop**: run in the current Desktop application's built-in terminal:
```sh
dsh plugin --profile desktop add -w @xmanrui/dsh-im
```
Restart DSH Desktop after installation.
**DSH Web**: run in the terminal environment used to start the current Harness:
```sh
dsh plugin --profile web add -w @xmanrui/dsh-im
```
Restart `dsh web` and refresh the browser after installation.
After restarting, open **Settings → IM Bot**. The top-level IM Bot entry uses `order: 21` to follow **Agent Presets**, and the Plugins page no longer retains the old entry. Upgrading preserves existing bots, credentials, workspaces, Agent Presets, and Session bindings.
Local `dsh web` and DSH Desktop reuse the current Host's internal services by default: the Typert Gateway invokes the Session and Workspace controllers. No Harness address or loopback HTTP connection is required. Desktop's compatibility, extended-window, and advanced modes do not require browser access or LAN access to be enabled. An explicit channel `harnessBaseUrl` is retained only for legacy remote HTTP/WebSocket Harness endpoints; failed internal calls never silently switch to another Host.
To try the latest code before it is published to npm, use the GitHub-source installer instead:
```sh
npx -y github:xmanrui/dsh-im install
```
A GitHub-source installation fetches and builds a Git dependency directly. With pnpm 10 or newer, the profile may first need an `allowBuilds` entry in `pnpm-workspace.yaml`. Most users should prefer the stable npm release.
After installation, follow the built-in instructions on each channel page to scan a QR code or enter credentials. Secrets and Tokens are sent only to the local Harness Host and stored through its protected credential provider; status responses and bot lists never return them.
If this machine must use a forward proxy to reach Feishu, set `HTTPS_PROXY` to a full HTTP proxy URL before starting `dsh web` (for example, `http://proxy:8080`; lowercase `https_proxy` is also supported, with `HTTP_PROXY` accepted as a fallback), then restart the Host after changing it. Feishu registration and credential verification reuse the SDK's proxy-aware HTTP client, while the message WebSocket explicitly uses that proxy; the WebSocket path does not currently read `ALL_PROXY` or `NO_PROXY`.
If this machine cannot reach the Telegram Bot API directly, use Node.js 22.21 or newer and enable Node's environment proxy support before starting `dsh web`:
```sh
NODE_USE_ENV_PROXY=1 \
HTTPS_PROXY=http://proxy:8080 \
HTTP_PROXY=http://proxy:8080 \
NO_PROXY=localhost,127.0.0.1 \
dsh web
```
Use the proxy URL required by your network and restart the Host after changing it. If Telegram Bot Token binding reports that the Bot API cannot be reached, first check the proxy URL, Node.js version, and `NO_PROXY` configuration.
| Default behavior | Description |
| --- | --- |
| Bot alias | Click the pencil beside a bot name to set an alias. Saving updates the display immediately, without restarting or reconnecting. The original name is retained; choose “Restore original name” or save an empty alias to restore it. Aliases only affect names shown in the local settings page. |
| Bot workspace | Each bot stores its workspace independently. New bots use `$DSH_HOME/im` (`~/.dsh/im` when unset); the directory is created when a bot or conversation selects it. Starting the plugin does not create it when all bots and conversations use other workspaces. New sessions appear under Ungrouped. Change it later from the bot card. An explicit `workspace` takes precedence, and `dshHome` overrides the `DSH_HOME` environment variable. |
| Model | Every bot in each IM channel can choose a model directly below its workspace, or follow the Host default. A change applies only to later new Sessions; send `/new` and then an ordinary message in the current chat to use it. |
| Reasoning effort | Explicitly choose an effort supported by the selected model, or follow the model default. Levels, descriptions, and defaults come from DSH. Switching models restores the new model's default effort. Each bot saves its own choice, which applies only to later new Sessions. |
| Agent Preset | Each bot can choose an Agent Preset on its settings card. When none is chosen, new Sessions follow the Host's `agent-presets.default`. A channel-level `config.agentPreset` is only the default for later new bots on that channel. Changing the preset never modifies or clears existing Sessions; if the current chat already has a Session, send `/new` and then a regular message to create one with the new selection. |
| Context enhancement | Open settings from a bot card to enable groups and DMs independently. Both switches default to off, including for existing bots after an upgrade. |
| Feishu command panel | Each Feishu bot decides, under **More settings → Command panel**, which commands the "/" list in the chat input offers and in what order. *Follow the default* keeps the shipped 34-command manifest (updated with the plugin); *custom* is exactly the chosen commands in the chosen order. Hiding a command only removes it from the list — typing it by hand still works — and commands added outside this manifest are never removed. Once one bot is set up, **Save and copy to the other bots** writes the same panel to every other bot on the channel (their own panel settings are overwritten; offline bots pick it up when they start). The bot syncs the panel in the background after saving, so a change takes a moment with many commands. |
| Feishu topic on mention | On by default. Mentioning the bot in a group or a private chat opens a dedicated Feishu topic under that message, and both the question and the answer stay inside it. The topic is an independent conversation in the dsh session list, and later messages in the topic belong to the same conversation. A bare "@bot" (which opens the menu) opens no topic, and messages without a mention stay in the chat's own conversation. Turn it off from the bot card's "Group" settings to return to flat replies in groups and private chats alike. |
| Feishu task progress display | Each Feishu bot can hide progress or use Live process, Live process card, or step-by-step messages. Live process uses Feishu's native thinking-process surface for reasoning, tool calls, and results, then sends the final answer separately. It requires Feishu desktop 7.70, mobile 7.74, or newer. Feishu's native thinking process currently cannot be posted inside a topic, so turns in a topic use the Live process card instead and keep the process and the answer in the topic. |
| Feishu voice interaction | Configure each Feishu bot independently under **More settings → Voice** on its bot card (optional channel capability, off by default). When enabled, voice messages are transcoded with ffmpeg and transcribed by DashScope `qwen3-asr-flash`, then processed through the normal text pipeline (commands, Sessions, model calls, and file delivery behave identically); the same turn's answer is also synthesized with `qwen3-tts-flash` as a voice reply to the original message. If transcription fails, the bot falls back explicitly to the existing text/image/file-only notice. The DashScope key is managed in the plugin credential store by environment variable name (`secretRef`, default `DASHSCOPE_API_KEY`) and never enters bot configuration. The ASR model, TTS model, reply voice (official `qwen3-tts-flash` voices such as Cherry, Serena, Bella, Chelsie, Momo, Katerina), and ffmpeg path are per-bot settings. It requires a working local ffmpeg and a key that can reach DashScope. |
| Session channel identity | Sessions from the local Host's IM channels and AI Office are marked with their source. The Web Session list and search results display channel logos in place of prefixes such as “WeChat ·”, preserving DSH's automatic title generation and updates. Existing Sessions receive the prefix when next loaded. |
Channel prefixes are appended after DSH produces a title, preserving its complete text and automatic/manual source without pinning automatic titles or making additional model calls. Regeneration, refresh, and restarts do not stack prefixes; actual manual renames retain DSH's normal pinning behavior. This feature uses the current Host's Session events; an explicit remote `harnessBaseUrl` requires the plugin on the destination Host.
Logos are a dsh-im browser enhancement and require no changes to DSH. The adapter preserves original text nodes, clicks, menus, and dragging; copied titles, screen readers, and other surfaces retain the textual channel name. Unrecognized DSH page structures, unsupported browsers, or image-loading failures keep the text prefix. Unloading the plugin restores the original display.
### Queueing and steering
Open a bot's **More settings → General**, choose **New messages while a task is running**, and save. Each bot has its own setting, across all 13 chat channels.
- **Queue (default)**: process new messages after the current task finishes, with a queue receipt when they need to wait.
- **Steer**: add ordinary plain text to the current task for the Agent to read at its next step, with a submission receipt. There is no need to type `/steer` each time.
When idle, messages start a task normally. Images, files, voice messages, and quoted replies keep their existing handling. Group mention rules and permissions still apply; automatic steering requires `/steer` permission. Both modes retain `/steer | QQ Group | Xiaohongshu | ||
|---|---|---|---|
| longmanr307@gmail.com |
|
|
|