通知 & CRM サービス
お知らせ、アプリ内受信箱、コールセンター CRM のバックエンド
プロジェクト背景
コールセンタースタッフは、最終コンタクト日時順に並んだ顧客リストに沿って対応する。リストを表示するたびに通話履歴を集計する方式はスケールせず、顧客データ自体は ID サービス側にある。
アーキテクチャ
管理画面 → ゲートウェイ(アウトリーチ API + プロバイダークライアント)→ アウトリーチ gRPC サービス → MySQL。ID サービスのイベント(登録、電話番号変更、ステータス変更)→ Kafka コンシューマー → 最新コンタクト行のトランザクショナルな更新。お知らせ:発行 → Kafka → WebSocket サービス → 接続中のクライアント。
主な技術ポイント
お知らせと受信箱を再構築:多言語コンテンツ、グループ単位の配信対象指定、ユーザーごとの既読状態と未読数、Kafka と WebSocket によるリアルタイム配信
顧客アウトリーチのバックエンドをゼロから構築:8テーブル(シート、通話・SMS 記録、設定)上の15の gRPC エンドポイント
23の管理用エンドポイントと、クラウド型コンタクトセンター兼 SMS プロバイダー向けの署名付き REST クライアント。シートグループの自動プロビジョニングに対応
Kafka のユーザーイベントから同期される「顧客ごとの最新コンタクト」リードモデル。リトライとデッドレタートピック、トランザクショナルな書き込み付き
リードモデルのオンラインバックフィル:一時インデックス作成 → INSERT … SELECT … ON DUPLICATE KEY UPDATE → インデックス削除
コア実装
イベント駆動のリードモデル
顧客ごとに1行で最新の通話と SMS を保持する。登録時に作成し、電話番号やステータスの変更時にリセットし、各通話記録と同じトランザクションで更新する。
Why: リスト画面は履歴を集計せず顧客ごとに1行を読むだけで済み、データは同期呼び出しなしで ID サービスに追従する。
プロバイダー連携
プロバイダー向けの汎用的な署名付き REST クライアントを用意し、プロバイダーのエラーコードをローカライズされたプラットフォームエラーにマッピングし、現在のシートグループが満杯になると新しいグループを自動で作成する。
Why: スタッフにベンダーの生のエラーを見せるべきではなく、新しいスタッフのオンボーディングにプロバイダー側の手動設定を必要とすべきでもない。
技術的意思決定
| 技術的意思決定 | 選択 | 代替案 | 理由 |
|---|---|---|---|
| 最新コンタクトのリスト | イベントで維持する非正規化リードモデル | クエリ時に通話履歴を集計 | 読み取りは通話よりはるかに頻繁で、リストには ID データにまたがるフィルターが必要。 |