開始使用
準備項目
- GitHub 與 Vercel 帳號。
- LINE Developers 的 Messaging API channel。
- OpenAI Platform API key 與 API billing。
- SerpAPI key(預設搜尋開啟;不使用時設
ENABLE_SEARCH=false)、選用 Vercel Blob store(GPT Image 生圖)。 - 6.0 必要:Supabase Postgres;Google Calendar/Tasks 另需 Google Cloud 專案與 OAuth client。
部署到 Vercel
- Fork SanHsien/gpt-ai-assistant。
- 在 Vercel 匯入 fork,Framework Preset 維持自動偵測。
- 在 Settings → Environment Variables 至少設定:
APP_DEBUG=false
OPENAI_API_KEY=...
LINE_CHANNEL_ACCESS_TOKEN=...
LINE_CHANNEL_SECRET=...
- 部署後取得穩定網域,例如
https://your-project.vercel.app。 - 在 LINE Developers → Messaging API 設定 webhook:
https://your-project.vercel.app/webhook
- 開啟 Use webhook,關閉 LINE 官方的 Auto-reply 與 Greeting messages。
- 使用 Verify 確認 webhook 可達,再加 bot 好友實測文字對話。
LINE_CHANNEL_SECRET 不可留空;缺少時服務會 fail closed,不接受 webhook。
LINE 圖文選單(選用)
Quick Reply 會隨 bot 回覆出現、由 LINE 排成單列橫向捲動;若希望手機版一直有兩列常用入口,可在 LINE Official Account Manager 手動建立大型 3×2 圖文選單。這不是部署前置條件,也不需要新增環境變數。
| 上左 | 上中 | 上右 | 下左 | 下中 | 下右 |
|---|---|---|---|---|---|
新增行程記行程 | 我的行程我的行程 | 天氣天氣 | 新增任務新增任務 | 我的任務我的任務 | 更多功能指令 |
六區的動作類型都選「文字」,傳送上表反引號內的內容。聊天優先可將選單預設收合,新手導覽可預設展開。不要再建立同名的「關鍵字自動回應」,否則可能和 webhook bot 同時回覆。Rich menu 只在 iOS/Android LINE 顯示,不支援 Windows/macOS;若未顯示,也要檢查 Messaging API 建立的 per-user/default rich menu 是否蓋過後台選單。詳細限制見 LINE Quick Reply、Rich menus overview 與台灣圖文選單手冊。
啟用生圖
gpt-image-2 回傳 base64 圖片,必須轉成 LINE 可讀的 HTTPS URL:
- 在 Vercel 專案連結一個 private Vercel Blob store。
- 新版 Vercel 會注入
BLOB_STORE_ID並使用 OIDC,不一定需要靜態 token。 - 若 log 顯示
No blob credentials found,再設定BLOB_READ_WRITE_TOKEN。 - 預設模型
gpt-image-2、品質low;可在環境變數調整。
程式會 private upload,再產生限時 signed URL 給 LINE;不要把 store 改成 public。
設定 durable-only runtime 與行程
- 建立 Supabase Postgres,使用 serverless transaction pooler URL。
- 在 Vercel Production 以 Sensitive env 設定
DATABASE_URL、DATABASE_SSL_CA、DATA_ENCRYPTION_KEY。 - 在 fork 的本機目錄把上述三個值放進未追蹤的
.env,執行npm ci與npm run db:migrate。 - 執行
npm run db:preflight,再到 Supabase SQL Editor 查schema_migrations,確認最後一筆是0019_calendar_sync_query_version.sql。migration runner 會保存 SHA-256;不要只貼 DDL 而漏掉 migration 紀錄。 - 在 Vercel Production 依需要啟用
ENABLE_SCHEDULE=true、ENABLE_TASKS=true與ENABLE_WEATHER=true,然後 Redeploy。6.0 固定使用 durable queue,沒有APP_WEBHOOK_QUEUE。
0010 是天氣訂閱、0011 是 Google Tasks outbound、0012/0013 是 Calendar inbound、0014/0016 是 Tasks inbound,0015/0017 收斂提醒索引,0018 將 bot source 啟停狀態移入 Postgres,0019 將 Calendar inbound 改為非展開系列同步並版本化既有 cursor。必須先套用 migration,再部署 6.0。
若啟用 ENABLE_GOOGLE_TASKS=true,先確認 Web OAuth client 所屬的同一 Google Cloud project 已啟用 Google Tasks API;只有 Tasks scope 不代表 API 已啟用。既有僅授權 Calendar 的帳號必須重新傳送「連結 Google 行事曆」授予 Tasks scope;callback 會自動回填既有未同步任務。若曾因 API 未啟用而失敗,啟用後再次連結,rc.5 會安全重排同一 dead sync job,不建立第二筆任務。
啟用每分鐘 worker 與到點提醒
- 產生至少 32 字元的隨機
REMINDER_CRON_SECRET,放入 Vercel Production Sensitive env。 - 在本機暫時設定相同 secret、
DATABASE_URL/DATABASE_SSL_CA,以及REMINDER_CRON_URL=https://你的正式網域/cron/reminders。 - 執行
npm run db:configure-reminders;URL 與 secret 會加密保存在 Supabase Vault,Cron 每分鐘觸發一次。此 worker 同時處理提醒、Google Calendar 同步重試與最終狀態通知。 - 設
ENABLE_REMINDERS=true並 Redeploy。行程有時間時在開始時間提醒;整天行程在當日 09:00 提醒。 - 到 Supabase Cron Jobs/History 確認
gpt-ai-assistant-reminders為 active,而且每分鐘成功呼叫正式/cron/reminders;只看到 job 存在不等於 worker 已成功執行。
提醒使用 LINE Push API,會計入月額度。不要把 secret 貼進 SQL、文件、issue 或聊天。
提醒偏好指令包含 暫停提醒、恢復提醒與 安靜時段 22:00-07:00。暫停期間到點的提醒不補發;恢復只影響之後到點的新提醒。
啟用 Google Calendar
- 在 Web OAuth client 所屬的同一 Google Cloud project 啟用 Google Calendar API;要同步任務時必須另外啟用 Google Tasks API,並到「API 和服務 → 已啟用的 API 和服務」確認兩者都存在。設定 External OAuth consent screen。短期測試可加入 test user;長期 Calendar 存取應發布為 In Production,否則授權與 refresh token 會在 7 天後到期。少於 100 位使用者的個人用途可暫不送驗證,但首次授權會顯示警告且有 100 位新使用者上限。
- 建立 Web application OAuth client,Authorized redirect URI 設為
https://你的正式網域/oauth/google/callback。 - 在 Vercel Production 設定
GOOGLE_CLIENT_ID、GOOGLE_CLIENT_SECRET、GOOGLE_OAUTH_REDIRECT_URI;全部使用 Sensitive env。 - 確認
0004_google_calendar.sql已套用;Tasks outbound 另需0011,Tasks inbound 需0014/0016,Calendar inbound 另需0012/0013/0019。 - 設
ENABLE_GOOGLE_CALENDAR=true;需要 Tasks outbound 設ENABLE_GOOGLE_TASKS=true,需要 Tasks inbound 再設ENABLE_GOOGLE_TASKS_INBOUND=true;Calendar timed inbound 則設ENABLE_GOOGLE_CALENDAR_INBOUND=true,然後 Redeploy。6.0 部署前 migration 必須到0019。 - 在 LINE 傳
連結 Google 行事曆或連結Google行事曆,按「前往 Google 授權」。每次新增 scope(例如首次開 Tasks)都必須重新連結;callback 會回填既有未同步任務。授權完成後,新增、修改行程、我的行程、完成與刪除才會操作 Google Calendar。 - 確認每分鐘 worker 已依上一節完成設定。Google 同步預設最多 3 次,成功後才回覆;最終失敗才顯示重試、暫不處理與刪除。Calendar inbound 預設最多需等待約 5–6 分鐘才會在 LINE 查詢反映。
不要把任何真實 key、client secret、Database URL、CA、encryption key 或 token 貼入文件、issue、commit 或聊天記錄。
Production 上線檢查
- 正式根網址回
200,且顯示預期版本。 - LINE Developers 的 webhook Verify 成功,文字對話只回覆一次。
- Supabase
schema_migrations最後一筆等於 repo 最新 migration,Cron History 每分鐘成功。 - Vercel 改過任何 env 後已 Redeploy,Function Logs 沒有 DB TLS、OAuth 或 cron
401/503。 - 在 LINE 重新連結 Google,建立一筆測試行程與一筆測試任務,分別確認 Google Calendar 與 Google Tasks 各只有一筆。
由 AI 操作 LINE PC 驗收
維護者可明確授權 AI 操作 LINE Windows 客戶端執行最後的 Production round-trip。這是受監督的桌面驗收,不是可在 CI 盲目重播的固定巨集:每一步都必須重新列出/啟用唯一 LINE 視窗、從最新畫面定位輸入框、一次傳送一則訊息,確認 bot 回覆後才做下一個狀態轉移。
開始前建立驗收清冊,記錄時間窗、唯一測試前綴、本機音訊路徑與產生的資料 id;LINE 結果須再到 Google Calendar/Tasks、Supabase jobs 與 Vercel logs 交叉核對。正式版後要回顧整個 release cycle,而非只清最後一批:刪除可精準界定的 events、tasks、confirmations、相關 jobs/runs/processed events 與本機暫存音訊,並檢查已無 event 的 pending reminder。週期 inbound cron/cursor、真實資料與平台不可控 logs 不刪,也不能宣稱完全沒有痕跡。
完整權威流程見主 repo 的 docs/DEVELOPMENT.md。
本機開發
需要 Node.js 24(與 CI、Vercel 及 Docker image 一致)。
git clone https://github.com/SanHsien/gpt-ai-assistant.git
cd gpt-ai-assistant
npm ci
cp .env.example .env
npm run dev
本機 webhook 需要公開 HTTPS,可用 ngrok 或 cloudflared 暫時轉送 APP_PORT(預設 3000)。
修改後至少執行:
npx eslint .
npm test
Docker
Repo 保留 Node 24 Dockerfile 與 docker-compose.yaml。先從 .env.example 建立不納入 Git 的 .env 並填完必要值,再執行 docker compose up --build --detach;Compose 會把 .env 注入 container,APP_PORT 未設定或留白時使用 3000。image 只安裝 production dependencies、以非 root 使用者執行,並內建 /health/live healthcheck。用 docker compose ps 確認狀態為 healthy,再開啟 http://127.0.0.1:3000/health/live。restart: unless-stopped 只在主程序退出時重啟,不會單憑 unhealthy 自動重啟;需要自動回收時須由部署平台或 orchestrator 監控。Docker 並不免除公開 HTTPS webhook、Supabase、LINE credentials 與 OpenAI API key 的需求。
更新
Vercel 連結 GitHub main 後,每次 push 會自動部署。更新前先查看 CHANGELOG,並確認新增的環境變數;修改環境變數後需 Redeploy 才生效。