Contents
導入と事前チェック
Chatwork API 連携を短時間で実装するための実務ガイドです。まずは事前に確認すべき項目を整理し、curlでの動作確認から自動化、運用までの最短ルートを示します。初心者向けに必要な権限やroom_idの取得手順、成功/エラー応答例を明示します。
事前チェックリスト(最低限確認すること)
まず着手前にこれらを確認してください。
- APIトークンを発行できるアカウントを用意していること(管理者権限が必要な場合はその手配)
- 対象となるチャットルームにAPIトークンの発行者が参加していること(room_id を取得できる)
- 開発環境で curl / jq(または代替ツール)が使えること
- シークレット管理(環境変数/Secrets Manager 等)の方針が決まっていること
期待されるレスポンス(成功/エラー例)
実務でよく目にするレスポンス例を示します。実際のフィールドは公式ドキュメントを確認してください。
成功(メッセージ送信の例):
|
1 2 3 4 5 6 7 |
HTTP/1.1 200 OK Content-Type: application/json { "message_id": "987654321" } |
認証エラー(例):
|
1 2 3 4 5 6 7 |
HTTP/1.1 401 Unauthorized Content-Type: application/json { "errors": ["Invalid API token"] } |
レート超過(例):
|
1 2 3 4 5 6 7 8 |
HTTP/1.1 429 Too Many Requests Content-Type: application/json { "errors": ["Rate limit exceeded"], "retry_after": 30 } |
上記はあくまで例です。実際の詳細は公式ドキュメント(下部参照)で最新版を確認してください。
認証とトークン管理
Chatwork API は基本的にAPIトークンを使うヘッダー認証です。トークンの保管やローテーション、最小権限の運用設計が運用リスク低減に直結します。ここではヘッダー仕様と運用手順、シークレット管理の具体例を示します。
認証ヘッダーと必要権限
認証はHTTPヘッダーで行います。一般的なヘッダーは次の通りです。実装では環境変数でトークンを読み込んでください。
- リクエストヘッダー(例):X-ChatWorkToken: {API_TOKEN}
必要な確認事項:
- トークン所有者が対象のルームに参加しているかを確認すること。room_id は GET /rooms で取得できます。
- ログにトークンを出力しないこと。デバッグ時もマスクすること。
- 通信は必ず HTTPS を使用すること。
トークンのローテーションと運用手順
トークンは定期的にローテーションし、漏洩時の影響を最小化します。標準的な手順は次のとおりです。
- 新しいトークンを発行する(サービス連携画面など)
- 新トークンをシークレットストアへ登録し、アプリに配布する
- 新しいトークンで検証(curlで簡単に確認)を行う
- 問題なければ古いトークンを失効させる
- ローテーション履歴と実施ログを保管する(監査用)
権限最小化の実務ポイント:
- 専用のサービスアカウントを作り、必要なルームのみ参加させる
- 人的アカウントのトークン利用は避け、運用変更時のみ行う
シークレット管理の実装例(AWS Secrets Manager / Azure / GCP)
シークレットは専用ストアで管理し、アプリ側はランタイムに取得します。例として AWS Secrets Manager と簡単なコード例を示します。
Node.js(AWS SDK v3)の例:
|
1 2 3 4 5 6 7 8 9 10 |
// npm install @aws-sdk/client-secrets-manager const { SecretsManagerClient, GetSecretValueCommand } = require('@aws-sdk/client-secrets-manager'); async function getSecret(secretId) { const client = new SecretsManagerClient({}); const cmd = new GetSecretValueCommand({ SecretId: secretId }); const res = await client.send(cmd); return JSON.parse(res.SecretString || '{}'); } |
Python(boto3)の例:
|
1 2 3 4 5 6 7 8 9 |
# pip install boto3 import boto3 import json def get_secret(secret_name, region_name=None): client = boto3.client('secretsmanager', region_name=region_name) resp = client.get_secret_value(SecretId=secret_name) return json.loads(resp['SecretString']) |
IAM ポリシー(最小例):
|
1 2 3 4 5 6 7 8 9 10 11 |
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["secretsmanager:GetSecretValue"], "Resource": "arn:aws:secretsmanager:リージョン:アカウントID:secret:シークレット名-*" } ] } |
シークレット管理は組織ポリシーに合わせて設計してください。
主要エンドポイント(メッセージ・タスク・ファイル)
API の主要操作をメッセージ送信、タスク作成、ファイルアップロードに分けて整理します。各操作で使うパラメータと代表的な成功/エラー例を載せるので実装・テスト時の参照にしてください。
ベースURL(例):https://api.chatwork.com/v2
API のバージョンや仕様は変更される可能性があるため、必ず公式ドキュメントを参照してください。
メッセージ送信
メッセージ送信の概要と主要パラメータを示します。
| 操作 | メソッド | パス | 主要パラメータ | 成功レスポンス(例) | 主なエラー |
|---|---|---|---|---|---|
| メッセージ送信 | POST | /rooms/{room_id}/messages | body(本文) | {"message_id":"123456789"} | 401(認証)、403(権限)、429(レート) |
例(成功レスポンス):
|
1 2 3 |
HTTP/1.1 200 OK {"message_id":"123456789"} |
注意点:本文は UTF-8 でエンコードし、フォームエンコード(application/x-www-form-urlencoded)で送るのが一般的です。
タスク作成
タスク作成の主要項目とレスポンスの例を示します。
| 操作 | メソッド | パス | 主要パラメータ | 成功レスポンス(例) | 主なエラー |
|---|---|---|---|---|---|
| タスク作成 | POST | /rooms/{room_id}/tasks | body, to_ids(カンマ区切り), limit(UNIXタイム) | {"task_id":"98765"} | 400(パラメータ不正)、403(権限) |
実務ポイント:to_ids は正確なアカウントIDを指定すること。期限は UNIX タイムスタンプで渡します。
ファイルアップロード
ファイル送信は multipart/form-data を使用します。サイズ・形式に注意してください。
| 操作 | メソッド | パス | 主要パラメータ | 成功レスポンス(例) | 主なエラー |
|---|---|---|---|---|---|
| ファイルアップロード | POST | /rooms/{room_id}/files | file(バイナリ), message(説明) | {"file_id":"55555","message_id":"66666"} | 413(サイズ超過)、415(形式非対応) |
curl 例(multipart):
|
1 2 3 4 5 |
curl -H "X-ChatWorkToken: ${CHATWORK_TOKEN}" \ -F "file=@./sample.pdf" \ -F "message=資料添付" \ "https://api.chatwork.com/v2/rooms/{room_id}/files" |
ファイルサイズ上限や対応形式は公式ドキュメントで確認してください。
動作確認と自動化(curl → Node.js / Python)
まずは curl で一度送って成功を確認することが運用上重要です。ここでは必須の curl 手順と、実務で使える Node.js・Python の実装例を示します。サンプルにはタイムアウトとリトライの注意点を含めています。
curlでの必須検証
curl を使った最小検証の手順と注意点を示します。各コマンドの前に短い説明を添えます。
ルーム一覧の取得(room_id 確認):
|
1 2 |
curl -i -H "X-ChatWorkToken: ${CHATWORK_TOKEN}" "https://api.chatwork.com/v2/rooms" |
出力の確認ポイント:HTTP ステータスが 200、出力が JSON 配列になっているかを確認します。
メッセージ送信(本文のみ):
|
1 2 3 4 5 |
curl -i -X POST \ -H "X-ChatWorkToken: ${CHATWORK_TOKEN}" \ -d "body=テストメッセージ" \ "https://api.chatwork.com/v2/rooms/{room_id}/messages" |
成功時は HTTP 200/201 と JSON 内に message_id が含まれることを確認します。エラー時はレスポンス本文とステータスコードをログに残してください。
ファイルアップロード(multipart):
|
1 2 3 4 5 6 |
curl -i -X POST \ -H "X-ChatWorkToken: ${CHATWORK_TOKEN}" \ -F "file=@./sample.pdf" \ -F "message=添付します" \ "https://api.chatwork.com/v2/rooms/{room_id}/files" |
大きいファイルは 413 等になるため事前にサイズをチェックしてください。
Node.js 実務サンプル(axios)
実運用向けのポイント:タイムアウト、リトライ(429/5xx)、トークンマスキング、multipart のヘッダー自動設定。
インストール:
- npm install axios form-data
サンプル(簡潔な実装例):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
// send.js const axios = require('axios'); const FormData = require('form-data'); const fs = require('fs'); const TOKEN = process.env.CHATWORK_TOKEN; const ROOM_ID = process.env.CHATWORK_ROOM_ID; if (!TOKEN || !ROOM_ID) throw new Error('環境変数 CHATWORK_TOKEN / CHATWORK_ROOM_ID が必要です'); const client = axios.create({ baseURL: 'https://api.chatwork.com/v2', timeout: 8000, // ms headers: { 'X-ChatWorkToken': TOKEN } }); function mask(token) { if (!token) return ''; return token.slice(0, 4) + '*'.repeat(Math.max(0, token.length - 8)) + token.slice(-4); } async function requestWithRetry(fn, retries = 3, baseDelay = 500) { for (let i = 0; i <= retries; i++) { try { return await fn(); } catch (err) { const status = err.response?.status; const shouldRetry = (status === 429 || (status >= 500 && status < 600) || !err.response); if (!shouldRetry || i === retries) throw err; const delay = baseDelay * Math.pow(2, i); await new Promise(r => setTimeout(r, delay + Math.random() * 200)); } } } async function sendMessage(body) { const params = new URLSearchParams({ body }); const res = await requestWithRetry(() => client.post(`/rooms/${ROOM_ID}/messages`, params.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }) ); return res.data; } async function uploadFile(filePath, message) { const form = new FormData(); form.append('file', fs.createReadStream(filePath)); form.append('message', message); const headers = { ...form.getHeaders(), 'X-ChatWorkToken': TOKEN }; const res = await requestWithRetry(() => axios.post(`https://api.chatwork.com/v2/rooms/${ROOM_ID}/files`, form, { headers, timeout: 20000 }) ); return res.data; } (async () => { try { console.log('token=', mask(TOKEN)); console.log(await sendMessage('自動化メッセージ')); console.log(await uploadFile('./sample.pdf', '自動アップロード')); } catch (err) { if (err.response) { console.error('Status:', err.response.status, err.response.data); } else { console.error('Network/Error:', err.message); } } })(); |
注意点:
- form.getHeaders() で Content-Type を自動設定する。手動で上書きしないこと。
- axios のタイムアウトは短すぎないようにし、ファイル送信は長めに設定する。
- レスポンスが空の場合やネットワークエラーは err.response が undefined になるので適切にハンドリングする。
Python 実務サンプル(requests + Retry)
実運用では requests.Session に Retry を組み合わせ、タイムアウトを必ず指定します。
インストール:
- pip install requests
サンプル:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# send.py import os import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry TOKEN = os.environ.get('CHATWORK_TOKEN') ROOM_ID = os.environ.get('CHATWORK_ROOM_ID') if not TOKEN or not ROOM_ID: raise SystemExit('環境変数 CHATWORK_TOKEN / CHATWORK_ROOM_ID を設定してください') session = requests.Session() retries = Retry(total=5, backoff_factor=0.5, status_forcelist=[429,500,502,503,504], allowed_methods=["GET","POST","PUT","DELETE","OPTIONS"]) session.mount("https://", HTTPAdapter(max_retries=retries)) session.headers.update({'X-ChatWorkToken': TOKEN}) def send_message(body, timeout=8): r = session.post(f'https://api.chatwork.com/v2/rooms/{ROOM_ID}/messages', data={'body': body}, timeout=timeout) r.raise_for_status() return r.json() def upload_file(path, message, timeout=30): with open(path, 'rb') as f: files = {'file': f} data = {'message': message} r = session.post(f'https://api.chatwork.com/v2/rooms/{ROOM_ID}/files', files=files, data=data, timeout=timeout) r.raise_for_status() return r.json() if __name__ == '__main__': try: print(send_message('Pythonからのテスト')) print(upload_file('sample.pdf', 'Pythonからの添付')) except requests.exceptions.RequestException as e: print('Error:', e) |
実務注意点:ファイルサイズが大きい場合はストリーミングや分割アップロードの検討が必要です。API側の制約は公式ドキュメントを確認してください。
受信と連携パターン(Webhook / ポーリング / iPaaS)
外部から Chatwork への通知(受信側設計)は、Webhook の有無や運用要件で選択が変わります。ここでは選択肢ごとの設計要点を示します。
Webhookの可否確認と設計上の注意
まず公式ドキュメントで Webhook の提供状況を確認してください。提供されている場合は次の観点で設計します。
- 受信エンドポイントの署名検証(HMAC 等)で改竄防止を行う
- リプレイ対策(timestamp と一意 ID を検証)を実装する
- 受信エンドポイントは冪等にし、二重通知に耐える設計にする
Webhook がない場合はポーリング/iPaaS を検討します。
ポーリング実装の設計(差分取得・重複防止)
Webhook が使えないときの代表設計です。実務上のポイントは下記です。
- 差分検出:最後に処理した message_id またはタイムスタンプを永続化して以降の新着のみ処理する。
- ポーリング間隔:要件とレート制限を見て決める。高頻度は避ける。
- 重複防止:message_id でデデュープ、処理は冪等にする。
- エラー時:429 / 5xx は指数バックオフ+ジッターで再試行する。
- スケール:メッセージをキュー化してワーカーで平準化する(SQS / Pub/Sub 等)。
簡単な擬似コード:
|
1 2 3 4 5 6 7 8 9 10 |
last_id = load_last_id() while True: msgs = get_messages(room_id) for m in sorted(msgs, key=lambda x: int(x['message_id'])): if int(m['message_id']) > last_id: process(m) last_id = int(m['message_id']) save_last_id(last_id) sleep(poll_interval) |
iPaaS(Zapier / Make / BizteX)活用の実務ポイント
非エンジニアや短期構築には iPaaS を使うと早いです。注意点は次のとおりです。
- API トークンは iPaaS のシークレット機能で安全に保管すること
- 再試行ポリシーやログ保存設定を確認すること
- ファイル転送時に multipart を正しく扱えるかを事前に確認すること
iPaaS を使う場合でも、差分や重複対策、アップロード制限は実装要件として押さえてください。
運用・監視・トラブルシューティング
本番運用で重要なのは安定性と復旧手順です。レート制御、監視項目、よくある障害と対処法をまとめます。
レートリミットとリトライ設計
レート制御は API 利用の安定性に直結します。具体的な制限値は公式ドキュメントを確認してください。設計の基本方針は以下です。
- 429 や 5xx は指数バックオフ+ジッターでリトライする
- 再試行回数の上限を決め、必要なら通知を上げる(アラート)
- バッチ化やキュー化でリクエスト集中を回避する
429 のサンプル(例):
|
1 2 3 4 5 6 7 8 |
HTTP/1.1 429 Too Many Requests Content-Type: application/json { "errors": ["Rate limit exceeded"], "retry_after": 60 } |
retry_after の有無や単位は API に依存します。必ず公式ドキュメントを参照してください。
監視・アラート設計(実務指標)
運用で見るべき主要メトリクスとアラート例を示します。
- エラー率(HTTP 4xx/5xx の割合) → 閾値例:1% を超えたらアラート
- 再試行回数/バックオフ発生率 → 急増があれば原因調査
- レイテンシ(API 応答時間のパーセンタイル) → 95p95 の閾値設定
- キュー長・処理遅延(ポーリング/ワーカ処理) → オートスケールまたは警告
- トークン有効期限・ローテーション失敗の検知
ログはレスポンス本文(トークンはマスク)と相関IDを付けて保存するとデバッグが容易です。
よくあるトラブルと短期対処
代表的な問題と初動対応をまとめます。
- 401 / 403(認証・権限):トークンの有効性、トークン所有者のルーム参加を確認する。curl で再現してログを確認する。
- 413(ファイル大きすぎ):ファイルサイズを縮小するか分割、または外部ストレージにアップしてリンクを送る運用に変更する。
- 429(レート超過):リトライ間隔を伸ばす、送信バッチ化を行う。API 利用のピークを平準化する。
- 5xx(サーバエラー):短時間のリトライを行い、継続する場合は公式サポートに問い合わせる。問い合わせ時にリクエストIDやタイムスタンプを提示できるようにログを用意する。
参考:詳細な操作や最新の仕様は公式ドキュメントを確認してください。
公式ドキュメント・ヘルプ(参照):
- Chatwork 開発者向けドキュメント: https://developer.chatwork.com/
- Chatwork ヘルプセンター(公式): https://help.chatwork.com/hc/ja
上記で仕様やレート制限、UI操作に関する最新情報を確認してください。
まとめ
ここまでの要点を実務的に整理します。curl での動作確認を最初に行い、認証周りとトークン管理を厳格に運用することが成功の鍵です。自動化はタイムアウト・リトライ・ログ設計を含めて実装してください。
- 事前に必要権限と room_id を確認し、まず curl で送受信を検証する。
- トークンはシークレットマネージャで管理し、定期的にローテーションする。
- メッセージ/タスク/ファイルそれぞれの主要パラメータとレスポンスを把握しておく。
- 実装はタイムアウト・リトライ・マスクログを必須とし、監視とアラートを整備する。
- Webhook が無い場合はポーリングや iPaaS、キュー化で安定動作を目指す。
まずは開発用ルームで全操作を検証してから本番に展開してください。公式ドキュメントで最新仕様や制限値を確認することを忘れないでください。