UIがチャットスレッドであるプロダクトを作る
LIFFトークン検証、Flex Messageカルーセル、リッチメニュー、ルーティングとしてのチャットボットフロー——バックエンドの規律としてのチャットプラットフォームエンジニアリング。
私が参加した中で一番奇妙なデザインレビューには、画面が1枚もありませんでした。議論されている「UI」はチャットスレッドです:リッチメニュー、ひと握りのメッセージテンプレート、会話の中で開くミニアプリのパネル。私はLINEの中で完結する物件探しプロダクトのバックエンドを作りました——ユーザーは物件を発見し、お気に入りに保存し、内見を予約する。アプリのインストールも、通常の意味でブラウザのタブを開くこともなしに。この仕事は私に、チャットプラットフォームのエンジニアリングとは「フロントエンドの衣装を着たバックエンドの規律」だと確信させました。
プラットフォームがあなたのフロントエンド——ただし先方の条件で
プロダクトの表面は3つのプリミティブに分解でき、それぞれにバックエンド側の帰結があります:
- リッチメニュー——会話の下に固定されたタップ領域のグリッド——がナビゲーションバーでした。各項目はチャットボットフローかミニアプリのビューへのディープリンクです。ここでのナビゲーション設計はコードではなく設定ですが、すべての行き先を定義するのはバックエンドです。
- チャットボットフローは素早いやり取りを担います:キーワードでルーティングされるメッセージが入り、テンプレートの応答が出る。各フローは小さなステートマシンを背負ったルートだと考えてください。
- LIFFミニアプリ(プラットフォームの埋め込みWebビュー)がフォーム的なものすべてを運びます——検索フィルタ、比較、予約カレンダー。バックエンドから見ればこれらは普通のWebクライアントです:私たちのサービスは60近いRESTエンドポイントを公開し、ミニアプリはSPAと同じようにそれを消費しました。
エンジニアリング上の洞察は、この3つが1つのバックエンドのアイデンティティモデルを共有することです。本当の仕事はそこから始まります。
アイデンティティ:信頼するな、検証せよ
ミニアプリはプラットフォーム発行のトークンを携えてやって来ます。誘惑は、そこからユーザーIDを読んで先へ進むことです。これを安全に保ったルール:
- トークンは毎回サーバーサイドで検証する。 私たちはクライアントのトークンをプラットフォームの検証エンドポイントに渡し、検証済みプロファイルからユーザーを解決しました——プラットフォームの公開鍵に対してローカルで署名検証するのがもう1つの正当な経路です。どちらにせよ、クライアントSDKの主張は利便であって、権威ではありません。
- プラットフォームのアイデンティティを自前のユーザーレコードにマッピングする。 初回接触時に作成します。システムの残りを流れるのはプラットフォームのIDではなく内部IDです——これが後に、チャットボット・ミニアプリ・外部の物件管理システムをまたいだユーザーの突合を、プラットフォームIDをテーブル中に漏らさずに可能にしました。
- Webhookイベントにも同じ猜疑心を。 すべての受信イベントで署名を検証し、ハンドラーは安全に再実行できるように書く。プラットフォームは再配送しうるからです。
どれもエキゾチックなOAuthではありません——しかしチャットプラットフォームは3つの入口面(Webhook、ミニアプリ、ボットAPI)を渡してきます。規律とは、それを3本のアイデンティティ経路ではなく、1本に収斂させることです。
Flex Message:サーバーサイドレンダリング、JSON版
レコメンドと検索結果はFlex Messageカルーセル——スレッド内でネイティブに描画されるスワイプ可能なカードの束——として出ていきました。これをうまく作る感覚は、サーバーサイドレンダリングそのものです:
- ビューを構成するのはバックエンド。 カードはユーザーごとに組み立てられるJSONドキュメント(画像、タイトル、価格帯、アクションボタン)です。後からパッチできるクライアントコードは存在しません——送ったものが、そのスレッドの中で永遠に存在し続けます。
- すべてのボタンは意図を持つディープリンク。 カードのボタンは特定の物件のLIFFビューを開きます(ボット側のナビゲーションはキーワードマッチのメッセージに乗ります)。だからバックエンドは常にどのカードがタップを生んだかを知っている——分析の物語はメッセージに設計として組み込むか、さもなければ存在しません。
- テンプレートにはバージョニングの規律を。 フォーマットが進化しても古いメッセージは再描画されません。スレッドは、あなたが出荷したすべてのテンプレートバージョンの不変の歴史です。テンプレート構成は1つのモジュールに集約し、公開契約として扱いました。
不変性の点は強調に値します:Webアプリでは、UIを直せば全員に行き渡ります。チャットスレッドでは、直せるのは未来だけ。メッセージフォーマットのロールアウトには、通常ならデータベースマイグレーションに払う慎重さを充てました。
ロジックが実際に住んでいた場所
ミニアプリが薄いままでいられたのは、面白い問題——このユーザーは誰か、このカードには何を載せるべきか、このタップで何が起きるか——がすべてサーバーサイドの問いだったからです。この逆転が持ち帰るべき点です。このプラットフォームでは、バックエンドチームが実質的にユーザー体験を所有していました:レスポンスのレイテンシは「アプリが重い」と体感され、メッセージの構成がビジュアルデザインであり、Webhookの障害は真っ暗な店先でした。
チャットファーストのプロダクトを検討しているなら:プラットフォームの制約(テンプレートのサイズ上限、メッセージングのクォータ、Webhook配送の意味論)は早めに予算化し、アイデンティティ検証は初日から一元化し、すべてのメッセージテンプレートをバージョン付きのAPIレスポンスとして扱うこと。伝統的なフロントエンドの不在はUIの仕事を消しません——それをサービス層へ移すだけです。少なくともそこでは、テストが書けます。