QQ Bot (QQ-бот)
В этом руководстве описывается настройка канала Qwen Code в QQ через официальный API QQ Bot Open Platform.
Предварительные требования
- Учётная запись QQ (мобильное приложение для сканирования QR-кода)
Настройка
Вход по QR-коду
Запустите канал — при первом запуске появится QR-код. Отсканируйте его с помощью приложения QQ для активации. Ни регистрация разработчика, ни ручная настройка не требуются. Учётные данные сохраняются и используются повторно автоматически.
{
"channels": {
"my-qq": {
"type": "qq"
}
}
}qwen channel start my-qq
# Отсканируйте QR-код в терминале с помощью приложения QQРучная настройка (портал разработчика)
Вы также можете использовать учётные данные с портала разработчика QQ Bot Open Platform , если у вас уже зарегистрировано приложение:
{
"channels": {
"my-qq": {
"type": "qq",
"appID": "YOUR_APP_ID",
"appSecret": "$QQ_APP_SECRET"
}
}
}Установите секрет через переменную окружения:
export QQ_APP_SECRET=<your-app-secret>Конфигурация
{
"channels": {
"my-qq": {
"type": "qq",
"appID": "YOUR_APP_ID",
"appSecret": "$QQ_APP_SECRET",
"sandbox": false,
"privatePolicy": "open",
"sessionScope": "user",
"cwd": "/path/to/your/project",
"instructions": "你是一个通过 QQ Bot 对话的 AI 助手。回复控制在 2000 字符以内。",
"groupPolicy": "disabled",
"groups": {
"*": { "requireMention": true }
}
}
}
}Параметры, специфичные для QQ
| Параметр | По умолч. | Описание |
|---|---|---|
appID | — | AppID приложения QQ Bot из портала разработчика. Если опущен, используется вход по QR-коду. |
appSecret | — | AppSecret приложения QQ Bot. Поддерживает синтаксис $ENV_VAR. Если опущен, используется вход по QR-коду. |
sandbox | false | Установите true для использования sandbox-среды API QQ (sandbox.api.sgroup.qq.com) |
Также поддерживаются все стандартные параметры канала (см. Channel Overview):
privatePolicy, allowedUsers, sessionScope, cwd, instructions, groupPolicy, groups, dispatchMode.
Запуск
# Запустить только канал QQ
qwen channel start my-qq
# Или запустить все настроенные каналы вместе
qwen channel startОткройте QQ и отправьте сообщение вашему боту. Вы должны увидеть ответ в чате.
Групповые чаты
Чтобы использовать бота в группах QQ:
- Установите
groupPolicyв"allowlist","pairing"или"open"в конфигурации канала. - Добавьте бота в группу QQ через панель управления QQ Bot Open Platform или попросите администратора группы пригласить его.
- Участники группы должны @упомянуть бота, чтобы вызвать ответ.
- Если используется
groupPolicy: "pairing", одобрите запрос на спаривание группы один раз перед началом ответов. Обратите внимание, что после одобрения группы любой участник этой группы может использовать бота по умолчанию (ограничьте с помощьюsenders: "allowlist"иallowedUsersгруппы);privatePolicyиallowedUsersкорневого уровня не регулируют доступ участников одобренной группы.
API QQ Bot V2 доставляет только групповые сообщения, в которых упоминается бот — бот не видит все сообщения группы. По умолчанию requireMention равно true, и для QQ это значение следует оставить.
Подробнее о групповых политиках и условиях упоминания см. в разделе Group Chats.
Поддержка Markdown
Канал QQ Bot поддерживает форматирование Markdown (msg_type=2). Ответы агента в Markdown отправляются как есть, а QQ отображает их с богатым форматированием (жирный шрифт, курсив, блоки кода, ссылки, списки).
Если сервер QQ отклоняет сообщение в Markdown по какой-либо причине, канал автоматически повторяет отправку как обычный текст — так ваши сообщения всегда доходят, даже если возможность использования Markdown ограничена на стороне сервера.
Это противоположно каналу WeChat, который удаляет весь Markdown. Вы можете позволить агенту использовать полный Markdown в канале QQ.
Изображения, видео и файлы
Пользователи могут отправлять боту изображения, видео, файлы и голосовые сообщения. Изображение передаётся агенту как визуальный вход, так что агент видит саму картинку — скриншоты, сообщения об ошибках и диаграммы работают — и тот же файл также сохраняется во временный локальный путь на случай, если модель не поддерживает изображения. Видео, файл или голосовое сообщение сохраняется во временный локальный путь, и агенту сообщается этот путь.
Медиа-сообщение не требует текста — сообщение только с изображением, только с видео, только с файлом или только с голосом начинает ход, и канал использует (image), (video), (file) или (voice) в качестве заполнителя. Если сообщение содержит текст, этот текст сохраняется как подпись.
Файл — это всё, что платформа доставляет как content_type: file — документы Word, PDF, таблицы, архивы, исходные файлы. QQ не сообщает MIME-тип для файла, поэтому канал сохраняет собственное расширение отправителя (ограниченное буквами и цифрами, с фолбэком на .bin, если расширение отсутствует) и сохраняет байты в channel-files/<uuid>/ во временном каталоге системы; инструмент чтения агента использует это расширение, чтобы определить, как открыть документ.
Голосовое сообщение приходит как content_type: voice. Помимо оригинального SILK URL, QQ предоставляет voice_wav_url — тот же аудио, уже конвертированный в WAV — и канал предпочитает его; когда платформа не отправляет его, канал использует фолбэк на оригинальный URL. Байты сохраняются в channel-files/<uuid>/ как qq_voice.wav или qq_voice.silk, когда использовался оригинальный SILK URL, и агенту сообщается этот путь. ASR-текст платформы не используется; агент работает из сохранённого аудиофайла.
- Изображения ограничены 8 МБ, видео, файлы и голосовые сообщения — 20 МБ, и обрабатывается не более пяти вложений на сообщение. Всё, что больше, пропускается и логируется в stderr канала.
- Скачанные файлы не удаляются. Они остаются во временном каталоге системы, который очищается по собственному расписанию системы.
Ввод изображений требует модели, принимающей изображения. Объявите возможность, если модель мультимодальна, но не распознана по имени. Это поле должно находиться в записи провайдера, обслуживающего модель, поскольку значение model.generationConfig верхнего уровня игнорируется для моделей провайдера:
{
"modelProviders": {
"openai": [
{
"id": "your-model-id",
"baseUrl": "https://example.invalid/v1",
"generationConfig": {
"modalities": { "image": true }
}
}
]
}
}При использовании текстовой модели агент получает уведомление «unsupported image» плюс сохранённый путь вместо изображения.
Отправка изображений, видео, файлов или голосовых сообщений обратно в QQ не поддерживается.
Управление токенами
Токены доступа истекают примерно через 2 часа. Канал автоматически обновляет их при достижении 80% времени жизни (TTL) (обычно ~1,6 часа). Если обновление не удалось, оно повторяется через 60 секунд.
Обновление токенов продолжается после переподключения WebSocket — канал никогда не отключается из-за истекшего токена, пока AppID и AppSecret остаются действительными.
Устойчивость соединения
- Автопереподключение: При разрыве WebSocket канал повторяет попытку с экспоненциальной задержкой (до 20 попыток, максимум 30 секунд между повторениями).
- Восстановление сессии: Если WebSocket ненадолго отключается, канал использует код операции
RESUMEQQ для восстановления сессии без потери сообщений, находящихся в процессе передачи. - Продолжение контекста между серверами: Состояние чатов и маршрутизация сохраняются на диск. Если демон перезапускается, разговоры продолжаются с того же места.
- Мониторинг heartbeat: Тайм-ауты HEARTBEAT_ACK обнаруживаются и вызывают принудительное переподключение, чтобы избежать «зомби»-соединений.
- Дедупликация сообщений: Повторно отправленные сообщения после переподключения обнаруживаются и пропускаются.
Советы
- Свободно используйте Markdown — В отличие от WeChat, QQ отображает Markdown нативно. Жирный шрифт, блоки кода, списки и ссылки — всё работает.
- Держите ответы в пределах 2000 символов — Более длинные ответы автоматически разбиваются на части. Добавление подсказки о длине в инструкции помогает агенту быть лаконичным.
- Sandbox для тестирования — Установите
"sandbox": true, чтобы использовать sandbox API во время разработки. На рабочие сообщения это не повлияет. - Ограничьте доступ — Используйте
privatePolicy: "allowlist"для фиксированного набора пользователей QQ или"pairing"для подтверждения новых пользователей из CLI. Подробнее см. в DM Pairing.
Ключевые отличия от Telegram
| Область | QQ Bot | Telegram |
|---|---|---|
| Аутентификация | Вход по QR-коду или AppID/AppSecret | Статический токен бота от BotFather |
| Markdown | Нативный Markdown QQ с запасным вариантом в виде обычного текста | HTML-форматирование из Markdown агента |
| Жизненный цикл токена | TTL 2 часа, автообновление при 80% | Постоянный токен бота |
| Групповые сообщения | Боту доставляются только сообщения с @упоминанием | Бот видит все сообщения (если режим приватности выключен) |
| Индикатор набора | Недоступно (ограничение API QQ) | Сообщение «Работает…» |
| Sandbox-режим | Поддерживается для тестирования | Недоступно |
Устранение неполадок
Бот не отвечает
- Проверьте вывод в терминале на наличие ошибок.
- Убедитесь, что канал запущен (
qwen channel status). - Если используется
privatePolicy: "allowlist", проверьте, что ваш QQ ID находится вallowedUsers. - При первом запуске в терминале появится QR-код — отсканируйте его с помощью приложения QQ.
Бот не отвечает в группах
- Проверьте, что
groupPolicyустановлено в"allowlist","pairing"или"open"(по умолчанию"disabled"). - Если используется
"pairing", убедитесь, что запрос на спаривание группы был одобрен. - Вы должны @упомянуть бота — QQ доставляет только сообщения с тегом бота.
- Убедитесь, что бот добавлен в группу.
Вход по QR-коду завис
- QR-код отображается в терминале. Отсканируйте его с помощью мобильного приложения QQ (Я → Сканировать).
- Если QR-код истёк (обычно через несколько минут), перезапустите канал, чтобы получить новый.
Сообщения в Markdown отображаются как обычный текст
- Возможно, сервер QQ отклонил сообщение в Markdown, и канал незаметно переключился на обычный текст. Проверьте терминал на наличие логов
"Markdown rejected". - На платформе QQ Bot Open Platform это редкость, но может произойти, если возможность использования Markdown ограничена на стороне сервера.
Срок действия токена истёк после долгого простоя
- Если канал был отключён более 2 часов, токен доступа истечёт. При переподключении канал получает новый токен — никаких действий не требуется.
- Если сам AppSecret стал недействительным (например, был изменён на портале разработчика), обновите поле
appSecretили удалите файл~/.qwen/channels/<name>-credentials.json, чтобы повторно запустить вход по QR-коду.