Node.js で WhatsApp を送受信する
受信は、Meta の認証 GET に応答し、POST を受け付けるルートです。送信は、電話番号の phone number id とトークンを使い、Cloud API へ fetch リクエストを送ります。こちらの SDK はなく、インストールも不要です。
Node でメッセージを受信するには?
Express、Fastify、Next のルートハンドラー、またはプレーンなサーバーで、2 つのメソッドを持つ 1 つのルートを使います。
GET では Meta の認証に応答します。クエリから hub.mode、hub.verify_token、hub.challenge を読み取り、トークンを自分のものと比較して、challenge をプレーンテキストで返します。JSON で返すのは典型的なミスです。見た目は正しくても、エンドポイントが何も受信しなくなります。
POST ではイベントを受信します。すぐに 200 を返し、その後で処理してください。Meta は遅いリクエストを再試行するため、応答前に処理すると同じメッセージを複数回受け取ります。特にサーバーレスでは、先に返してからキューに処理を追加することで、コールドスタートによる重複を防げます。
送信するには?
電話番号の messages エンドポイントへ、トークンを bearer ヘッダーに設定して fetch します。
こちら固有の処理はないため、リクエストは Meta の公式ドキュメントと完全に一致し、覚えるラッパーや依存する仕組みもありません。2 つの値はダッシュボードにあり、アシスタントが接続を設定する場合は MCP コネクターの get_api_credentials から取得できます。
本文は送信時点によって変わります。顧客の最後の受信メッセージから 24 時間以内なら、text オブジェクトを送ります。時間外は、承認済みのテンプレート名と言語を指定した template オブジェクトを送ります。text だけを送るコードはすべてのテストに通っても、夜間に届いた最初のメッセージで失敗します。
サーバーレスでは何が違いますか?
違いは 2 つあり、どちらも処理が終わる前に関数が終了することに関係します。
200 を返してから処理を続けても、応答した瞬間に停止する関数では動きません。プラットフォームが提供する、応答後も処理を継続する仕組みを使うか、ペイロードをキューに送り、別の関数で処理してください。Meta に必要なのは迅速な確認応答であり、処理の完了ではありません。
コールドスタートによって応答が遅くなり、再試行や重複が増えることもあります。この構成では、wamid メッセージ ID による重複排除は任意ではなく、信頼性を確保するために必要です。
よくある間違い
- challenge を生の本文ではなく JSON として返す
- 200 を返す前に処理する。サーバーレスでは、応答した瞬間に関数が停止することがあります
- 重複排除を省く。Meta は仕様として再試行するため、重複は例外ではなく通常発生します
easycoexistence.com で番号を接続し、Webhook の送信先をルートに設定して、ダッシュボードから phone number id とトークンを確認します。番号 1 件あたり月額 US$ 9 から、利用量に応じて US$ 2 まで。最初の 7 日間は無料です。
よくある質問
ライブラリは必要ですか?
いいえ。ルートと fetch だけで十分で、呼び出しは Meta のドキュメントと完全に一致します。
Vercel や Lambda で動きますか?
はい。ただし通常のサーバーレスの注意点があります。先に確認応答を返し、その後はインライン処理ではなく、キューやバックグラウンドの仕組みで処理してください。
リクエストが Meta から来たことを確認するには?
署名ヘッダーをアプリシークレットと照合します。エンドポイントを公開したら、すぐに実装する価値があります。
TypeScript は使えますか?
はい。ペイロードは Meta のもので、Meta がドキュメント化しているため、こちらで型を定義する必要はありません。
続きを読む
始める準備はできましたか?
WhatsApp Coexistence の設定は数分で完了し、数か月もかかりません。スマートフォン上のアプリも引き続き使えます。
無料トライアルを始める確認日