toC LINE ポータル — LINE ログイン × Firebase Auth で「回答する人」を「戻ってくる人」に
開始位置は 3 パターン
| 開始位置 | 最初の画面 | LINE ログインの区間 | その後 |
|---|---|---|---|
| ① LINE アプリから | A01 トークのリッチメッセージ / L01 リッチメニュー | LIFF 内なので A03 同意 (初回のみ) だけ | LIFF 枠のまま |
| ② ToC アンケート画面 × LINE アプリあり | W01 展示台 QR → A02 (ブラウザ) | W03 OS の「LINE で開く」確認 → A03 (LINE アプリ内) → ブラウザに自動で戻る | ブラウザ枠。EC の使用感アンケートは Push から LINE 内で開く |
| ③ ToC アンケート画面 × LINE アプリなし | W01 → A02 (ブラウザ) | W05 LINE のブラウザログイン → W06 メール → A03 (ブラウザ)。アカウントが無い人は匿名 (B) が受け皿 | ブラウザ枠。Push が届かないので W09 ポータルのお知らせで案内 |
🔺 As-Is / ✅ To-Be
同じ骨格 (入口 → 本人識別 → 属性 → 回答保存 → リワード → 再訪・回遊 → 削除) を左右に並べた。点線は「仕組みが無い」。
決めたこと (設計判断)
- 匿名回答は残す。LINE は「主ボタン」として並べる — 回答前に登録の壁を作らない。匿名で答えた人には完了画面で初めて連携を誘い、回答を引き継いでチケットを渡す (B02→B03)。
- LINE ログインは LIFF の ID トークン → API で検証 → Firebase カスタムトークン — Workers 上で LINE の verify エンドポイントを叩き、uid=
line:<sub>のカスタムトークンを WebCrypto で署名して返す。Identity Platform (OIDC プロバイダ) へのアップグレードは不要。既存のbetalabo-channel-oauth-identity-linking-asis-tobe.htmlの「LINE のみ」スコープと同じ方式。 - 匿名回答の引き継ぎはサーバ側で付け替える — Firebase の
linkWithCredentialはカスタムトークンと結合できないため、匿名 uid の Firebase ID トークンを一緒に送り、API がその uid の回答を consumer_user に付け替える (冪等・他人の回答は奪わない)。 - 属性は連携直後に 3 タップで 1 回だけ (年代・性別・エリア)。以後の回答には自動で添付し、設問から属性質問を外せるようにする。
- 友だち追加は LINE の許可画面で同時に (bot_prompt=aggressive) — 製品アンケートの案内 (E04) やチケット控えを Push で送るため。Messaging API チャネルは LINE Login と同一プロバイダーに作る (userId と sub を一致させる)。
- EC は外部 (各ブランドの公式 EC) — BetaLab は決済しない。紹介コード付きリンク → 注文 webhook で購入確認 → 購入者限定アンケートを解放 (
betalabo-ec-referral-attribution-asis-tobe.htmlの方式)。 - カフェチケットは 1 回答 = 1 枚 (冪等キー = response_id)。QR は「使う」を押してから出す。押した瞬間にチケットを提示中にロックし、1 回限りのトークンを発行。店舗が読み取ったら、お客さまが「表示をやめる」を押していても消込が優先される (下の「チケット消込の設計」)。
- 開始位置は 3 パターン (LINE アプリ / アンケート画面 × LINE アプリ有無)。違うのはログインの区間だけで、以降の画面は共通 (ブラウザでは枠だけ変わる)。
- LINE グリーン (#06C755) は LINE の操作にだけ使う。それ以外は shadcn zinc の primary / outline / ghost。
LINE ワンタップ登録のシーケンス
チケット消込の設計 (ロック・冪等)
状態
| 状態 | 入る条件 | 出る条件 |
|---|---|---|
issued | 回答保存と同時に発行 (response_id で 1 枚) | お客さまが「使う」→ presenting |
presenting 🔒 | POST /tickets/:id/present。署名付き 1 回限りトークン (nonce, exp=10 分) を発行。他の端末からは使えない | 店舗が読み取り → used / 期限切れ → issued に戻る |
used | POST /store/redeem {token} が CAS で成功 | (終端) 取り消しは管理画面から監査ログ付き |
expired | チケット自体の有効期限切れ | (終端) |
競合と失敗の扱い
| ケース | 結果 |
|---|---|
| 読み取られた直後にお客さまが「表示をやめる」 | 消込が勝つ。cancel は「QR を隠す」だけで、トークンは期限まで有効。画面は待ち受けを続け、確定したら使用済みに切り替える |
| 同じ QR を 2 回読んだ / 通信リトライ | 2 回目も同じ成功結果を返す (nonce 単位で冪等)。チケットは 1 回だけ消える |
| 「使う」を 2 回押した / 2 台で開いた | 有効なトークンがあれば同じトークンを返す (チケット単位のロック)。並行して 2 つのトークンは作らない |
| 店舗端末がオフライン | 署名と期限は端末で検証して「使用できます」を出し、読み取り時刻つきで保留 → 復帰時に送る。期限内に読んだものは有効 |
| 10 分間読み取られなかった | presenting → issued に戻る。もう一度「使う」で新しいトークン |
| スクショの使い回し | トークンは 1 回限り・10 分で失効。時計が秒で動くので店員が目視でも見分けられる |
整備するユーザーデータ
画面サムネイル
実装面の課題 (整理)
| 領域 | 課題 | 方針 / 担当 issue |
|---|---|---|
| 認証 | custom トークンで role クレームが欠けると既存判定に落ちて product_owner になりうる (レビュー M1) | custom / line: は role を anonymous に固定。#259 で修正 |
| 退会 | D1 を消しても Firebase Auth の line:<sub> ユーザーが残る (レビュー M2) | Identity Toolkit accounts:delete を呼ぶ。#259 で修正 |
| LIFF | LIFF の Endpoint URL は 1 つ。PR ごとに変わる preview の URL では LIFF が開けない | 本番 / 検証で LINE Login チャネルと LIFF を分け、検証用は固定の preview スロットに向ける (#260) |
| LINE ログイン | ID トークンを nonce なしで検証 (同じチャネルのトークンなら期限までリプレイできる)・/auth/line にレート制限が無い | LIFF 方式では一般的なので許容。レート制限は公開台帳に記録済み、別途追加 |
| 匿名の引き継ぎ | 他人の匿名 ID トークン (1 時間) を得た人は未所有回答を付け替えられる | 引き継ぎを auth_time が新しいトークンに限る (#259 の残課題) |
| アプリなし | LINE アカウントが無い人はログインできない / Push が届かない | 匿名 (B) を受け皿に。案内はポータルのお知らせ (W09)。#261 / #264 |
| チケット | 提示中のロック・消込の CAS・オフライン読み取り・店舗スタッフの認証 (誰が読んだか) | 上の「チケット消込の設計」。店舗スタッフは admin の店舗ロールで発行 (#262) |
| Push | Messaging API の無料枠は月 200 通 (日本・コミュニケーションプラン) | 送信数の上限と計測。プラン選定は事業判断 (#264) |
| 製品データ | 写真はスクショからの切り出し (444px)。価格・提携カフェが未確定 | 実装では R2 の原本 (product_assets) を使う。価格は各 EC で表示 (#263) |
実装状況と issue
| issue | 内容 | 画面 | 状態 |
|---|---|---|---|
| #258 | [Epic] toC LINE ポータル | 全 22 | — |
| #260 | 人手設定: LINE Developers / Firebase の発行と環境変数投入 | — | 人の作業待ち |
| #259 | LINE ワンタップ登録 × Firebase Auth (匿名回答の引き継ぎ・開始位置 3 パターン) | W01–W06, A02–A07, B01–B03 | 実装済み (PR #265) |
| #261 | ポータル シェル + 入口 (ホーム・アンケート一覧・マイページ・連携解除・リッチメニュー・再訪) | P01, P02, M01, L01, W08, W09 | 未着手 |
| #262 | リワード: カフェチケット発行・一覧・提示ロック・店舗消込 | A07, E06, R01–R05 | 未着手 |
| #263 | EC 回遊: ショップ・紹介リンク・購入確認 | E01–E03 | 未着手 |
| #264 | 製品アンケート: LINE Push 案内 + 購入者限定 | E04–E06 | 未着手 |