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

WeCom(企業微信)

SHA1 ソート+AES-256-CBC コールバックエンベロープを用いた WeCom 自社製アプリのメッセージング。中国企業向けデプロイの標準チャネルです。

🟡 送信対応・受信サポート済み。最も一般的なデプロイ形態である自社製アプリパスを中心に実装されています。WeChat OA と同じレガシー SHA1 + AES エンベロープを使うため、共有ヘルパー wxcrypt が両プロバイダーをカバーします。

できること

  • POST /cgi-bin/message/send による送信テキストメッセージ。1 人以上の touser 宛、またはエージェント全体へは @all を指定できます。
  • /webhooks/wecom への受信コールバックイベント。WeCom はすべてのコールバックに msg_signature[token, timestamp, nonce, encrypt] を辞書順ソートした SHA1)を付与します。ボディは 43 文字の EncodingAESKey を使った AES-256-CBC で暗号化されます。
  • アプリごとの access_token を 2 時間キャッシュし、自動更新します。
  • 現時点ではテキストのみ対応。 画像・ファイルのアップロード("upload media" エンドポイント)は今後の拡張予定です。
  • テキスト上限は 2048 文字(マークダウンは 4096 文字ですが、現時点では未接続)。

セットアップ

1. 自社製アプリケーションの作成

  1. WeCom 管理コンソール にサインインします。
  2. 「アプリケーションとミニプログラム」→「自社製」→「作成」へ進みます。
  3. アプリケーションのメタデータを入力し、詳細ページで AgentIDSecret を控えます。
  4. 企業レベルの CorpID は「マイ企業」→「企業情報」にあります。

2. コールバックの有効化(受信する場合のみ)

  1. アプリケーション詳細ページ →「API 受信」→「API 受信設定」を開きます。
  2. URL を https://<your-host>/webhooks/wecom に設定します。
  3. Token(任意の不透明文字列)を入力し、EncodingAESKey(43 文字の Base64)は「ランダム生成」をクリックします。
  4. 「保存」をクリックします。WeCom が GET ハンドシェイクで URL を叩き、Minara が echostr を復号してエコーバックし、バインディングが完了します。

3. Minara の設定

minara auth messaging add
# `wecom` を選び、corp id・agent id・secret・default touser・
# callback token・EncodingAESKey を貼り付けます。

または環境変数を直接設定します。

WECOM_CORP_ID=ww<...>
WECOM_AGENT_ID=1000002
WECOM_SECRET=<application secret>
WECOM_DEFAULT_TOUSER=user1|user2     # または @all
WECOM_CALLBACK_TOKEN=<callback token>
WECOM_CALLBACK_AES_KEY=<43-char EncodingAESKey>

WECOM_DEFAULT_TOUSER は WeCom の慣習に従い、パイプ区切りのユーザー ID、またはエージェントの全対象者へは @all を指定します。

4. テスト

minara auth messaging test wecom

デフォルトリストの各 touser に「✅ Minara gateway test ping」が届きます。

受信 Webhook

WeCom はメッセージシグネチャをヘッダーではなく URL クエリに付与します。Minara はボディを復号する前に、SHA1(sort([token, timestamp, nonce, encrypt]).join("")) に対して msg_signature を検証します(Tencent のレガシー IM 方式)。

GET URL 検証ハンドシェイクでは、WeCom が ?msg_signature=…&timestamp=…&nonce=…&echostr=<base64> を送信します。Minara はシグネチャを検証し、AES キー(IV はキーの先頭 16 バイト)で echostr を復号してプレーンテキストをエコーします。Token または AES キーが誤っている場合は 401 / 500 を返します。

復号後の XML ペイロード内部:

<xml>
  <ToUserName>...</ToUserName>
  <FromUserName>...</FromUserName>
  <CreateTime>...</CreateTime>
  <MsgType>text</MsgType>
  <Content>...</Content>
  <MsgId>...</MsgId>
</xml>

現時点では MsgType=text のメッセージのみ Agent に送出されます。画像・音声・イベントタイプはサイレントに破棄されます。

制限・注意事項

  • access_token とコールバックトークンは別物です。 前者は WeCom のアプリごとの OAuth、後者はコールバック用の共有署名シークレットです。env ファイルで混同しないようにしてください。
  • @all はよくある落とし穴です。 エージェントのスコープ内の全ユーザーに通知が届くため、本番環境では WECOM_DEFAULT_TOUSER を特定のユーザー ID に固定してください。
  • AES キーの長さは必須要件です。 キーが正確に 32 バイトにデコードされない(43 文字の Base64 ではない)場合、WeCom は拒否します。

トラブルシューティング

「Get access token failed (errcode 40013)」

  • WECOM_CORP_ID が、その Secret が属する企業と一致していません。

「受信 Webhook が 401 を返す」

  • msg_signature が一致していません。最も多い原因は WECOM_CALLBACK_TOKEN の誤字です。まれに、リバースプロキシがシグネチャクエリを除去しているケースもあります。

「signCallbackParams length mismatch」

  • WECOM_CALLBACK_AES_KEY が 43 文字ではありません。WeCom コンソールから再生成してください。

リファレンス

目次