migrate-to-sent について
migrate-to-sentは、主要なCPaaSプロバイダーからSentへの移行を計画する開発者向けスキルです。ルーティング、ステータス、Webhook検証、同意管理、テンプレート、テナント構成の変換と移行手順を扱います。
主な機能
- 01プロバイダーの挙動マッピング
- 02ルーティングとステータスの変換
- 03Webhook検証の再実装ガイド
- 04同意管理とテンプレート移行の指針
- 05移行調査と切り替え手順
活用シーン
- 01TwilioまたはSinchからの移行計画
- 02リポジトリ内の送信処理とハンドラーの特定
- 03ステータスとエラー処理の再構築
- 04段階的なプロバイダー切り替えの準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sentdm/ sent-plugin --skill migrate-to-sentインストール後、Claude Code で/migrate-to-sentを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/cutover-playbook.mdprovider-mapping.mdscripts/inventory_scan.py詳細
Sent への移行
主要な CPaaS プロバイダーから移行する際には、必ず同じ 5 つの翻訳上の問題に直面します。次の順序で対応してください。最初の問題は、コストを気付かないうちに倍増させ、テストでは検出できないためです。
1. 順序付きフォールバックは自動ルーティングに置き換える
既存プラットフォームでは、呼び出し元側のさまざまな配列、フェイルオーバーオブジェクト、メッセージングサービスの機能、またはアプリケーションレベルの優先順位設定によって、チャネルをまたいだ配信を表現します。こうした形式に直接対応する Sent のリクエストフィールドがあると考えてはいけません。
Sent の channel 配列はブロードキャストリストです。 順序付き配列を移植すると、受信者とチャネルの組み合わせごとに 1 通のメッセージと 1 回分の料金が発生します。テストには合格しても、本番環境の支出が増大します。正しくは自動ルーティングに置き換えます。channel を省略するか、["sent"] を送信してください。これにより、プラットフォームがルートを選択し、同じ message_id で最大 3 組のチャネルとプロバイダーをまたいで再ルーティングできます。詳細は sent-routing-strategist を参照してください。移行ルールは次のとおりです。順序付きチャネルリストは絶対に移植しないでください。
2. ステータスの語彙は一致しない
既存のステータスは Sent のステータスに対応付けられますが、Sent には同等のものがないステータスが 2 つ追加されており、単純なリトライロジックを破損させます。
| Sent のステータス | 最も近い既存プロバイダーの類似ステータス | 移行時の注意 |
|---|---|---|
QUEUED | Twilio queued、Sinch QUEUED_ON_CHANNEL | 受け付け済みですが、送信済みではありません |
ROUTED | 類似ステータスなし | ルートが選択されました。再ルーティング時にも再度発火します |
SENT | Twilio sent、Sinch MESSAGE_SUBMIT | プロバイダーへの引き渡しのみを示します |
DELIVERED | すべてのプロバイダーの delivered | 端末での受信を示す最初の証拠です |
READ | Twilio read、Sinch READ | WhatsApp と RCS のみ |
FAILED | failed、undelivered | 再ルーティングされる可能性があり、必ずしも最終状態ではありません |
FILTERED | Twilio エラー 21610(オプトアウト) | ポリシーゲートです。絶対にリトライしないでください |
BLOCKED | アカウントレベルのエラー | アカウントの前提条件です。アカウントを修正してから再送してください |
SCHEDULED | 類似ステータスなし | 静穏時間帯のために保留され、自動的に再開します |
移植したコードには 2 つの影響があります。配信完了以外のすべての最終状態をリトライ可能として扱うハンドラーは、同意に関するブロックをリトライします。これはバグではなく、コンプライアンス違反です。また、プロバイダーの数値エラーコード(代表例は Twilio の 21610)をキーにするハンドラーは、Sent の文字列 error.code ファミリーを基準に書き直す必要があります。
3. Webhook の検証は移植ではなく書き直しです
同じ方法で署名するプロバイダーは 2 つとなく、Sent SDK に検証機能は含まれていません。
| プロバイダー | 方式 |
|---|---|
| Twilio | X-Twilio-Signature。完全な URL とソート済み POST パラメーターを対象とする base64 HMAC-SHA1 |
| Sinch | body.nonce.timestamp を対象とする HMAC-SHA256、4 つの x-sinch-webhook-signature* ヘッダー、または OAuth 2.0 |
| Infobip | Basic、raw body を対象とする HMAC-SHA256、または通知プロファイルでの OAuth。ヘッダー名はアカウントごとに設定されます |
| Vonage | Authorization: Bearer 内の JWT、またはレガシーの sig パラメーター |
| MessageBird/Bird | messagebird-signature。タイムスタンプ、URL、SHA-256 のボディハッシュを対象とする base64 HMAC-SHA256 |
| Sent | x-webhook-signature: v1,{base64}。{x-webhook-id}.{x-webhook-timestamp}.{raw_body} を対象とする HMAC-SHA256 |
Sent のキーは、署名シークレットから whsec_ を取り除き、残りの部分を base64 デコードしたものです。比較には定時間比較を使用し、300 秒を超えるタイムスタンプは拒否します。Sent はイベントごとの ID を提供しないため、重複排除キーはペイロードの意味に基づいて導出する必要があります。既存プロバイダーの検証機能を改変するのではなく、sent-webhook-engineer を使って受信側を構築してください。
4. オプトアウトストアはコピーで移行せず、照合する必要があります
各プロバイダーは独自の配信停止リストを保持しています。Twilio Advanced Opt-Out、Infobip Blocklist、Sinch の OPT_IN/OPT_OUT イベントなどです。Sent はイベントがアプリケーションに届く前にプラットフォームレベルで同意を適用し、連絡先の opt_out として保存します。また、チャネルに依存せず適用するため、SMS での STOP は WhatsApp と RCS も抑止します。
照合ルール:切り替え前に既存プロバイダーの配信停止リストをエクスポートし、既存プロバイダーのいずれかのチャネルでオプトアウトされている場合は、Sent でも全体的なオプトアウトとして扱います。移行データを「クリーンアップ」するために opt_out を決してクリアしないでください。Sent のデフォルトキーワードは STOP、CANCEL、UNSUBSCRIBE、QUIT、END、START、UNSTOP、SUBSCRIBE、HELP、INFO の 10 個で、トリミング後の本文全体がキーワードと一致する場合にのみ照合されます。そのため、既存プロバイダー固有のキーワードにはカスタムキーワードエントリーが必要です。既存のキーワード照合処理は、厳密なローカル同意ミラーおよび監査メカニズムとして書き換えてください。この照合処理から Sent に同意を書き込んではいけません。同意のセマンティクスは sent-two-way-messaging に属します。
5. テンプレートとテナント設定は移管せず、再登録します
WhatsApp テンプレートは WABA に紐付いているため、移行では WABA を移動するかどうかを判断します。位置指定プレースホルダー({{1}}、{{2}})は Sent では名前付きパラメーターになるため、順序付き配列を渡していたすべての呼び出し元を、名前付きマップを渡すように変更する必要があります。承認は非同期で、templates ウェブフックイベントとして届くため、切り替え中ではなく、切り替え前にテンプレート一覧を作成してください。
テナント設定は以下のように対応付けます。境界の判断は sender-profile-architect が担当し、API 作業は sent-profile-provisioning が担当します。
| 既存プロバイダーの構成要素 | Sent の同等の構成要素 |
|---|---|
| Twilio subaccount | Sender Profile |
| Twilio Messaging Service | ルーティングとプロファイル設定。呼び出し元側のプールではありません |
| Infobip Application または Entity | Sender Profile |
| Sinch Conversation API app | Sender Profile |
| テナントごとのプロバイダー API 認証情報 | プロファイルスコープの API キー、または x-profile-id を使う組織キー |
移行手順
- 一覧化:すべての送信呼び出し元、ウェブフックハンドラー、ステータス分岐、テンプレート、配信停止リスト、認証情報を洗い出します。
scripts/inventory_scan.pyを使用すると、機械的に検出できます。このスクリプトは、選択したリポジトリ内のローカル通常ファイルを読み取り、シンボリックリンクと環境ファイルをスキップし、ソースの抜粋を表示せずに、パス、行番号、移行ガイダンスを報告します。ネットワークリクエストは行いません。 - references/provider-mapping.md を使って各項目を対応付け、順序付きフォールバック配列と数値のエラーコードには、必須の書き換えがあることを明記します。
- Sent を並行して立ち上げます:認証情報、環境ごとのウェブフック 1 つ、検証済み受信側、再登録して承認されたテンプレートを用意します。
"sandbox": trueを指定したサンドボックスで同等性を検証し、その後、DELIVEREDが確認された少数の本番コホートで検証します。- トラフィックを分割してデュアルランを行い、同じメッセージクラスで配信率、レイテンシー、メッセージあたりのコストを比較します。
- メッセージクラスごとに切り替えます。リスクの最も低いトランザクションメッセージから始め、マーケティングメッセージを最後にし、既存の受信側は稼働状態に保ちます。
- クリーンなデータで請求サイクルを一巡した後にのみ廃止し、その後、既存プロバイダーの認証情報を取り消します。
手順の詳細、検証ゲート、ロールバックのトリガーについては、references/cutover-playbook.md を参照してください。
テストをすり抜けるミス
- 順序付きチャネル配列をそのまま移植します。コストが2倍になるだけで、エラーにはなりません。
FILTEREDを再試行可能として扱います。コンプライアンス上のリスクが生じます。- 既存プロバイダーの署名検証器を再利用します。すべての配信が401を返します。
202は配信完了を意味すると考えます。Sentが確認するのは受け付けたことだけです。- テンプレートの位置指定プレースホルダーをそのまま使います。パラメーターが気づかれないまま不一致になります。
401で再試行します。認証に10回連続で失敗すると、ロックアウト時間が段階的に延長され、認証情報がロックされます。- 二重実行中に
Idempotency-Keyを省略します。タイムアウト後の再試行で2回送信されます。 - プロファイルスコープのキーで
x-profile-idを送信します。403が返されます。 - 既存プロバイダーの
Authorization: Bearer方式をそのままコピーします。Sentはx-api-keyで認証します。
対応範囲
このスキルでは、プロバイダーのマッピングと、行単位の移行計画を担当します。作成したSentクライアントとレジリエンス対応は sent-integration-starter に、チャネルのセマンティクスは sent-routing-strategist に、レシーバーの構築は sent-webhook-engineer に、WhatsAppのオンボーディングは waba-embedded-signup に、米国のキャンペーン登録は sms-10dlc-registration に引き継いでください。