简体中文 English 繁體中文 日本語 Русский
本文为静态镜像,内容以交互版为准 在交互式文档中心打开 →

Документация по функциям платформы QQBot

QQBotAdapter — это адаптер, построенный на основе протокола QQ-бота (QQ OpenAPI), объединяющий функции для чатов в группах, личных сообщений и каналов, предоставляющий стандартные события OneBot12, стандартные API-действия и интерфейсы для выполнения запросов.

Информация о документации

Основная информация

Конфигурация

# config.toml
[QQBot_Adapter]
intents = "[0, 9, 12, 25, 26, 27]"   # Глобально: подписанные события intents (JSON массив, поддерживает имена событий)

[QQBot_Adapter.accounts.default]
appid = "YOUR_APPID"                 # ID приложения QQ-бота (обязательно)
secret = "YOUR_CLIENT_SECRET"        # Секретный ключ клиента QQ-бота (обязательно)
mode = "websocket"                   # Способ получения событий: websocket / webhook
bot_id = ""                          # ID бота (оставьте пустым для автоматического получения; можно вручную указать для использования в Using())
gateway_url = ""                     # URL WebSocket-шлюза (оставьте пустым для динамического получения через /gateway/bot)
api_base_url = "https://api.bot.qq.com"  # Корневой URL API (можно настроить для прокси)
webhook_path = "/webhook"            # Путь обратного вызова webhook (действует при mode=webhook)
enabled = true

Версия v5 — критические изменения:

Описание intents (поддерживает номера позиций или имена событий):

Позиция Имя события Описание
0 GUILDS Изменения каналов
1 GUILD_MEMBERS Изменения участников канала
9 GUILD_MESSAGES Сообщения канала (внутриканальные)
12 DIRECT_MESSAGE Личные сообщения канала
24 GROUP_MEMBER Изменения участников группы (ново в v5)
25 GROUP_AND_C2C_EVENT Сообщения упоминания в группе и личные сообщения
26 INTERACTION Взаимодействие (кнопки и т.д.)
27 MESSAGE_AUDIT События проверки сообщений
30 PUBLIC_GUILD_MESSAGES Сообщения канала (внешние каналы)

Отправка сообщений

Базовая отправка

from ErisPulse import sdk
qqbot = sdk.adapter.get("qqbot")

await qqbot.Send.To("user", user_openid).Text("Hello World!")

# Упоминание в чате (автоматически использует формат <qqbot-at-user id="x" />)
await qqbot.Send.To("group", group_openid).At("member_openid").Text("@你")

# Сообщение в канале (автоматически использует формат <@user_id>)
await qqbot.Send.To("channel", channel_id).Text("Сообщение в канале")

# Ответ на сообщение (автоматически включает msg_id, не нужно использовать Reply вручную)
await qqbot.Send.To("group", group_openid).Reply(msg_id).Text("Содержимое ответа")

# Мультимедиа (URL / локальный путь / бинарные данные; файлы больше 5 МБ загружаются по частям)
await qqbot.Send.To("group", gid).Image("https://example.com/img.png")

# Markdown (в виде исходного текста / шаблона)
await qqbot.Send.To("group", gid).Markdown("# Заголовок\n- Список")
await qqbot.Send.To("user", uid).Markdown(template_id=1, kv=[{"key": "title", "value": "Уведомление"}])

# Клавиатура (автоматически устанавливается тип markdown и добавляется bot_appid)
await qqbot.Send.To("group", gid).Keyboard(keyboard).Text("Выберите опцию")

# Потоковое сообщение (личный чат)
await qqbot.Send.To("user", openid).Stream("Содержимое ответа")

# Множественные аккаунты
await qqbot.Send.Using("account2").To("group", gid).Text("От второго бота")

OneBot12 стандартный API-действия

result = await qqbot.Api.get_self_info()                     # Информация о боте
result = await qqbot.Api.get_group_info(group_openid)        # Информация о группе
result = await qqbot.Api.get_group_member_list(group_openid) # Список участников группы (автоматическая пагинация)
result = await qqbot.Api.get_guild_list()                    # Список каналов
result = await qqbot.Api.get_channel_list(guild_id)          # Список подканалов
await qqbot.Api.delete_message(message_id)                   # Отмена сообщения (автоматический маршрут по источнику сообщения)
result = await qqbot.Api.get_status()                        # Статус работы нескольких аккаунтов
result = await qqbot.Api.Using("account2").get_self_info()   # Указание аккаунта

Поддерживаемые стандартные действия: get_self_info / get_group_info / get_group_member_info / get_group_member_list / get_guild_info / get_guild_list / get_guild_member_info / get_guild_member_list / get_channel_info / get_channel_list / set_channel_name / leave_channel / delete_message / get_status / get_version / get_supported_actions. Действия, которые не поддерживаются, возвращают retcode=10002.

Операции с запросами (одобрение заявки на вступление в группу)

Событие GROUP_JOIN_REQUEST преобразуется в событие request по стандарту OneBot12 и поддерживает стандартизованное одобрение:

from ErisPulse.Core.Event import request as request_event

@request_event.on_request()
async def handle_join(event):
    if event.get("platform") == "qqbot":
        await event.approve()                  # Принять
        # await event.reject(comment="Причина")   # Отклонить

request_id = join_request_id от официального API, адаптер автоматически кэширует контекст заявки и маршрутизирует запрос на POST /v2/groups/{group_openid}/approval_join_request/{member_openid}.

@Механизм обнаружения бота (важно)

Факт упоминания бота в QQ официально передаётся через имя события, а упоминание пользователя в группе имеет вид <@{openid пространства группы}> (это не относится к той же системе идентификаторов, что и bot_id, возвращаемый READY). Адаптер автоматически обрабатывает:

  1. Анализ меток: <@openid> и <qqbot-at-user> оба стиля анализируются как упоминания (упоминания не остаются в тексте)
  2. Нормализация имён: если имя бота, возвращённое /users/@me, совпадает с именем в массиве упоминаний, упоминание нормализуется как bot_id (оригинальный openid сохраняется в data.qqbot_openid)
  3. Обучение openid: автоматически обучается openid бота в каждой группе, используется для распознавания упоминаний в режиме "получать все сообщения из группы"
  4. Гарантия вставки: GROUP_AT_MESSAGE_CREATE / AT_MESSAGE_CREATE гарантируют наличие упоминания бота

Таким образом, on_at_message() / event.is_at_message() можно использовать напрямую на платформе qqbot. После включения разрешения "получать все сообщения из группы" упоминания будут отправляться через GROUP_MESSAGE_CREATE (событие GROUP_AT_MESSAGE_CREATE больше не поступит), адаптер также способен распознавать упоминания.

Семейство методов платформенных API

Адаптер предоставляет полный набор официальных API QQ (подробности см. в файле platform-features.md репозитория адаптера):

WebSocket / Webhook подключение

Поток WebSocket

  1. appId + clientSecret для получения access_token (автоматическое обновление за 45 с до истечения срока действия, неудача повторяется 3 раза)
  2. Используя GET /gateway/bot динамически получите адрес шлюза (при настройке gateway_url используйте его напрямую)
  3. OP_HELLO → Identify/Resume → READY (получение session_id и bot_id) → цикл поддержания соединения
  4. Переподключение при разрыве: максимум 50 попыток, экспоненциальная задержка min(5 * 2^n, 300) секунд; OP_RECONNECT сохраняет сессию

Режим Webhook

После установки режима mode = "webhook" для аккаунта, через маршрутизатор ErisPulse зарегистрируйте HTTP-маршруты:

Описание кодов ошибок

retcode Описание
0 Успешно
10001 Отсутствуют параметры
10002 Действие не поддерживается
10003 Цель/учетная запись не может быть определена
32000 Время ожидания запроса истекло
33000 Аномалия сети/вызов API
34001 Запрос не существует или просрочен (Request DSL)
34100 Не удалось загрузить медиафайл
34000+ Ошибка бизнес-процесса платформы (прозрачный код от официального источника)

Использование примеров

Обработка групповых сообщений (по @)

from ErisPulse.Core.Event import message

@message.on_at_message()
async def handle_at(event):
    if event.get("platform") != "qqbot":
        return
    text = event.get_text()
    if text == "签到":
        await event.reply("已签到")

Обработка взаимодействий

from ErisPulse.Core.Event import notice

@notice.on_notice()
async def handle_interaction(event):
    if event.get("platform") != "qqbot":
        return
    if event.get("detail_type") == "qqbot_interaction":
        await qqbot.reply_interaction(event.get("qqbot_interaction_id"), code=0)
        button_id = event.get("qqbot_button_id", "")
        # Обработка кнопки...

Запуск нескольких аккаунтов

[QQBot_Adapter.accounts.bot_a]
appid = "A_APPID"
secret = "..."
enabled = true

[QQBot_Adapter.accounts.bot_b]
appid = "B_APPID"
secret = "..."
mode = "webhook"
enabled = true

Два аккаунта запускаются параллельно: bot_a использует WebSocket, bot_b использует Webhook, они не влияют друг на друга.