# LINE LIFF App 設定流程（Step by Step）

本文件供營運／工程在 **LINE Developers Console** 為單一商家建立或重建 LIFF App。  
架構說明見：[line-liff-integration.md](./line-liff-integration.md)

---

## 0. 開始前準備

先備齊下列資訊，再進 Console：

| 項目 | 從哪裡取得 | 範例 |
|------|------------|------|
| LINE Provider | Console 固定選 **iPetBooking** | `iPetBooking` |
| 商家 `alias` | 後台／DB `merchants.alias` | `daydreamlab` |
| 站台根網域 | 主專案 env `DINGSOMETHING_DOMAIN` | `ipetbooking.com` |
| 商家前台根網址 | `https://{alias}.{domain}` | `https://daydreamlab.ipetbooking.com` |
| 登入後要去的頁 | 自行決定（建議會員中心或首頁） | `https://daydreamlab.ipetbooking.com/member` |

確認：

- [ ] 該商家前台用瀏覽器可正常開啟（非 LIFF）
- [ ] 已有（或即將建立）**LINE Login channel**（不是 Messaging API channel）
- [ ] 若是**重建** LIFF：盡量掛在**原本同一個 Login channel**（會員綁定才不會斷）

---

## 1. 登入 LINE Developers

1. 開啟 [LINE Developers Console](https://developers.line.biz/console/)
2. 選擇 Provider：**iPetBooking**（本專案正式使用的 Provider；勿建到其他 Provider）
3. 若尚無 Login channel → 進入 **步驟 2**  
   若已有 → 進入 **步驟 3**

> 新商家／新 LIFF 一律掛在 **iPetBooking** 這個 Provider 底下，方便統一管理 Login channel 與 LIFF App。

---

## 2. 建立 LINE Login Channel（首次才需要）

1. Provider 頁面 → **Create a new channel**
2. 選擇 **LINE Login**
3. 填寫 Channel 基本資料（名稱之後可改）
4. 建立完成後進入該 channel

> **注意：** LIFF 必須掛在 **LINE Login** channel。  
> 商家後台的 Bot（`line_channel_*`）是 Messaging API，**另一條線**，不要把 LIFF 建在 Bot channel 上。

### Channel name 可以改嗎？

可以。進 channel 基本設定即可改顯示名稱；**Channel ID 不可改**。改名稱不影響登入。

---

## 3. 新增 LIFF App

1. 進入該 **LINE Login channel**
2. 上方分頁點 **LIFF**
3. 點 **Add**（新增）

---

## 4. 填寫 LIFF 設定（建議值）

依畫面欄位填：

### 4.1 LIFF app name

- 建議：`{商家名}-會員站` 或清楚可辨識的名稱
- 勿含不當字串；之後可改
- **LIFF ID 建立後不可改**（名稱可改）

### 4.2 Size

- 建議選 **Full**

### 4.3 Endpoint URL（最重要）

本專案前台路由為 `/liff/:liffId`，且 login 成功後**必須**靠 query `redirectTo` 轉頁（**必填**）。

**最終正確格式：**

```
https://{alias}.{domain}/liff/{liffId}?redirectTo=https://{alias}.{domain}/member
```

**範例：**

```
https://daydreamlab.ipetbooking.com/liff/1234567890-AbCdEfGh?redirectTo=https://daydreamlab.ipetbooking.com/member
```

| 規則 | 說明 |
|------|------|
| 必須 https | Console 不接受 http |
| path 含真實 `liffId` | 不可寫字面 `:liffId` |
| **必填** `redirectTo` | **完整 https 絕對網址**；缺參數時 login 成功後畫面會停在空白、看起來「沒反應」 |
| `redirectTo` 目的地 | 通常 `/member` 或商家首頁 |

**實務兩段式填寫（建立當下還沒有 liffId）：**

1. 第一次建立：Endpoint 可先填商家根網址，例如  
   `https://daydreamlab.ipetbooking.com/`
2. 按 Add／儲存後取得 **LIFF ID**
3. 立刻回到編輯，把 Endpoint 改成完整：  
   `https://{alias}.{domain}/liff/{剛拿到的 liffId}?redirectTo=https://{alias}.{domain}/member`
4. 儲存

### 4.4 Scopes

| Scope | 勾選 |
|-------|------|
| `profile` | **勾** |
| `openid` | 不勾 |
| `email` | 不勾 |
| `chat_message.write` | 不勾 |

### 4.5 Add friend option（加好友選項）

| 選項 | 建議 |
|------|------|
| **Off（none）** | **建議** — 本專案 LIFF 只做登入，不加好友依賴 |
| Normal | 授權後詢問加官方帳號 |
| On（aggressive） | 授權前強推加好友 |

站內加好友走 `lineFriendUrl`，與這個開關無關。

### 4.6 Scan QR

| 選項 | 勾選 |
|------|------|
| Scan QR | **不勾** |

用途：開啟後可在 LIFF 內呼叫掃碼 API（`liff.scanCode`／`scanCodeV2`），讓網頁在 LINE 裡掃描 QR Code。  
本專案登入流未使用此功能，故不勾。

### 4.7 其他

- 若有 **Module mode** 等進階選項：本專案一般登入流**不需要**特別開
- 其餘維持預設即可

---

## 5. 儲存並記下結果

建立／更新成功後，畫面上會有：

| 項目 | 範例 | 用途 |
|------|------|------|
| **LIFF ID** | `1234567890-AbCdEfGh` | Endpoint path、`liff.init` |
| **LIFF URL** | `https://liff.line.me/1234567890-AbCdEfGh` | 給使用者點的入口（選單／訊息／QR） |

請再次確認 Endpoint 已是：

```
https://{alias}.{domain}/liff/{LIFF_ID}?redirectTo=https://{alias}.{domain}/member
```

---

## 6. 設定使用者入口（必做）

本系統**不會**自動產生 LIFF QR，也不會把連結寫進官方帳號。請自行擇一：

1. **官方帳號 Rich Menu** → 連結填 **LIFF URL**（`https://liff.line.me/{liffId}`）或完整 Endpoint
2. **推播／圖文訊息** 放 LIFF URL
3. 自行把 LIFF URL 做成 QR 給人掃

> 站內「加好友 QR」（`lineFriendUrl`）**不是** LIFF 登入入口。

---

## 7. 實機驗證清單

用 **LINE App 內**開啟入口（不要只用桌面瀏覽器當唯一測試）：

### 7.1 已綁定會員

- [ ] 可開啟 LIFF、`liff.init` 無錯
- [ ] 會打 login API 成功
- [ ] 會導向 `redirectTo` 指定頁（例如 `/member`）
- [ ] 站內已是登入狀態

### 7.2 未綁定會員（新 LINE 帳號或未 bind）

- [ ] login 回「找不到會員」後導向 `/login?liffUserId=...`
- [ ] 手機驗證碼登入成功
- [ ] 自動 bind 後再 login
- [ ] 之後再用同一 LIFF 可直接登入

### 7.3 常見「login 成功沒反應」

| 原因 | 處理 |
|------|------|
| Endpoint **沒有** `?redirectTo=完整網址` | 補上並儲存 |
| `redirectTo` 不是絕對 https URL | 改成 `https://...` |
| Endpoint 的 liffId 與 Console 不一致 | path 改成正確 LIFF ID |
| 開在外部瀏覽器且未完成 LINE login | 用 LINE 內開啟，或完成 `liff.login` 導回 |

---

## 8. 特殊情境

### 8.1 同一個 Login channel 再建第 2 支 LIFF

- **可以**，一般沒問題
- 同一 Login 下，同一使用者的 **userId 相同** → 綁過一次，兩支都能登入
- 每支 Endpoint 的 path 必須用**自己的** liffId
- 對外入口要分清楚連到哪一支

### 8.2 放棄舊 LIFF、重建新 LIFF（同一商家 alias）

| 做法 | 結果 |
|------|------|
| **只重建 LIFF，Login channel 不變** | **建議**。既有 `lines.lineId` 綁定仍有效 |
| Login channel 也重建 | **危險**。userId 可能變，舊綁定失效，會員需重綁 |

步驟建議：

1. 在**同一個** Login channel 新增新 LIFF（照本文件步驟 3～5）
2. Endpoint 指到**同一**商家 alias
3. 更新 Rich Menu／訊息／QR 到**新** LIFF URL
4. 實機測過後，再刪除或停用舊 LIFF

### 8.3 本專案後台／env 要填什麼？

**不用。**  
沒有商家級 LIFF 欄位、沒有 `LIFF_*` env。設定只在 LINE Console + 對外連結。

---

## 9. 一頁速查（建議設定）

| 欄位 | 建議值 |
|------|--------|
| Provider | **iPetBooking** |
| Channel 類型 | LINE Login |
| Size | Full |
| Endpoint | `https://{alias}.{domain}/liff/{liffId}?redirectTo=https://{alias}.{domain}/member` |
| Scope | `profile` 勾；其餘不勾 |
| Add friend | Off |
| Scan QR | **不勾**（用途：LIFF 內掃碼；本專案未用） |
| 入口 | Rich Menu／訊息用 `https://liff.line.me/{liffId}` |

---

## 10. 完成定義

同時滿足才算上線完成：

1. Console Endpoint 已含正確 `/liff/{liffId}` 與 `redirectTo`
2. 官方帳號或對外素材已指向新 LIFF URL
3. LINE 內實測：已綁定可進站；未綁定可完成綁定後登入

---

## 相關文件

- [LINE LIFF 申請與串接架構](./line-liff-integration.md)
- [Adding a LIFF app（官方）](https://developers.line.biz/en/docs/liff/registering-liff-apps/)
- [LIFF 概覽（官方）](https://developers.line.biz/en/docs/liff/)
