Eagle AI × LINE 頻道 · 開發交接 · 2026-07-07
LINE 頻道全景:從選單到每一頁 LIFF
工地主任 × 監工 · 群組 × 1:1 · 截圖 + 流程圖 + 路由與 API 對照,全部與 line-worker/ 原始碼核實。
eagle-line.jaredsong.workers.dev · LIFF 2010491601-uK7jHMCT(Full)程式 = GitLab
JaredSong1/eagle-line(本機 eagle-ai-qms/line-worker/)· D1 eagle-line · R2 eagle-line-evidence · cron 每天 08:00。
截圖說明 — 全部是正式環境真實資料(remote D1:真實群組、真實請款單掃描、真實現場照片),身分 = 真實 userId。主任視角拍自 Testing 群組、監工視角拍自另一個真實專案群。手機 430×932、深色主題(淺色是同一套 token 自動切換,畫面右上有手動切換鈕)。
01系統全景圖
一個 Cloudflare Worker 做三件事:bot webhook(聊天訊息與卡片)、/api/*(資料)、靜態 LIFF(public/index.html,單頁 app)。LINE 上有三個場景,全部通到同一個 LIFF,用 URL 參數決定情境:
flowchart LR G["💬 群組聊天
bot 選單 + Flex 卡片
連結都帶 ?g=群組id"] L["🖥️ LIFF 工作台
指派·審核·日報·證據·總覽·我的工項"] P["👤 1:1 聊天
Rich Menu 底欄·跨專案·指揮中心"] G <--> L L <--> P
核心迴圈,五步:
flowchart LR A["1 · 上傳請款單"] --> B["2 · 畫框指派
框 + 監工 + 張數 + 截止"] B --> C["3 · 群組通知
你被指派 N 項"] C --> D["4 · 監工拍照
LIFF 或直接丟照片"] D --> E["5 · 主任審核
採認 / 退回"] E -->|退回| D E -->|採認| F(["完成"])
設計鎖定:沒有 OCR — 系統不讀掃描上的字。「框 + 人 + 張數」就是資料模型,照片證據掛在框上,任何格式的請款單都能用。標註後的掃描圖是指派 → 拍照 → 審核三步共享的物件。
02選單與 Rich Menu
群組選單 = bot 發的 imagemap 圖片(不是 Rich Menu)
LINE 的 Rich Menu 不會出現在群組,所以群組入口是一張 bot 發的橫幅圖片訊息(imagemap,menuImagemap())。bot 被加進群組時、或有人打喚起詞時發出(見第 3 章)。
| Tap zone(x 範圍,實測像素) | 標籤 | 動作 | 目的地 |
|---|---|---|---|
0–208 | 指派工項 | 開 LIFF | ?g=(主任 → 上傳/指派;監工 → 我的工項 + 提示) |
208–399 | 我的工項 | 開 LIFF | ?v=mine&g= |
399–589 | 出工日報 | 開 LIFF | ?v=daily&g= |
589–795 | 問 Eagle | 送文字「問 Eagle」 | bot 在聊天內回答,不開 LIFF |
802–1040 | eagle-ai logo | 無(純品牌) | — |
1:1 Rich Menu(在 OA Manager 手動設定)
歡迎訊息(兩種)
| 時機 | 內容(程式) |
|---|---|
| bot 進群(join 事件) | groupWelcome():「⚒️ Eagle AI 已加入這個工地群組!點下方選單開始,第一次會先請你選身分:🏗️ 工地主任(上傳請款單、指派工項、看出工日報與總覽)· 👷 監工(查看我的工項、拍照回報)。選單不見了?隨時打『選單』、『Eagle』或『AI』就能叫出來。」+ imagemap 選單 |
| 加好友(follow 事件,1:1) | welcomeText(暱稱):「👋 歡迎使用 Eagle AI!我是你的工地小幫手 ⚒️:📋 我的工項(你負責的工項、拍照回報)· 📷 我的照片(你上傳的證據)· 📊 我的儀表板(完成統計與排行)· 💬 問 Eagle(隨時問我)。點下方選單開始 👇」+ 問 Eagle 按鈕卡 |
03喚起詞完整對照 程式核對
「怎麼叫出選單 / Eagle / AI」在群組裡其實有 多層規則,不是單一關鍵字。以下逐條對照 src/index.js 與 src/parse.js 的實際判斷(這是最容易被文件寫漏的地方)。
六層規則
| 層級 | 觸發(實際 regex / 條件) | 結果 | 程式 |
|---|---|---|---|
| 選單關鍵字 | 選單 · 單獨 menu · 單獨 ai/選單|^\s*(?:menu|ai)\s*$/i | 發 imagemap 選單 | index.js(menuReq) |
| 打招呼 / 求助 | 問eagle · 單獨 hi/hello/help/start/menu · 你好 哈囉 嗨 幫助 怎麼用 可以問 功能 選項 開始 | 狀態列一句 + 問 Eagle 按鈕卡(askMenuFlex:什麼時候到期?/ 有沒有被退回?;管理者再加 待我採認 / 誰還沒交) | isGreeting() |
| @提及 OA | 群組訊息 tag 到本 OA(LINE 標記 isSelf) | 一定回應:純 tag → 按鈕卡;帶問題 → 回答 | mentioned |
| 智慧回答 wantsEagle() | 主題詞(進度/逾期/退回/採認/待採認/還沒交/請款/照片/幾項…)+疑問意圖(? /嗎 呢 幾 多少 有沒有 哪 什麼 何時…),或整句 ≤6 字。 語尾助詞的陳述句(…了/啦/喔)=閒聊 → 安靜 | 回答(文字或 Flex 卡) | parse.js EAGLE_TOPIC / QWORD / STMT |
| Fallback 關鍵字 | 句中任意位置含 menu · eagle · ai(字界)· 指派 · 工項 | 發選單 | index.js 尾段 |
| 提醒全部(主任限定) | 群組裡打 提醒全部 | @提及所有今明到期/逾期未回報的監工 + 1:1 推卡;非主任 → 「只有工地主任可以提醒全部」 | remindAllPending() |
groupWelcome() 的最後一句就是:「選單不見了?隨時打『選單』、『Eagle』或『AI』就能叫出來。」
所以正式對外的喚起詞是 選單 / Eagle / AI 三個 —— 文件若只寫「選單 / menu / ai」會漏掉 Eagle,也沒交代 @提及與智慧回答兩層。
群組收到一句文字,bot 怎麼判斷
webhook 依這個優先順序逐層判斷(第一個命中就回,後面不看):
flowchart TD
M["群組收到文字"] --> Q1{"選單關鍵字?
選單 · menu · ai"}
Q1 -->|是| MENU["發 imagemap 選單"]
Q1 -->|否| Q2{"主任打「提醒全部」?"}
Q2 -->|是| REMIND["@提及未交監工 + 1:1 推卡"]
Q2 -->|否| Q3{"@提及 OA,或 wantsEagle?"}
Q3 -->|"打招呼 / 純 @提及"| GREET["狀態列 + 問 Eagle 按鈕卡"]
Q3 -->|"真的問句"| ANS["回答(文字 / Flex 卡)"]
Q3 -->|否| Q4{"像出工日報?"}
Q4 -->|是| DAILY["整理成日報卡(確認 / 修改)"]
Q4 -->|否| Q5{"句中含
menu·eagle·ai·指派·工項?"}
Q5 -->|是| MENU2["發選單"]
Q5 -->|否| SILENT(["安靜 — 不打擾群組"])
為什麼要這麼多層:群組是工班聊天的地方,bot 不能話多。所以只有「明確喚起(選單/@提及)」或「明顯在問 Eagle(主題詞+問句)」才出聲;一般閒聊(「油漆好了啦」)保持安靜。分類器 wantsEagle() 有單元測試護著(parse.test.js 內 3 個 wantsEagle 案例)。
04加入與身分
- 身分是每群一份:同一人可以在 A 群當主任、B 群當監工(跨群雙身分在 1:1 有檢視切換,見第 8 章)。
- 第一次在某群開 LIFF → 角色選擇頁。一群只有一位工地主任(
/api/members伺服器端擋),被佔走會鎖卡並顯示「已由 X 擔任」。 - 加入或變更角色時,bot 在群組廣播:
「{名字} 加入工項 · 身分:工地主任 / 監工」。
?g=群組id;liff.getContext() 只做備援(從 imagemap / Flex 卡開啟時它不可靠 — 曾造成「角色存不住、不能指派」)。1:1 沒有 g → 進個人模式(solo-使用者id)。05工地主任(群組)
底部導覽五個 tab(NAV_SUPER):指派工項 · 審核 · 出工日報 · 證據 · 總覽。點左上 logo = 回角色首頁(主任 → 指派工項)。
指派:上傳 → 畫框 → 指派 → 通知
審核:採認 / 退回(逐樓層)
sequenceDiagram
participant C as 監工
participant G as 群組
participant S as 主任
participant L as LIFF 審核頁
C->>G: 拍滿張數
G-->>S: 完成卡「審核 ›」
S->>L: 深連 ?rev=請款單_框
S->>L: 逐樓層 採認 / 退回
L-->>G: 結果(採認✅ / 退回↩️@監工)
- 退回要填理由(quick-reply)→ 該樓層回到待處理;監工重拍新照片會自動清掉退回狀態。退回一定推播群組並 @提及監工。
- 採認單項時安靜(不洗版);某人整組工項全數採認才發「已採認 {名字} 的全部工項 ✅」。
出工日報:聊天自動解析 → LIFF 檢視與修改
flowchart LR T["群組貼派工訊息
(任意格式)"] --> P["bot 錨點解析
parseDailyLog()"] P --> K["「已整理」卡
樓層/區域 chips + 人數"] K -->|"確認(主任限定)"| C["✅ 已確認 → 進日報頁"] K -->|"修改"| E["LIFF 編輯器
?v=daily&edit=1"] E --> C C --> R["出工 vs 照片落差
→ 請工班補拍 推播"]
解析器(src/parse.js;parse.test.js 共 22 個案例涵蓋解析器與 wantsEagle)吃工地實際會貼的格式:
- 日期:民國(115.7.1)、西元、M.D 都認得;同日期重貼=覆蓋舊版並提醒重新確認。
- 樓層 / 位置:單層、範圍(23F 28F)、以上/以下;區域詞自動判別(車道、前中庭、北側… 台灣工地詞庫)→ 樓層綠 chip、區域中性 chip。
- 人數:前置或後置、含不含「人」都可;0 人照列不丟。
- 看不懂的行不會默默消失 → 卡上 ⚠ 未整理提示,編輯器裡可「加入」(轉成正式列)或「移除」。
證據 · 總覽 · 說明
06監工(群組)
底部導覽四個 tab(NAV_CREW):我的工項 · 我的照片 · 排行 · 問 Eagle。點 logo → 我的工項。
07聊天拍照回報(不開 LIFF 也能交)
監工不一定會開 LIFF 拍照 —— 直接把照片丟進群組(或 1:1)也算回報。Worker 收到照片 → 下載進 R2 → 進待歸檔佇列(pending_capture),約 2 秒 debounce 把一波連發照片收成一張卡(LINE 每張照片是獨立 webhook)。
flowchart LR P["照片進群組 / 1:1
每張是獨立 webhook"] --> C["2 秒收批
「這是哪一項?」卡"] C --> K["點一下歸檔
(cap: postback)"] K --> D{"拍滿張數?"} D -->|是| F["完成卡 → 審核流"] D -->|否| W["繼續等照片"] C -.->|"混批 / >13 張 / 1:1"| S["整理照片頁
?v=capture&b=批次"]
「這是哪一項?」卡(captureAskCard())回顯照片 + 該監工未完成的工項/樓層按鈕(標籤唯一:「工項N · 第M張 · 樓層」);主任會看到全工班的代傳選項(名字前綴)。沒待辦且不是主任 → bot 安靜(不打擾閒聊丟圖)。
| 情境規則 | 行為 |
|---|---|
| 同人約 2 分鐘內又丟照片 | 先確認再入帳:「延續上一項 — 這張也記到【工項N】嗎?」[是的][換一項·整理照片 ›][略過]。會寫資料的自動行為一律先確認(上次選擇存 capture_pick) |
| 點到舊卡片的按鈕 | 每波照片有 batch id,postback 全帶 batch、處理範圍鎖 WHERE batch=?。舊卡 → 「這批照片已處理」,不會誤刪 / 誤歸新照片 |
| 沒待辦且不是主任 | bot 保持安靜(不發卡) |
| 逾時 | 待歸檔托盤 15 分鐘過期;提問卡以約 15 秒連發窗口去重 |
081:1 個人(指揮中心)
模型:群組=工班佈告欄;主任的 1:1=指揮中心。1:1 導覽四個 tab(NAV_PERSONAL):儀表板 · 我的工項 · 我的照片 · 問 Eagle(Rich Menu 是入口,LIFF 底欄同構)。所有頁面跨專案彙整,多群以專案分組。
- 監工完成 → 「待你審核」卡,按鈕「前往待採認 ›」=跨專案佇列(不是單群審核頁)。監工沒加 OA 好友時退回發群組。
- 問 Eagle「誰還沒交」→ 還沒交卡上每個專案一顆「催 {專案} 工班 →」(nudge postback)→ 該群組收到「待回報提醒」卡。
?v=progress=我的進度純數字儀表板(完成率環 + 週/今日/逾期,沒有清單;showMine(false,true))。與 ?v=dash 相鄰但不同頁,Rich Menu 舊版曾指這裡。09聊天卡片總表
所有卡片共用一個殼(flexCard()):tone 色條頂欄 + 內文 + 綠色主 CTA(primaryBtn,次要動作灰色)。瀏覽器渲染不出 Flex — 改動要在手機上用「新觸發的訊息」驗(舊卡片永遠凍結在發送當下)。
四種代表卡片的長相(示意,非實際渲染 — 聊天卡片只在 LINE 對話裡呈現,無法截圖):
照片 2/2
| 卡片 / 訊息 | 色調 | 發到哪 | 什麼時候發 | 按鈕 → 落點 |
|---|---|---|---|---|
| 群組歡迎 + imagemap 選單 | — | 群組 | bot 被加入群組 | 四個 tap zone(見第 2 章) |
| 1:1 歡迎 + 問 Eagle 按鈕卡 | — | 1:1 | 加 OA 好友 | 常見問題按鈕(送文字) |
| 加入廣播「X 加入工項 · 身分:…」 | 文字 | 群組 | LIFF 選擇 / 變更角色 | — |
| 指派通知(每位監工:工項 N · 樓層 · 截止) | 綠 | 群組 | 主任送出指派 | 開啟我的工項 › ?v=mine&g= |
| 收到照片「這是哪一項?」 | 橘 | 群組 / 1:1 | 照片進聊天(2 秒收批) | 工項/樓層按鈕(cap:)· 從清單選工項 › ?v=capture&b= · 略過(capskip:) |
| 延續上一項?(連拍確認) | 橘 | 群組 / 1:1 | 同人 2 分鐘內再丟照片 | 是的 · 換一項·整理照片 › · 略過 |
| 工項完成 / 已回報 | 綠 | 群組 + 主任 1:1 副本 | 拍滿需要張數 | 群組卡:審核 › ?rev=;1:1 卡(kick「待你審核」):前往待採認 › ?tab=review |
| 採認 / 退回結果(退回附理由 + @提及監工) | 綠 / 紅 | 群組 | 主任在審核頁操作 | —(單項採認安靜;整組完成才發全部採認通知) |
| 出工日報「已整理」→ 確認後「✅ 已確認」版 | 中性 | 群組 | 群組貼派工文字(重貼=覆蓋 + 提醒) | 確認(dl_confirm:,主任限定)· 修改(?v=daily&edit=1) |
| 請工班補拍 | 橘 | 群組 | 主任在日報頁按「請工班補拍」 | 開啟我的工項 › |
| 每日提醒 digest「N 項今明到期/逾期」 | 橘 / 紅 | 群組 | 每天 08:00,有今明到期或逾期才發 | 🔔 提醒全部 ›(remindall:,主任限定)· 查看工項 › |
| 提醒全部(textV2 @提及未交監工 + 各自 1:1「🔔 主任提醒」卡) | 橘 / 紅 | 群組 + 監工 1:1 | digest 按鈕,或主任打「提醒全部」 | 1:1 卡:開啟我的工項 拍照回報 › |
| 待回報提醒(催工班) | 橘 | 指定群組 | 主任在 1:1 按「催 {專案} 工班 →」(nudge:) | 開啟我的工項 拍照回報 › |
| 問 Eagle 答案卡:待你採認 ⏳ / 還沒交 ❌ / 逾期·到期 🚨⏳ / 需要注意 👀 / 純文字 | 依內容 | 群組 / 1:1 | @提及、問句、智慧判斷(見第 3 章) | 逐項審核 › / 查看工項 › / 催工班 → |
| 問 Eagle 按鈕選單(綠 header) | — | 群組 / 1:1 | 打招呼、純 @提及、「問 Eagle」單詞 | 什麼時候到期? / 有沒有被退回?(管理者+待我採認 / 誰還沒交) |
| 異動通知:重新指派(工項 N 從舊→新)/ 刪除 / 截止日修改 | 精簡 | 群組 | 主任在 LIFF 操作 | 重新指派帶「開啟我的工項 ›」 |
textV2 + substitution({key} → {type:"mention", mentionee:{type:"user", userId}})。text + mention.mentionees 是 inbound webhook 的格式,發送時被 LINE 靜默忽略、變純文字。Flex 卡本身不能帶 mention → 需要 @提及時另發一則伴隨文字。計費(reply 免費 / push 計額度)見第 11 章。
10LIFF 路由 / Deep-link
單一入口 liff.line.me/2010491601-uK7jHMCT(= worker 根路徑)。route() 分流順序:help / photos / capture(不需成員身分)→ 1:1 個人模式(沒有 g)→ 載入成員 → 非成員一律先落角色選擇 → rev= 審核深連 → 各 v= 畫面。
參數表
| 參數 | 畫面 | 備註 |
|---|---|---|
?g=群組id | 群組情境 | bot 烙進所有群組連結;沒帶 v 時主任 → 上傳/指派、監工 → 我的工項 + 提示 |
| (沒有 g) | 1:1 個人模式 | 跨專案;雙身分先解析檢視身分 |
?v=mine | 我的工項 / 審核清單 | 群組:監工「我的|全部」、主任落「待採認」;1:1:「我的工項|待採認」 |
?v=mine&tab=review | 1:1 跨專案待採認佇列 | 聊天卡「前往待採認 ›」用 |
?v=progress | 我的進度純數字儀表板 | 完成率環 + 週/今日/逾期,無清單(showMine(false,true)) |
?rev=請款單_框(配 g) | 審核詳情 deep-link | 可帶樓層;聊天完成卡「審核 ›」用;非主任被擋 |
?v=daily | 出工日報 | &d=YYYY-MM-DD 落日、&edit=1 修改模式(主任) |
?v=evidence | 證據(照片流 + 待審清單) | 群組限定 |
?v=overview | 總覽 / 排行 | 主任全量、監工只排行 |
?v=photos · ?v=ask | 我的照片 · 問 Eagle | 群組=本專案;1:1=跨專案 |
?v=dash | 我的儀表板(1:1) | Rich Menu 主要落點 |
?v=capture&b=批次 | 整理照片 | 聊天卡「整理照片 ›」用;1:1 丟照片一律走這 |
?v=join · ?v=help | 已加入頁 · 使用說明 | help 不需成員身分(白色 LIFF chrome) |
開發輔助參數
| 參數 | 作用 |
|---|---|
?as=userId | super | crew | 只在 localhost 生效(hostname 硬性 gate,正式站無效)。模擬身分渲染(唯讀 — 寫入仍需真 token,匿名 403)。配 ?g= 且不帶 as =自動帶該群主任 |
?name=顯示名 | 只在 localhost 生效。mock 的顯示名稱(預設 Dev) |
?p=1 | 強制 1:1 個人模式。正式站也生效(不受 hostname gate) |
?dev=1 | 顯示群組 ↔ 1:1 跳轉 chip。正式站也生效 |
只有 ?as / ?name(身分 mock)被 hostname 鎖在 localhost;?p=1 / ?dev=1 在線上 workers.dev 也會作用。跑法:cd line-worker && npx wrangler dev --remote(接真實 remote D1)→ http://localhost:8787/?g=…&as=…。
11Worker API · 資料層 · 排程
Routes
| Route | 用途 |
|---|---|
POST /line/webhook | bot 事件(訊息 / 照片 / postback / 進群 / 加好友)。X-Line-Signature HMAC 驗簽只在有設 LINE_CHANNEL_SECRET 時執行 — 沒設就全部放行不驗 |
/api/members | 名冊查詢(?group=)+ 選角色(一群一主任在這擋)+ 加入廣播 |
/api/assign | 送出指派:存 payapp + boxes、掃描圖進 R2、群組推播。欄位不齊 → 400,save-first 不假 ok |
/api/payapp · /api/payapp/edit | 讀掃描(?group=)/ 改框(拍照、採認退回、改派、刪除、改截止 — 逐框 patch,防多人互相覆蓋) |
/api/mine · /api/review | 1:1 跨專案工項(?user=)· 跨專案待採認 + 是否主任 |
/api/dailylog(+ /save /remind) | 日報讀取 / 主任限定儲存(重發修正卡)/ 補拍提醒 |
/api/capture(+ /file) | 整理照片:批次讀取 / 歸檔寫入(batch 範圍內) |
/api/ask · /api/events | 問 Eagle 資料(&g= 定範圍)· 群組稽核 log(最近 200 筆) |
POST /api/img | 上傳一張照片到 R2(回傳 line/ key)— LIFF 拍照回報的寫入面 |
GET /img/<key> | 提供 R2 照片(只允許 line/ 前綴,長效 immutable cache) |
/menu/<序號>/<寬> | 選單圖(menu-寬.png;換圖要 bump 序號 + 重發選單) |
/privacy · /terms | 平台審核用頁面 |
寫入授權
- LIFF 寫入帶
liff.getAccessToken()→ worker 打 LINE/v2/profile驗人 → 依members角色授權(主任 / 本人)。 - 匿名請求 → 403。localhost dev-mock 也因此唯讀。
- 聊天 postback(採認 / 確認 / 提醒全部…)在 webhook 端用
roleOf()再驗一次主任身分。
資料層(D1 + R2)
| 表 / 桶 | 內容 |
|---|---|
members | 每群一份的角色(super / foreman)+ 名字頭像 |
payapps | 一張掃描一列。boxes=內嵌 JSON:% 座標 + 指派人 + 需要張數 req + photos + 截止 due + 樓層 floors + 逐樓層照片/審核(fp / fpReview / fpReturned)+ 採認 review / 退回 returned |
assignments | 指派彙總(人 × 數量) |
daily_log | 出工日報(解析後的列 + 確認狀態;未整理行以 {unsorted:true} 標記混存,無 schema 變更) |
pending_capture · capture_pick | 聊天照片待歸檔佇列(含 batch 欄)·「延續上一項」的上次選擇 |
line_groups | 群組 → 專案名對照(ensureGroupName() 首次看到群組時經 getGroupSummary 學起來) |
events | 稽核 log(誰在何時對哪個框做了什麼) |
R2 eagle-line-evidence | 所有照片與掃描(line/ 開頭 key,經 /img/ 提供) |
wa_evidence / wa_session 是 WhatsApp 頻道的表(同一個 worker 的另一條線),不屬於 LINE。
測試 · 排程 · 計費
- 測試:
npm test共 34 個案例(parse.test.js22:日報解析 + wantsEagle 分類;boxpatch.test.js12:逐框 patch 防覆蓋)。 - 排程:cron
0 0 * * *(UTC 00:00 = 台灣 08:00)掃所有群組:今明到期或逾期的未回報工項 → 發 digest 卡(帶「提醒全部」按鈕);沒有到期項就不發。 - 計費:reply(回應使用者動作)免費不限量;push 計入 OA 月額度(台灣 Light 200 / Standard 3,000 / Premium 6,000 則)— digest、指派通知、完成卡、催工班都是 push。
12檔案與交接
帳號與環境
| 項目 | 值 / 備註 |
|---|---|
| LINE Provider | 「Eagle AI」(台灣)· OA 未驗證(驗證解鎖群組自動名冊,非關鍵路徑) |
| LINE Login channel | 2010491601 — 掛 LIFF 2010491601-uK7jHMCT(size Full,scope profile+openid)。必須維持 Published:Developing 狀態下非開發者開啟會 400 |
| Messaging API channel | 2010491594 — bot;webhook ON → …/line/webhook |
| Secrets(wrangler secret) | LINE_CHANNEL_ACCESS_TOKEN(push / reply 必需)· LINE_CHANNEL_SECRET(webhook 驗簽,選配) |
| Cloudflare | Worker eagle-line · D1 eagle-line · R2 eagle-line-evidence(Jared 的 CF 帳號) |
檔案地圖
| 去哪看 | 位置(重點函式) |
|---|---|
| 程式(唯一交付 repo,禁 AI 署名) | GitLab JaredSong1/eagle-line=本機 eagle-ai-qms/line-worker/(獨立 git,母 repo 已解除追蹤) |
| Bot / 卡片 / cron / 喚起詞判斷 | src/index.js — 卡片殼 flexCard() · 選單 menuImagemap() · 拍照收件 captureAskCard() · 完成 fireCompletion() · 提醒 remindAllPending() · 打招呼 isGreeting() · 排程 scheduled() |
| LIFF 全部畫面 | public/index.html — route() 開始讀 · 三組導覽 NAV_SUPER / NAV_CREW / NAV_PERSONAL · 審核深連 openReviewDeep() · 日報 showDaily() |
| 解析器 + 智慧回覆 + 測試 | src/parse.js(parseDailyLog() · wantsEagle())+ tests/ |
| 資料層 | schema.sql(⚠ DROP+CREATE)+ migrate-*.sql(增量,remote 用這些) |
| 選單 / Rich Menu 美術源檔 | 母 repo line-channel-design/menu-art/;輸出品 public/menu-*.png |
| 決策史 / 60 條教訓 | 母 repo docs/specs/eagle-line-channel.md |
部署流程
- 部署:
cd line-worker && npm run deploy(wrangler 是本地 devDependency — 一次性指令用npx wrangler …)。 - 部署後必驗 live:
curl+?cb=隨機值抓 LIFF 首頁、grep 本次改動的標記字串 — 「No updated asset files」訊息可能伴隨舊資產,眼見為憑。 - 換選單美術:重出
menu-*.png→ bump/menu/序號→ 部署 → 在群組重發選單(打「選單」)。 - 資料庫異動:只跑增量
migrate-*.sql(npx wrangler d1 execute eagle-line --remote --file=…)。
- Flex 卡瀏覽器看不到,只能手機驗新觸發的訊息;舊卡片凍結在發送當下。
src/wa.js/wa_*表是 WhatsApp 頻道,不是 LINE。- 群組選單=imagemap 訊息,1:1 才是 Rich Menu,機制完全不同。
schema.sql是 DROP+CREATE,絕不能重跑在 remote。
Eagle AI · LINE 頻道系統文件 · 2026-07-07 · 截圖 28 張 + 選單素材 2 張(shots/)· 喚起詞、路由、API、資料層均已對照 line-worker/ 原始碼核實 · 僅供內部交接。





























