MINARA
Minaraを使用するクライアントとインターフェースメッセージングプラットフォーム

QQ 公式 Bot

Ed25519 webhook イベントを使った QQ Official Bot v2 メッセージング。アクティブメッセージは Bot ごとに月 4 件までに制限されるため、受動返信を主体に設計してください。

⚠️ プッシュではなく受動返信を使用してください。 QQ のアクティブメッセージは Bot ごとに月 4 件までです。1 日あたりの上限: アクティブ DM は 200 件、チャネルごとのサブチャネルへのアクティブメッセージは 20 件。本番環境でのやりとりは、ユーザーからの受信メッセージへの返信(Bot の応答は 5 秒以内、無料枠)を基本とし、アクティブなプッシュは重要なアラートのみに限定してください。

利用できる機能

  • 4 種類の送信サーフェスchannel プレフィックスによってルーティングされます。
    • c2c:<openid>/v2/users/{openid}/messages(C2C DM)
    • group:<openid>/v2/groups/{openid}/messages(グループ)
    • channel:<id>(デフォルト) → /channels/{channel_id}/messages(パブリックギルドチャネル)
    • dm:<guild_id>/dms/{guild_id}/messages(プライベートギルド DM)
  • /webhooks/qq への受信 webhook(Ed25519 署名付き)。
  • access_token のキャッシュは 7200 秒で、自動更新に対応。
  • テキストのみ対応。 リッチメディアメッセージ(画像、ファイル、ARK カード)は将来の機能拡張で対応予定。
  • テキスト上限は 4000 文字。

セットアップ

1. Bot を登録する

  1. QQ オープンプラットフォーム Bot コンソールにサインイン
  2. Bot を作成し、Bot 詳細ページの AppIDAppSecret を控える
  3. 「Develop Settings」→「Webhook」から URL を https://<your-host>/webhooks/qq に設定し、「Webhook Mode」を選択
  4. プラットフォームから op=13 のバリデーションハンドシェイクが送信される。Minara は署名済みの plain_token を自動的に返答する。

2. デフォルトの送信先を決める

最もよく使う送信先を選び、プレフィックスを付けてエンコードしてください。

シナリオQQ_BOT_DEFAULT_CHANNEL_ID
パブリックギルドの DM に返信するchannel:<channel id>
グループへプッシュするgroup:<group openid>
特定ユーザーへプッシュするc2c:<user openid>
プライベートギルド DM に返信するdm:<guild id>

パブリックギルドチャネルの場合(最も一般的)はプレフィックスを省略できます。

QQ_BOT_DEFAULT_CHANNEL_ID=1234567890

channel:1234567890 と同等です。

3. Minara を設定する

minara auth messaging add
# `qq` を選択し、AppID・AppSecret・デフォルト送信先を貼り付ける。

または環境変数で設定します。

QQ_BOT_APP_ID=12345678
QQ_BOT_APP_SECRET=<opaque secret>
QQ_BOT_TOKEN=<bot token>
QQ_BOT_DEFAULT_CHANNEL_ID=channel:1234567890

4. テストする

minara auth messaging test qq

月間アクティブメッセージの枠を消費します。 計画的に使用してください。

受信 webhook

QQ は受信ボディに対して <timestamp><raw_body> を Ed25519 で署名します。 公開鍵はプラットフォームから公開されておらず、Bot シークレットから導出されます。

  1. QQ_BOT_APP_SECRET の UTF-8 バイト列を取得する
  2. バッファが 32 バイトに達するまで繰り返す
  3. これを Ed25519 シードとして使用し、鍵ペアを導出する

Minara はこのシード導出による鍵ペアを内部で処理します。リプレイウィンドウは 5 分間で、Discord や Slack と同じ規約に準拠しています。

バリデーションハンドシェイク: プラットフォームから {op: 13, d: {plain_token, event_ts}} が送られた場合、Minara は導出した秘密鍵で event_ts + plain_token に署名し、署名済みの hex を返答します。これによりプラットフォームは、エンドポイントがシークレットを保持していることを確認します。

受け付ける受信イベントの種類:

  • AT_MESSAGE_CREATE: パブリックギルドチャネルで Bot が @メンションされた
  • GROUP_AT_MESSAGE_CREATE: グループで Bot が @メンションされた
  • C2C_MESSAGE_CREATE: ユーザーからの DM

その他の op=0 ディスパッチイベント(チャネル更新、リアクションなど)は無視されます。

制限と注意事項

  • アクティブメッセージの枠制限。 月 4 件、DM は 1 日 200 件、サブチャネルごとに 1 日 20 件。枠を超えるとエラーコード 130_001 が返ります。ある程度のボリュームでプッシュする場合は、このエラーを想定内として扱ってください。
  • 受動返信パターンが想定される利用方法です。 ユーザーが Bot を @メンションし、Bot が 5 秒以内に返信する形式です。この返信はアクティブ枠に含まれません。
  • 新規 Bot は webhook が必須です。 WebSocket のサンドボックスモードは v2 では非推奨となっています。

トラブルシューティング

「テストメッセージで errcode 130001 が返る」

  • 月間アクティブメッセージの枠が消費されています。受動返信を使用してください。

「受信 webhook が 401 を返す」

  • 最もよくある原因: ホストのクロックスキュー。5 分間のリプレイウィンドウは厳格に適用されます。
  • まれな原因: App Secret の一部しか貼り付けていない。短いシークレットはシード導出時に繰り返されますが、誤ったシークレットを使うと誤った公開鍵が生成されます。

「バリデーションハンドシェイク(op=13)が失敗する」

  • 起動時に QQ_BOT_APP_SECRET が設定されていません。設定がないとシード導出が失敗し、プラットフォームのバインドが完了しません。

リファレンス

目次