顯示具有 AI Agent 標籤的文章。 顯示所有文章
顯示具有 AI Agent 標籤的文章。 顯示所有文章

2026年4月21日 星期二

為什麼 OpenClaw 排程一直送不出訊息?一次追到 LINE 429 的原因


 

最近我排查了一個很典型的通知系統問題。

表面上看,OpenClaw 的排程有正常執行,網站資料也抓得到,但 LINE 群組始終收不到通知。更容易誤導的是,部分 run 還顯示 ok,讓人一開始直覺懷疑是網站解析、排程設定,或 prompt 寫法出了問題。

但一路拆解之後,最後真正的根因不是 cron,也不是解析流程,而是 LINE 官方帳號本月免費訊息額度用完,導致主動發送持續被 429 擋下來。

這篇整理成一篇偏技術部落格風格的精簡版記錄,聚焦在排查順序、關鍵判斷點,以及最後如何收斂到真正的根因。


問題現象

當時的需求很單純:

  • 定時執行 OpenClaw cron
  • 檢查某個公告頁面
  • 若有新公告,就主動發送到 LINE 群組

實際看到的症狀是:

  • cron 有跑
  • 群組沒收到訊息
  • 部分 run 顯示 ok
  • 部分 run 出現:
  • HTTPFetchError: 400 -
  • HTTPFetchError: 429 -
  • deliveryStatus: not-delivered

這類問題最麻煩的地方在於,系統看起來像只有一個問題,實際上往往是多層故障疊在一起。


第一步,先修排程邏輯,而不是先猜平台壞掉

這次最先修的不是 LINE,而是排程本身的送訊邏輯。

當時的設計同時存在:

  • 任務內自己嘗試送訊
  • 外層 delivery/announce 機制也可能介入

這會產生一個典型問題:

  • 任務內若沒有真的送成功,只是輸出「原本應該送什麼」
  • 外層又可能把這段內容當成待送摘要處理

結果就會變成:

  • 看起來像有處理內容
  • 但其實沒有真正送出
  • 還可能多製造一層錯誤

所以第一個修正方向,是把送訊責任收斂成單一來源,避免任務內邏輯和外層 delivery 機制互撞。


第二步,先保證資料一致性

下一步不是硬把通知送出去,而是先修正這件事:

送訊失敗時,不能把資料誤記成已送。

因此我重寫了排程 prompt,核心原則是:

1. 有新公告才處理

2. 只有確認送出成功後,才更新正式已送記錄

3. 如果送訊失敗或不確定是否送達:

  • NO_REPLY
  • 不更新記錄檔
  • 不輸出「應送內容」摘要

這一步很重要,因為它把問題先從「可能污染資料」縮小成「純粹的發送失敗」。

後來做受控測試也確認:

  • 即使 LINE 發送失敗
  • 正式記錄檔也不會被誤回寫

這代表資料一致性已經被保住。


第三步,確認問題不是「沒送」,而是「送了但失敗」

一開始最容易誤判的地方是:

  • run 顯示 ok
  • 但群組沒收到訊息

這時候至少有兩種可能:

1. 任務根本沒送

2. 任務有送,但送失敗後被正確處理掉了

後來直接看 transcript 才確定:

  • 任務內確實有嘗試送 LINE
  • 但送訊時碰到 429
  • 然後依規則 NO_REPLY
  • 所以 run 還是可能顯示 ok

這一步很關鍵,因為它把問題收斂成:

cron 執行流程沒壞,真正失敗的是 LINE 發送端。


第四步,從 log 看出這不是單一 job 問題

接著去看 gateway log,很快就發現不是只有某一支 cron 在失敗,而是整條 LINE 通道近期都反覆出現:

  • line final reply failed: HTTPFetchError: 429
  • delivery-recovery: Retry failed for delivery ...: 429 -

這代表問題已經不能只看成單一排程故障,而要往更外層想:

  • 是不是 LINE channel 本身有問題?
  • 是不是平台在限流?
  • 是不是有 backlog 不斷重試?

第五步,找到 delivery backlog 的實體位置

後來我把 backlog 的實體位置挖出來了:

  • ~/.openclaw/delivery-queue/

裡面會留下待送但未成功的 delivery 項目,內容包含:

  • 舊通知
  • 測試訊息
  • 失敗通知

再結合 log 可以看出:

  • 某批 pending delivery 會被 delivery recovery 拿出來重試
  • 重試又再次碰到 429
  • 於是 queue 一直堆著、一直重試

這說明 backlog 的確存在,而且是跨時間持續存在。


第六步,隔離 backlog,但問題仍然存在

為了驗證 backlog 是否為主因,我採用比較保守的方式處理:

  • 停 gateway
  • 把 active queue 裡的 backlog 隔離到 quarantine 資料夾
  • 再啟動 gateway
  • 重新測試直接送訊

這種處理方式的好處是:

  • 不直接刪資料
  • 可回復
  • 能快速驗證 backlog 是否造成主要影響

但測完後結果很清楚:

  • backlog 確實被隔離了
  • queue 也乾淨很多
  • 但新的直接送訊仍然回 429

這表示 backlog 不是唯一問題,真正更底層的限制還在。


最後根因,LINE 免費訊息額度已用完

最後到 LINE Developers / 官方帳號後台確認,答案就很明確了:

  • 本月免費訊息額度已經用完

這時整個事件才完整串起來:

1. 主動發送額度先耗盡

2. 所有新的主動送訊都回 429

3. 送失敗的內容堆進 delivery queue

4. recovery 不斷補送

5. 補送再度 429

6. 表面上看起來像 cron 有跑但訊息永遠送不到

所以最後真正的根因不是:

  • cron 壞了
  • 網站解析壞了
  • OpenClaw 不會送 LINE

而是:

LINE 官方帳號的主動發送額度先耗盡了。


這次最值得保留的排查方法

這次事件裡,我自己覺得最值得保留的是下面這幾個排查習慣。

1. 不要把所有症狀都叫做「排程失敗」

要拆開看:

  • cron 有沒有跑
  • 任務邏輯有沒有走到送訊
  • delivery 狀態是不是 not-delivered
  • gateway log 在報什麼
  • backlog 有沒有持續重試
  • 平台本身是不是有限流或額度問題

2. 先修資料一致性,再修通知能力

先保證「失敗不會誤標成已送」,再處理送訊本身,這樣排查才不會把資料一起搞亂。

3. ok 不等於真的送到

這次最迷惑人的點就在這裡。run status 只能代表任務流程是否成功收尾,不能單獨代表通知真的送達。

4. backlog 一定要找實體位置

只看 log 很容易一直猜。真的找到 queue 檔案位置後,整個問題才變得可驗證、可操作。


遇到類似問題時的排查順序

如果你也遇到「排程有跑,但通知沒到」的問題,我會建議照這個順序查:

1. 確認 cron 是否真的有執行

2. 確認任務是否真的走到送訊邏輯

3. 確認失敗時不會誤回寫 sent 記錄

4. 查看 gateway log 裡的 delivery / 429 / 400 訊號

5. 檢查 delivery queue 是否有 backlog

6. 如果 backlog 清掉後仍然 429,就直接查平台額度或限流

這樣可以避免你一直在本地系統裡打轉,卻忽略真正的上游限制。


最後怎麼處理?

既然已確認這個月免費訊息額度用完,那在不付費前提下,最實際的作法不是硬送,而是:

  • 暫停主動 LINE 發送
  • 排程改成只記錄待通知內容
  • 同時輸出:
  • 一份人類好讀的 Markdown 待通知檔
  • 一份結構化 JSON 待通知檔
  • 等下個月額度重置後,再切回主動推播

這樣做的好處是:

  • 不再持續撞 429
  • 不再製造新的 delivery backlog
  • 不會遺失新公告資訊
  • 下個月可以平順恢復

結語

這次的問題很適合提醒自己一件事:

排程有跑,不代表通知真的有送到。

很多時候,問題根本不在 cron,而是在更外層的 delivery 設計、queue 重試機制,甚至平台額度本身。

如果我只停在「cron 顯示 ok」這一層,就永遠找不到真正原因。

這次最後能收斂到 LINE 免費額度用盡,靠的不是單一招,而是一路把每一層拆開來看,最後才把問題釘死。

如果你也在做 OpenClaw、LINE 通知、或任何有 queue / retry / 平台額度限制的系統,我很推薦保留這種排查思路。下次再遇到類似問題,會快非常多。

2026年4月1日 星期三

OpenClaw 串接 LINE Bot 後,加入群組卻無法回應?一次完整排查與修正紀錄

最近我把 OpenClaw 串接到 LINE,並把 bot 加入群組,原本以為只要加入成功,就能直接在群組中互動。結果實際測試後卻發現:


- 私訊 bot 沒問題

- bot 也確實已加入群組

- 但在群組裡呼叫它,卻完全沒有反應


這篇文章整理我這次的排查過程,希望能幫助遇到相同問題的人少走一些彎路。


問題現象

這次遇到的情況很明確:

- 私訊 bot 時可以正常回覆

- bot 已被加入 LINE 群組

- 但在群組裡傳送訊息,例如:

  蝦蝦 在嗎

  蝦蝦 回 1


bot 都沒有反應。


第一步:先確認是不是整體壞掉


我先直接私訊 bot 測試,確認:


- LINE channel 沒壞

- OpenClaw gateway 有正常運作

- bot 本身不是離線

- webhook 至少對私訊事件是正常的


結果是:私訊正常


這代表問題不是整體服務故障,而是更可能集中在群組路徑。


第二步:檢查 OpenClaw 狀態

接著查看 OpenClaw 與 gateway 狀態:

openclaw status --deep

openclaw gateway status


檢查後確認:


- OpenClaw 正常

- gateway 正常

- LINE provider 有啟動


所以可以先排除整個系統掛掉的可能。


第三步:檢查 openclaw.json

接著查看設定檔,找到 LINE 相關設定:


"channels": {

  "line": {

    "enabled": true,

    "dmPolicy": "pairing",

    "groupPolicy": "allowlist"

  }

}


這裡的重點是:

- 私訊使用 pairing

- 群組使用 allowlist

也就是說,群組不是自動允許,而是需要符合 allowlist 規則。


第四步:檢查 allowlist

進一步檢查後發現,目前 allow 清單裡只有使用者本人的 LINE ID,沒有群組 ID。

這代表:

即使 bot 已經加入群組,只要該群組 ID 沒有進 allowlist,群組訊息就可能被擋住。


第五步:嘗試查群組 ID

我接著用 OpenClaw 指令查詢群組:

openclaw directory groups list --channel line --account default --json

結果回傳是空的:

[]

這表示當下沒有成功取得群組 ID,也因此無法直接把該群組加入 allowlist。


第六步:回頭檢查 LINE 設定

接著回頭確認 LINE Developers / Official Account 的幾個重點:

- Use webhook 是否開啟

- Webhook URL 是否正確

- Verify 是否成功

- 是否允許 bot 加入群組 / 多人聊天室

- 是否使用正確的 Messaging API channel

確認後,這些設定都沒有問題。


第七步:先把 groupPolicy 改成 open

因為當下無法取得 group ID,所以先做一個最小調整,把:

groupPolicy = allowlist

改成:

groupPolicy = open

這一步的目的,是先排除 allowlist 的限制,驗證群組是否能正常工作。


第八步:設定改完後要重啟 gateway

修改設定後,日誌裡出現提示:

Updated channels.line.groupPolicy. Restart the gateway to apply.

這表示設定雖然已經寫入檔案,但還沒有真正生效。

所以如果只改設定、不重啟 gateway,接下來的測試可能還是在測舊設定。


第九步:重啟 gateway

最後執行:

openclaw gateway restart

重啟後再確認:

- gateway 正常 running

- LINE provider 已重新啟動

- 新設定已套用

到這裡,群組設定的變更才算真正生效。


這次排查學到的事


1. 私訊正常,不代表群組一定正常

私訊與群組是不同路徑,私訊可用只能證明 bot 沒整體故障。


2. allowlist 很容易成為盲點

bot 看起來在群組裡,不代表該群組真的被允許觸發回應。


3. 改完設定不代表已生效

有些設定需要重啟 gateway 才會真正套用。


4. 排查要一層一層拆

這次最有效的順序是:

- 先測私訊

- 再看 OpenClaw 狀態

- 再檢查 groupPolicy

- 再看 allowlist

- 最後重啟 gateway


建議的排查順序

如果你也遇到 LINE 群組裡 bot 不回應的問題,可以照這個順序檢查:


1. 私訊 bot,確認私訊是否正常

2. 執行 openclaw status --deep

3. 執行 openclaw gateway status

4. 檢查 openclaw.json 裡的 groupPolicy

5. 確認 allowlist 是否包含群組 ID

6. 執行 openclaw directory groups list --channel line --account default --json

7. 修改設定後記得重啟 gateway


結語


這次問題表面上看起來像是 LINE 群組訊息沒進來,但實際排查後發現,真正的關鍵在於:

- groupPolicy 使用 allowlist

- allowlist 裡沒有群組 ID

- 設定修改後還需要重啟 gateway 才會生效


如果你也在用 OpenClaw 串接 LINE,建議不要只檢查 webhook,

groupPolicy、allowlist 和 gateway restart 這幾個地方也一定要一起看。