Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> - Add Media Support section to overview with images and files - Document model option for multimodal channel support - Add Images and Files section to Telegram guide - Add complete WeChat (Weixin) setup guide with QR auth This documents the new media handling capabilities added to both Telegram and WeChat channels.
9.6 KiB
Channels
Channels let you interact with a Qwen Code agent from messaging platforms like Telegram or WeChat, instead of the terminal. You send messages from your phone or desktop chat app, and the agent responds just like it would in the CLI.
How It Works
When you run qwen channel start <name>, Qwen Code:
- Reads the channel configuration from your
settings.json - Spawns an agent process using the Agent Client Protocol (ACP)
- Connects to the messaging platform (e.g., Telegram) and starts listening for messages
- Routes incoming messages to the agent and sends responses back to the chat
Each channel runs as a long-lived process that bridges a messaging platform to a Qwen Code agent.
Quick Start
- Set up a bot on your messaging platform (see channel-specific guides: Telegram, WeChat)
- Add the channel configuration to
~/.qwen/settings.json - Run
qwen channel start <name>
Configuration
Channels are configured under the channels key in settings.json. Each channel has a name and a set of options:
{
"channels": {
"my-channel": {
"type": "telegram",
"token": "$MY_BOT_TOKEN",
"senderPolicy": "allowlist",
"allowedUsers": ["123456789"],
"sessionScope": "user",
"cwd": "/path/to/working/directory",
"instructions": "Optional system instructions for the agent.",
"groupPolicy": "disabled",
"groups": {
"*": { "requireMention": true }
}
}
}
}
Options
| Option | Required | Description |
|---|---|---|
type |
Yes | Channel type: telegram or weixin |
token |
Telegram | Bot token. Supports $ENV_VAR syntax to read from environment variables. Not needed for WeChat |
model |
No | Model to use for this channel (e.g., qwen3.5-plus). Overrides the default model. Useful for multimodal models that support image input |
senderPolicy |
No | Who can talk to the bot: allowlist (default), open, or pairing |
allowedUsers |
No | List of user IDs allowed to use the bot (used by allowlist and pairing policies) |
sessionScope |
No | How sessions are scoped: user (default), thread, or single |
cwd |
No | Working directory for the agent. Defaults to the current directory |
instructions |
No | Custom instructions prepended to the first message of each session |
groupPolicy |
No | Group chat access: disabled (default), allowlist, or open. See Group Chats |
groups |
No | Per-group settings. Keys are group chat IDs or "*" for defaults. See Group Chats |
Sender Policy
Controls who can interact with the bot:
allowlist(default) — Only users listed inallowedUserscan send messages. Others are silently ignored.pairing— Unknown senders receive a pairing code. The bot operator approves them via CLI, and they're added to a persistent allowlist. Users inallowedUsersskip pairing entirely. See DM Pairing below.open— Anyone can send messages. Use with caution.
Session Scope
Controls how conversation sessions are managed:
user(default) — One session per user. All messages from the same user share a conversation.thread— One session per thread/topic. Useful for group chats with threads.single— One shared session for all users. Everyone shares the same conversation.
Token Security
Bot tokens should not be stored directly in settings.json. Instead, use environment variable references:
{
"token": "$TELEGRAM_BOT_TOKEN"
}
Set the actual token in your shell environment or in a .env file that gets loaded before running the channel.
DM Pairing
When senderPolicy is set to "pairing", unknown senders go through an approval flow:
- An unknown user sends a message to the bot
- The bot replies with an 8-character pairing code (e.g.,
VEQDDWXJ) - The user shares the code with you (the bot operator)
- You approve them via CLI:
qwen channel pairing approve my-channel VEQDDWXJ
Once approved, the user's ID is saved to ~/.qwen/channels/<name>-allowlist.json and all future messages go through normally.
Pairing CLI Commands
# List pending pairing requests
qwen channel pairing list my-channel
# Approve a request by code
qwen channel pairing approve my-channel <CODE>
Pairing Rules
- Codes are 8 characters, uppercase, using an unambiguous alphabet (no
0/O/1/I) - Codes expire after 1 hour
- Maximum 3 pending requests per channel at a time — additional requests are ignored until one expires or is approved
- Users listed in
allowedUsersinsettings.jsonalways skip pairing - Approved users are stored in
~/.qwen/channels/<name>-allowlist.json— treat this file as sensitive
Group Chats
By default, the bot only works in direct messages. To enable group chat support, set groupPolicy to "allowlist" or "open".
Group Policy
Controls whether the bot participates in group chats at all:
disabled(default) — The bot ignores all group messages. Safest option.allowlist— The bot only responds in groups explicitly listed ingroupsby chat ID. The"*"key provides default settings but does not act as a wildcard allow.open— The bot responds in all groups it's added to. Use with caution.
Mention Gating
In groups, the bot requires an @mention or a reply to one of its messages by default. This prevents the bot from responding to every message in a group chat.
Configure per-group with the groups setting:
{
"groups": {
"*": { "requireMention": true },
"-100123456": { "requireMention": false }
}
}
"*"— Default settings for all groups. Only sets config defaults, not an allowlist entry.- Group chat ID — Override settings for a specific group. Overrides
"*"defaults. requireMention(default:true) — Whentrue, the bot only responds to messages that @mention it or reply to one of its messages. Whenfalse, the bot responds to all messages (useful for dedicated task groups).
How group messages are evaluated
1. groupPolicy — is this group allowed? (no → ignore)
2. requireMention — was the bot mentioned/replied to? (no → ignore)
3. senderPolicy — is this sender approved? (no → pairing flow)
4. Route to session
Telegram Setup for Groups
- Add the bot to a group
- Disable privacy mode in BotFather (
/mybots→ Bot Settings → Group Privacy → Turn Off) — otherwise the bot won't see non-command messages - Remove and re-add the bot to the group after changing privacy mode (Telegram caches this setting)
Finding a Group Chat ID
To find a group's chat ID for the groups allowlist:
- Stop the bot if it's running
- Send a message mentioning the bot in the group
- Use the Telegram Bot API to check queued updates:
curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getUpdates" | python3 -m json.tool
Look for message.chat.id in the response — group IDs are negative numbers (e.g., -5170296765).
Media Support
Channels support sending images and files to the agent, not just text.
Images
Send a photo to the bot and the agent will see it — useful for sharing screenshots, error messages, or diagrams. The image is sent directly to the model as a vision input.
To use image support, configure a multimodal model for the channel:
{
"channels": {
"my-channel": {
"type": "telegram",
"model": "qwen3.5-plus",
...
}
}
}
Files
Send a document (PDF, code file, text file, etc.) to the bot. The file is downloaded and saved to a temporary directory, and the agent is told the file path so it can read the contents using its file-reading tools.
Files work with any model — no multimodal support required.
Platform differences
| Feature | Telegram | |
|---|---|---|
| Images | Direct download via Bot API | CDN download with AES decryption |
| Files | Direct download via Bot API (20MB limit) | CDN download with AES decryption |
| Captions | Photo/file captions included as message text | Not applicable |
Slash Commands
Channels support slash commands. Some are handled locally by the adapter:
/start— Welcome message/help— List available commands/reset— Reset your session and start fresh
All other slash commands (e.g., /compress, /summary) are forwarded to the agent.
Running
qwen channel start my-channel
The bot runs in the foreground. Press Ctrl+C to stop.