APIでWhatsAppグループを作成する:IDと初期メンバーの確認
UnifyPortでWhatsAppグループを作成するには、POST /v1/accounts/{account_id}/groups/create に必須の name と任意の members 配列を送信します。この作成リクエストでは、WhatsAppの初期メンバーを電話番号で指定します。成功レスポンスが返すのは data.id であり、参加者ごとの結果ではありません。IDをすぐに保存し、グループとメンバーを取得してから、後続の自動処理を開始してください。
要点
- グループ作成、招待、既存メンバーの管理は別の操作です。
- 初期
membersは電話番号ですが、その後のメンバー管理では別の識別子を使います。 - 公開イベント一覧に
group.createdはありません。この通知を完了条件にしないでください。 - レスポンスがない場合、結果は不明です。作成を自動再試行すると別のグループができる可能性があります。
フォームを作る前にAPIの契約を確認する
グループ作成リファレンスは、次の契約を定めています。UnifyPortは接続済みのメッセージングアカウント向けの非公式インターフェースであり、この操作はWhatsApp Cloud APIのエンドポイントではありません。操作対応表では、グループ作成は現在 whatsapp のみに対応し、LINE、Telegram、別プロバイダーの whatsapp-protocol は含みません。LINEでグループを取得できても、同じ作成操作が使えるとは限りません。
| 値 | 意味 | 代わりに使えない値 |
|---|---|---|
パスの account_id | グループを作成するアカウント | ワークスペースID |
本文の name | 必須のグループ名、最大100文字 | 一意のリソース識別子 |
本文の members | 任意の初期メンバー。WhatsAppでは電話番号 | メンバーLIDの配列のコピー |
レスポンスの data.id | 新しいグループID | 招待コードや操作ID |
作成レスポンスの data に含まれるのは新しいグループIDだけです。参加者ごとの加入結果は返しません。「参加してほしい初期メンバー」と「後で確認した実際のメンバー」を分けて記録してください。
WhatsAppの公式メンバー管理ガイドでは、メンバーの追加、招待、承認を有効にした場合の保留中リクエストの確認を説明しています。これらは別々の利用フローであり、いずれも同じ「参加済み」の証拠にはなりません。既存グループへの参加を本人に選んでもらうなら、別のグループを作るのではなく、招待リンクの取得フローを使います。
確認済みの作成リクエストを一度だけ送る
アカウントのライフサイクルに従い、選択したアカウントの認証が完了し、ランタイムが running であることを確認します。APIキーはバックエンドに保持し、担当者の操作権限もそこで検証してください。
推奨するアプリケーション側の対策は次のとおりです。
- 確認画面にアカウント、予定のグループ名、参加者を表示する。参加を認識し、期待している人だけを追加する。
- 送信前にローカルの作成意図を保存する。担当者と予定の入力は自分のアプリケーションに記録し、独自のAPIフィールドとして送らない。
- 同じ作成意図の並行送信をバックエンドで止める。ブラウザーのボタンを無効化するだけでは不十分。
- 一度だけリクエストし、結果を保存してから後続操作を許可する。
次のサーバー側JavaScriptは、確認済み入力からリクエストを組み立てる例です。ここでは実行しておらず、自動再試行も含めていません。
async function createGroupOnce({ apiKey, accountId, name, phones }) {
if (!apiKey || !accountId || typeof name !== 'string' || !name.trim()) {
throw new Error('Missing credential, account, or group name');
}
const body = { name };
if (phones !== undefined) {
if (!Array.isArray(phones) ||
phones.some(p => typeof p !== 'string' || !/^[0-9]+$/.test(p))) {
throw new Error('Use confirmed phone-number strings');
}
body.members = phones;
}
const response = await fetch(
`https://api.unifyport.ai/v1/accounts/${encodeURIComponent(accountId)}/groups/create`,
{
method: 'POST',
headers: { 'X-Api-Key': apiKey, 'Content-Type': 'application/json' },
body: JSON.stringify(body)
}
);
return { httpStatus: response.status, result: await response.json() };
}
実際に確認した電話番号を、ドキュメントの形式で渡してください。数字の検査はローカルの入力チェックにすぎず、その番号のユーザーが参加できる証明ではありません。名前の長さも仕様どおり検証します。本番実装ではネットワーク障害とJSON以外のレスポンスを扱い、取得できた request_id を安全に保存し、認証情報や参加者の電話番号一覧をログに残さないようにします。
グループIDの保存とメンバー確認を分離する
200 OK と data.id を受け取ったら、返されたIDをアカウントとローカルの作成意図に紐づけて永続化します。続いてグループ取得で、そのIDを group_id として指定します。
参加者は会話メンバー一覧で確認します。グループIDを conversation_id に設定し、type=group を使います。has_more と next_cursor に従って全ページを取得してください。最初のページにいないだけでは、メンバー確認は完了していません。返された peer_id と role はそのまま保持し、電話番号からLIDを推測しないでください。
後続のグループメンバー管理は別契約です。1回のリクエストに単数の member_id と1つの操作を指定し、WhatsAppではメンバー一覧の peer_id として返されたLIDを使います。作成ペイロードをそのまま流用しないでください。管理者の任命が次の作業なら、管理者ロール変更ガイドへ進みます。
| 確認できたこと | 推奨するアプリケーション状態 | 次の処理 |
|---|---|---|
| 成功レスポンスとIDの保存 | 作成済み、メンバー未確認 | グループとメンバー全ページを取得 |
| グループは取得可能、予定メンバーは未確認 | グループは存在、メンバーは要確認 | IDの対応関係や公式アプリで確認 |
| タイムアウト、解析不能、期待したIDなし | 作成結果は未確定 | 再作成の前に照合 |
これらはアプリケーション内部の状態であり、追加のAPIレスポンス値ではありません。
復旧時に重複グループを作らない
標準イベント一覧に group.created はなく、作成成功時にその通知が届く保証もありません。group.updated も、このリクエストごとに必ず届く受領証ではありません。
レスポンスを失ったら、同じアカウントのグループ一覧を全ページ確認します。この一覧には、まだメッセージがない参加済みグループも含まれます。取得可能な情報と公式アプリを使って調査してください。同名であることだけでは同じグループだと証明できず、取得失敗や不完全なページ取得も作成失敗の証拠にはなりません。
公開の作成契約には冪等性キーの記載がありません。ローカルの作成意図は自分のアプリケーションによる二重送信を抑えますが、上流の処理を厳密に一度だけにする保証ではありません。結果が未確定の間は、関連する招待や自動メッセージを保留し、再作成の前に担当者の確認を求めてください。
よくある質問
membersは省略できますか?
はい、APIでは任意です。ただし、これはリクエスト構造の定義であり、すべての上流アカウントの挙動を保証するものではありません。実際の結果を確認してください。
HTTP成功なら全員が参加していますか?
いいえ。返されるのはグループIDで、各メンバーの結果ではありません。メンバーを別途取得してください。
作成時に説明や画像も送れますか?
作成フィールドとしては記載されていません。作成後、別のグループ情報編集フローを使います。
次のステップと出典
グループ作成リファレンスに沿って実装してください。管理下のアカウントで、二重クリック、レスポンス紛失、同名グループ、メンバー一覧のページング、参加できないユーザーをテストします。これらは推奨テストであり、実施済みの結果ではありません。
確認日:2026-10-24。
メッセージ連携を安定したプロダクトパイプラインへ。
まずは 1 つの API で送信を始め、標準イベントですべての inbound メッセージを業務システムへ戻しましょう。