0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Chatworkシリーズ #7】コンタクト承認をn8nで自動化しようとしたら、3つの罠にハマった

0
Last updated at Posted at 2026-03-14

「コンタクト承認くらい、自動化できるだろ」

15分で終わると思っていた。n8nにHTTP Requestノードを3つ並べて、IFで分岐して、終わり。そういうイメージだった。

結果、半日かかった。Chatwork APIの仕様、MCPサーバーのバグ、日本語の漢字——3つの全く違う方向から殴られた記録を書く。

やりたかったこと

Chatworkには「コンタクト承認」という仕組みがある。ダイレクトメッセージを送る前に、相手にコンタクト申請を出して、承認してもらう必要がある。LINEの友だち追加に近い。

問題は、事務局の仕事をしていると申請が大量に来ることだ。講座の受講生が一斉にコンタクト申請を送ってくる。10人、20人。一つずつブラウザで「承認」ボタンを押すのは、正直やってられない。

n8nで15分おきにコンタクト申請を自動チェックし、名簿に載っている人は自動承認する——そういうワークフローを作ろうとした。

罠①:204 No Contentでn8nが死ぬ

まず最初に組んだのは単純な構成だ。

Schedule Trigger(15分) → HTTP Request(GET /incoming_requests) → IF(申請あり) → HTTP Request(PUT /incoming_requests/{id})

テストで動かしてみる。申請がある状態では問題なく動く。だが、申請が0件のときにワークフローが死ぬ

エラーメッセージ:

ERROR: Invalid JSON in response body

原因はChatwork APIの仕様にある。GET /incoming_requestsは、申請が0件のときHTTP 204 No Contentを返す。レスポンスボディは空。

n8nのHTTP Request node(V4.2)は、デフォルトでレスポンスをJSONとしてパースしようとする。空のボディをJSONパースすれば、当然エラーになる。

試して効かなかったもの

  • onError: "continueRegularOutput" — JSON parseエラーはこの設定では捕捉されない
  • options.response.neverError: true — HTTPステータスエラーだけを抑制する。JSON parseは別の話

解決策

responseFormat"text"に変更し、後続にCodeノードを追加する。

// Codeノード:申請データパース
const rawBody = $input.first().json.data;

if (!rawBody || rawBody.trim() === '') {
  // 204 No Content(申請0件)
  return [{ json: { request_id: null } }];
}

const requests = JSON.parse(rawBody);
return requests.map(r => ({ json: r }));

後続のIFノードでrequest_idがnullかどうかを判定し、nullならスキップ。これで申請0件のときも死なずに回る。

教訓:HTTP 204を返す可能性があるAPIをn8nで呼ぶときは、responseFormat"text"にしてCodeノードで手動パースする。

罠②:Chatwork MCPサーバーのAPIパスが違う

n8nで組む前に、まずClaude CodeからChatwork MCP(Model Context Protocol)サーバー経由で手動承認を試みた。#5で書いた通り、34のAPIが全部使える便利なやつだ。だが、すべてのエンドポイントが完璧に動くわけではなかった。

> コンタクト申請一覧を確認して、承認して

申請一覧の取得(list_incoming_requests)は問題なく動く。だが承認(accept_incoming_request)を呼ぶと400エラーが返ってくる。

ソースコード(@chatwork/mcp-server v0.0.4のtoolCallbacks.ts)を読んで原因がわかった。APIのパスが違う。

# Chatwork API仕様
PUT /incoming_requests/{request_id}

# MCPの実装(toolCallbacks.ts)
PUT /incoming_requests/{request_id}/accept  ← /acceptが余計

HTTPメソッド(PUT)は合っている。だがパスの末尾に /accept が付いている。Chatwork APIにこのパスは存在しない。結果、400エラーが返る。

回避策

MCPを使わず、curlで直接叩く。

curl -X PUT \
  -H "X-ChatWorkToken: YOUR_TOKEN" \
  "https://api.chatwork.com/v2/incoming_requests/{request_id}"

n8nのHTTP Request nodeでも同じようにPUTを指定すれば問題ない。MCP経由ではなくAPI直叩きが正解。

教訓:MCPサーバーは便利だが、エラーが出たらソースコードとAPIの仕様書を突き合わせる。MCPが正しいとは限らない。

罠③:「髙橋」と「高橋」は別人

ここまでで技術的な問題は片付いた。あとは名簿との照合ロジックを組むだけ——と思っていた。

コンタクト申請の自動承認で一番重要なのは「この人は本当に名簿に載っている人か」の判定だ。知らない人を自動承認してはいけない。

Chatworkの申請データにはアカウント名が含まれる。名簿にも名前がある。一致すれば承認。単純な話だ。

ところが、ある受講生の照合が失敗した。仮に「高橋さん」としよう。

名簿を見ると「髙橋」と書いてある。Chatworkには「高橋」で登録されている。

わかるだろうか。

名簿:髙橋(はしご高)— U+9AD9
CW :高橋(普通の高)— U+9AD8

Unicodeの別文字だ。 人間の目には同じ「高」に見えるが、コンピュータにとっては完全に別の文字。完全一致でも部分一致(先頭2文字)でもヒットしない。

これは日本語の人名処理ではよくあるハマりポイントだ。異体字のバリエーションは多い:

よく見る字 異体字 Unicode
U+9AD8 / U+9AD9
U+5D0E / U+FA11
U+6D5C / U+6FF5
邊 邉 U+8FBA / U+908A / U+9089
齋 齊 U+658E / U+9F4B / U+9F4A

対策の選択肢

  1. 異体字マッピングテーブルを作る — 髙→高、﨑→崎のような変換表を用意して、照合前に正規化する
  2. Unicode正規化(NFKC)を適用する — ただし髙→高はNFKCでも変換されない場合がある
  3. フリガナで照合する — カタカナなら異体字問題が発生しない。名簿にフリガナがあればこちらを使う

今回は手動で「この人です」と確認して対処した。自動化の中に手動が挟まるのは不本意だが、知らない人を自動承認するよりマシだ。

今後の対策としては、漢字の完全一致だけに頼らず、フリガナのフォールバックを用意するのが安全だろう。名簿にフリガナがあればカタカナで照合すれば異体字問題は発生しない。そもそも名簿の設計段階でフリガナ欄を必須にしておくと、この手のトラブルを根元から防げる。

教訓:日本語の人名照合では、漢字一致を信用しすぎない。異体字は思った以上に多い。

完成したワークフロー

最終的に動いている構成はこうなった。

Schedule Trigger(15分おき)
  ↓
HTTP Request: GET /incoming_requests (responseFormat: text)
  ↓
Code: 空ボディチェック + JSONパース
  ↓
IF: request_id が null でない
  ↓
HTTP Request: GET /名簿API(照合用)
  ↓
Code: 名前照合(漢字 + フリガナフォールバック)
  ↓
IF: 名簿に存在する
  ├─ true → HTTP Request: PUT /incoming_requests/{id}(承認)
  └─ false → 通知(手動確認が必要な申請として報告)

申請が来たら15分以内に自動承認。名簿にない人は手動確認に回す。204で死なない。異体字にも対応。

「コンタクト承認くらい簡単だろ」と思っていた半日前の自分に伝えたい。APIの仕様書は隅々まで読め。HTTPメソッドは信用するな。日本語の漢字は信用するな。


まとめ

原因 解決策
204 No Content Chatwork APIが申請0件で空レスポンスを返す responseFormatをtextにしてCodeノードで手動パース
MCPのパス不一致 accept_incoming_requestのパスに余計な/acceptが付いている API直叩き(PUT)を使う
異体字(髙 vs 高) Unicodeの別文字で照合失敗 フリガナフォールバックを用意する

Chatwork APIは基本的によくできている。だが、エッジケースは自分で踏んで覚えるしかない。204 No Contentを返すAPIは他にもあるかもしれない。MCPサーバーも発展途上だ。異体字問題はChatworkに限らず、日本語を扱うシステム全般の話だ。

まあ、結局全部自分で踏んで覚えるしかないんだけど。


Chatworkシリーズ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?