broadcast-campaign について
broadcast-campaignは、バルクメールを含む複数宛先向けのZavuメッセージキャンペーンを構築するスキルです。キャンペーン作成、連絡先管理、審査と予約、進捗の監視、拒否への対応を扱います。
主な機能
- 01複数チャネルでの一斉配信作成
- 02変数付き連絡先の一括追加
- 03審査申請、予約、停止、キャンセル
- 04配信進捗と宛先ステータスの追跡
- 05コンテンツ審査の拒否と再試行への対応
活用シーン
- 01一括メールニュースレターの配信
- 02複数宛先SMSキャンペーンの予約
- 03配信状況と失敗した宛先の監視
- 04審査で拒否された一斉配信の修正
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ zavudev/ zavu-skills --skill broadcast-campaignインストール後、Claude Code で/broadcast-campaignを入力して読み込まれたか確認します。
詳細
ブロードキャストキャンペーン
使用する場面
キャンペーンで複数の宛先にメッセージを送信するコードを作成するときに、このスキルを使用します。大量メールも対象です。作成からモニタリングまで、ブロードキャストのライフサイクル全体を扱います。
ブロードキャストのライフサイクル
draft -> pending_review -> pending_admin_review -> approved -> sending -> completed
-> rejected -> (edit) -> pending_review (retry, max 3)
-> rejected -> escalated (manual review by Zavu team)
-> rejected_final
approved -> scheduled -> sending -> completed
sending -> paused (can resume)
draft | pending_review | pending_admin_review | approved
| rejected | escalated | scheduled | sending -> cancelled
(any) -> failed (permanent failure)
手順
1. ブロードキャストを作成する
const result = await zavu.broadcasts.create({
name: "Black Friday Sale",
channel: "sms", // smart | sms | sms_oneway | whatsapp | telegram | email
text: "Hi {{name}}, check out our Black Friday deals! Code: FRIDAY20",
});
const broadcastId = result.broadcast.id; // brd_xxx
Python:
result = zavu.broadcasts.create(
name="Black Friday Sale",
channel="sms",
text="Hi {{name}}, check out our Black Friday deals! Code: FRIDAY20",
)
broadcast_id = result.broadcast.id
Go:
result, err := client.Broadcasts.Create(context.TODO(), zavudev.BroadcastCreateParams{
Name: zavudev.String("Black Friday Sale"),
Channel: zavudev.String("sms"),
Text: zavudev.String("Hi {{name}}, check out our Black Friday deals! Code: FRIDAY20"),
})
broadcastID := result.Broadcast.ID
Ruby:
result = client.broadcasts.create(
name: "Black Friday Sale",
channel: "sms",
text: "Hi {{name}}, check out our Black Friday deals! Code: FRIDAY20",
)
broadcast_id = result.broadcast.id
PHP:
$result = $client->broadcasts->create([
'name' => 'Black Friday Sale',
'channel' => 'sms',
'text' => 'Hi {{name}}, check out our Black Friday deals! Code: FRIDAY20',
]);
$broadcastId = $result->broadcast->id;
チャネルのオプション
| チャネル | 説明 |
|---|---|
smart | 連絡先ごとにインテリジェントにルーティングします |
sms | すべての連絡先にSMSを送信します |
sms_oneway | 一方向SMS(返信なし)です。番号も認証情報も不要です |
whatsapp | WhatsApp(ウィンドウ対象外の連絡先にはテンプレートが必要です) |
telegram | Telegram。宛先には、すでにボットにメッセージを送った相手の数値のチャットID(838360395 または telegram:838360395)を指定します。ボットからチャットを開始することはできず、電話番号は拒否されます |
email | メール(emailSubject が必要です)。大量メールに推奨される方法です |
メッセージの種類
| 種類 | 説明 |
|---|---|
text | プレーンテキスト(デフォルト) |
image | 任意のキャプションを付けられる画像 |
video | 動画メッセージ |
audio | 音声メッセージ |
document | ドキュメントファイル |
template | WhatsApp の事前承認済みテンプレート |
メールのブロードキャスト(HTML本文を使用)
大量メールキャンペーンでは、HTML本文と channel: "email" を使用します。これは、Zavu 経由で一括メールを送信する推奨方法です。
メールのブロードキャストには有料プランが必要です。Free プランでは、送信またはスケジュール設定を行うと、code: "paid_plan_required" を伴う 402 が返されます(下書きは引き続き作成できます)。smart ブロードキャストは引き続き送信されますが、メールの宛先は errorCode: "PAID_PLAN_REQUIRED" で失敗します。POST /v1/messages によるトランザクションメールは、すべてのプランで利用できます。
const result = await zavu.broadcasts.create({
name: "Newsletter",
channel: "email",
emailSubject: "Special offer for {{name}}",
text: "Hi {{name}}, check out our latest sale!", // plain text fallback
emailHtmlBody: "<h1>Hi {{name}}!</h1><p>Check out our latest sale.</p>",
metadata: { campaign_id: "camp_123", region: "US" },
});
2. 連絡先を追加する(一括、1リクエストあたり最大1000件)
const result = await zavu.broadcasts.contacts.add({
broadcastId: broadcastId,
contacts: [
{ recipient: "+14155551234", templateVariables: { name: "John" } },
{ recipient: "+14155555678", templateVariables: { name: "Jane" } },
],
});
console.log(result.added, result.duplicates, result.invalid);
3. 送信する(コンテンツレビューが開始されます)
ブロードキャストの送信に、どのチャネルでもアカウント認証は必要ありません。本人確認とビジネス認証によって、1 日あたりの上限は引き上げられますが、どちらもブロードキャストの許可にはなりません。ブロードキャストの前に行われるのはコンテンツレビューであり、これを回避することはできません。
自動レビューの実行前に、ブロードキャスト自体のテキストが一度だけ確認されます。受信者ごとに確認されるわけではありません。拒否されたブロードキャストは rejected になり、フラグが付けられたブロードキャストは担当者の確認を待ちます。これは、レビューに合格するとすぐに送信されるメールの場合も同様です。
whatsapp のブロードキャストではレビューが省略されます。 テンプレートを使ってのみ作成でき、Meta はそのテンプレートを承認する際に、ビジネスとコンテンツを審査します。代わりに適用されるのは、テンプレートが承認済みであることです。未承認のテンプレートは 400 template_not_approved で拒否され、WhatsApp ではこれ以外のレビューが行われないため、これが唯一の関門となります。
その後、各受信者には通常のメッセージとして送信されるため、1 日あたりの上限と、+1 の SMS 送信先に対する 10DLC 要件は、受信者ごとに適用されます。
レビューの結果が承認(送信中、予約済み、または送信準備完了)または非承認となると、チームオーナーに、理由と次に行うことを記載したメールが届きます。作成後に送信者が削除されたブロードキャストは、残高を確保する前に 400 sender_not_found で拒否されます。別の送信者を指定して、新しいブロードキャストを作成してください。
// Send immediately
await zavu.broadcasts.send({ broadcastId });
// Or schedule
await zavu.broadcasts.send({
broadcastId,
scheduledAt: "2024-01-15T10:00:00Z",
});
下書きがそのまま送信されることはありません。次に何が起こるかはチャネルによって異なります。
| ブロードキャスト | この呼び出しで行われること |
|---|---|
| Meta 承認済みテンプレートを使った WhatsApp | レビューを省略し(Meta による審査済み)、送信を開始します |
| 自動レビューを行い、合格するとすぐに送信します | |
| SMS、Telegram、smart、その他すべて | 自動レビューの後、pending_admin_review となり、担当者が承認してから送信されます |
したがって、202 は「受け付け済み」を意味し、「送信中」ではありません。送信中だと決めつけず、ステータスをポーリングしてください。すぐに sending に移行するのは、WhatsApp テンプレートを使ったブロードキャストのみです。
すでに approved または scheduled になっているブロードキャストに対して send を呼び出すと、レビューを通過済みのため、そのまま送信または再予約されます。
残高が見積もりコストをまかなえない場合、send は最上位に共通のエラー形式 { code: "insufficient_balance", message, details: { totalBalance, reservedBalance, availableBalance } } を含む 402 を返します。同じオブジェクトは、古いインテグレーション向けに error の下にも繰り返し含まれます。
4. 進行状況を確認する
const progress = await zavu.broadcasts.progress({ broadcastId });
console.log(`${progress.percentComplete}% complete`);
console.log(`Delivered: ${progress.delivered}, Failed: ${progress.failed}, Skipped: ${progress.skipped}`);
console.log(`Estimated completion: ${progress.estimatedCompletionAt}`);
連絡先ごとのステータス:
pending、queued、sending:まだプロバイダーに渡されていません。sent:プロバイダーがメッセージを受け付けました。配信はまだ確認されていません。チャネルから報告があると、受信者はdeliveredまたはfailedに移行します。配信を報告しないチャネルでは、受信者はsentのままになります。delivered:チャネルがデバイスへの配信を確認しました(WhatsApp の開封確認も含みます)。failed:配信されませんでした。プロバイダーから遅れて失敗の報告が届いた場合、受信者はsentまたはdeliveredからfailedに移行することがあります。skipped:受信者がそのチャネルの受信をオプトアウトしたか、ブロードキャストが受信者に届く前にキャンセルされたため、送信されませんでした。
進行状況のレスポンスとブロードキャストでは、sent 件数は sent と sentCount として示されます。また、sent は GET /v1/broadcasts/{broadcastId}/contacts の有効な status フィルターです。SDK ではまだ型が定義されていないため、REST レスポンスから読み取ってください。
curl -s https://api.zavu.dev/v1/broadcasts/$BROADCAST_ID/progress \
-H "Authorization: Bearer $ZAVU_API_KEY"
# { "total": 500, "sent": 120, "delivered": 360, "failed": 20, ... }
完了数では sent も完了として数えられるため、completed のブロードキャストでも、配信確認を待っている受信者がいる場合があります。
5. 拒否に対処する(コンテンツレビューに不合格となった場合)
// Check remaining review attempts
const broadcast = await zavu.broadcasts.get({ broadcastId });
console.log(`Review attempts: ${broadcast.reviewAttempts}/3`);
// Edit content
await zavu.broadcasts.update({
broadcastId,
text: "Updated message content with {{name}}",
});
// Retry review (max 3 attempts)
await zavu.broadcasts.retryReview({ broadcastId });
// Or escalate to manual review
await zavu.broadcasts.escalate({ broadcastId });
その他の操作
// Reschedule
await zavu.broadcasts.reschedule({
broadcastId, scheduledAt: "2024-01-16T14:00:00Z",
});
// Cancel (pending contacts skipped, queued may still deliver). Allowed from
// draft, pending_review, pending_admin_review, approved, rejected, escalated,
// scheduled and sending; not from paused or a finished status. Any reserved
// balance is released.
await zavu.broadcasts.cancel({ broadcastId });
// List contacts in broadcast
const contacts = await zavu.broadcasts.contacts.list({
broadcastId, status: "delivered", limit: 100,
});
// Delete (draft only)
await zavu.broadcasts.delete({ broadcastId });
テンプレート変数
ブロードキャストのテキストには {{variable_name}} を使用します。連絡先ごとに上書きするには templateVariables を使用します。
await zavu.broadcasts.contacts.add({
broadcastId,
contacts: [
{ recipient: "+14155551234", templateVariables: { name: "John", order_id: "ORD-001" } },
],
});
制約
addリクエストあたりの連絡先は最大1000件です(それ以上の場合は分割してください)。- どのチャネルでも、送信にアカウント認証は必要ありません。ブロードキャストを制限するのは、以下のコンテンツレビューです。下書きには何も必要ありません。
- メールのブロードキャストには有料プランが必要です。Freeでは、送信時に
402 paid_plan_requiredが返されます。 - 受信者1人につき、チャネルの日次上限に1件としてカウントされます(
send-messageスキルを参照)。上限に達すると、残りの受信者はerrorCode: "DAILY_LIMIT_EXCEEDED"でfailedとしてマークされ、翌日に再試行されることはありません。 - Meta承認済みテンプレートを使うWhatsAppを除き、送信前にコンテンツレビューが行われます。
- 自動審査の後、ほとんどのチャネルでは人による審査(
pending_admin_review)も行われます。メールは例外で、レビューで人による確認が求められない限り、そのまま送信されます。 - 送信時に残高が(推定コスト分)確保されます。
- レビューの再試行は最大3回で、その後エスカレーションされます。
draftステータスのブロードキャストのみ更新・削除できます。- キャンセルしても、キューに追加済みのメッセージは停止しません。