Zeabur bot 搬家:Discord、Telegram、LINE bot 的 token 重發、webhook 改址與排程替代

Discord、Telegram、LINE bot 要搬出 Zeabur,順序是:先在新環境把程式部署好,再到各家後台重發 token(LINE 連 channel secret 一起換),新 token 只填進新環境;webhook 型的 bot 要把 webhook 網址改到新主機並通過驗證,長連線型的 bot 不需要公開網址。bot 要一直在線,適合能長駐的容器平台或 VPS,不適合有執行時間上限的 serverless。另外跑的 Python 排程,可以改用 GitHub Actions、Cloudflare Workers Cron Triggers 或 VPS 上的 systemd timer,三者的時區與準時程度不同。文末附搬完的驗收表。

這篇是〈Zeabur 搬家前先換金鑰〉的 bot 與排程專篇。停止營運的時程、退款、網域轉出等共通部分,請看那篇;這裡只講 Discord、Telegram、LINE bot 和排程工作特有的地方。

文中 Zeabur 的說法引自官方狀態頁與官方文件,各家 bot 平台與排程服務的做法引自各家官方文件,文中官方資料的查詢日期是 2026 年 10 月 18–19 日。各家介面常改,實際操作以官方頁面為準。

先分清楚:你的 bot 是哪一種

搬 bot 之前,先看它是怎麼收訊息的。這決定新主機需不需要公開網址。

平台要公開網址的方式不用公開網址的方式官方怎麼說
TelegramWebhook(setWebhook)Long polling(getUpdates)兩種收 update 的方式互斥,只能擇一
DiscordInteractions Endpoint URLGateway(WebSocket 長連線)預設走 Gateway;設了 Endpoint URL 才改走 HTTP
LINEWebhook URL無官方教學寫明,bot 要收訊息就要設 webhook URL

用 python-telegram-bot 的,程式裡呼叫的是 run_polling() 還是 run_webhook(),就看得出是哪一種;用 discord.py 寫的 bot,預設就是 Gateway 長連線。

要人代搬,可以看我們的PaaS 停運搬家與資安檢查服務。

第一步:bot 的 token 一定要換

Zeabur 狀態頁 10 月 15 日的更新寫明,這次事件外洩的資料包括服務的環境變數(原文:「The exposed data includes service environment variables, account information, API tokens, and zSend API keys」),官方要用戶做的第一件事,就是輪換存在環境變數裡的所有密鑰。

bot 的 token 通常就放在環境變數裡。Telegram 官方說 token「can be used by anyone to control your bot」,拿到 token 的人就能用你的 bot 發訊息;LINE 官方舉的例子是,channel access token 外洩後,第三方可以用「Broadcast message」對官方帳號的所有好友發訊息。所以 bot 搬家前,token 要先換。其他金鑰的換法,見〈Zeabur 金鑰外洩後要換哪些?〉。

順序很重要:先把程式部署到新環境、確認能啟動,再重發 token。新 token 只填進新環境,不要回填到 Zeabur 上的舊服務。舊 token 什麼時候失效,各家寫法不同(見下面各段),所以舊服務要自己停掉,不要靠 token 失效,才不會出現新舊兩個 bot 同時在線。

另外,Zeabur 官方文件列出 ${ZEABUR_[連線埠名稱]_URL}、${ZEABUR_SERVICE_ID} 這類平台自動帶入的變數。程式如果用這些變數組 webhook 網址,搬走後都要改成固定值。

Telegram:在 @BotFather 用 /token

官方原句:「If your existing token is compromised or you lost it for some reason, use the /token command to generate a new one.」到 @BotFather 送 /token,就能產生新的 token。

官方頁面只寫 /token,沒有寫 /revoke,也沒寫舊 token 什麼時候失效。換完後用舊 token 呼叫一次 getMe(官方說這是「testing your bot’s authentication token」的方法),確認已經不能用。

Discord:在 Developer Portal 按 Reset Token

到 Discord Developer Portal,選你的應用程式,左側 Bot 頁的 Token 底下按「Reset Token」產生新的 bot token。官方提醒,token 只會顯示一次,「You won’t be able to view your token again unless you regenerate it」,要先存到密碼管理工具;也不要把 token 放進版本控制。舊 token 什麼時候失效,官方文件沒寫。

搬到新環境時還要注意一件事:Discord 官方文件寫明,一個應用程式 24 小時內最多呼叫 1,000 次 IDENTIFY(Gateway 連線時的登入),超過的話所有連線會被中斷、bot token 會被重設,並寄信通知擁有者。新環境如果設定有錯、程式一直重啟重連,可能撞到這個上限,所以要先在新環境把錯誤排除,再讓它自動重啟。

LINE:channel access token 依種類處理,channel secret 也要換

LINE Messaging API 的 channel access token 有四種,官方整理如下:

種類有效期每個 channel 可發幾個
自訂有效期(v2.1)最多 30 天30
Stateless15 分鐘不限
Short-lived30 天30
Long-lived不會過期1

LINE 官方的建議是:「if you suspect that the channel access token has been compromised, revoke it.」各種類的處理方式:

  • Long-lived:到 LINE Developers Console 該 channel 的 Messaging API 分頁重新發行。官方寫明,重新發行會讓目前的 long-lived token 失效;重新發行時可以讓舊的再撐最多 24 小時。外洩的情況下,不建議延長,新環境準備好再按。
  • Short-lived 與 v2.1:用官方 API 撤銷,short-lived 用 POST /v2/oauth/revoke,v2.1 用 POST /oauth2/v2.1/revoke,再發新的。
  • v2.1 的簽章私鑰:v2.1 token 是用你自己產生的 assertion signing key(一組私鑰與公鑰)簽 JWT 換來的。如果私鑰也放在環境變數裡,要重新產生一組金鑰,到 Console 的 Basic settings 分頁按「Register a public key」登錄新的公鑰。舊公鑰怎麼停用,以 LINE 官方頁為準。
  • Stateless:官方寫明發出後不能撤銷,但 15 分鐘就過期。

Channel secret 用來驗證 webhook 簽章,也在環境變數裡的話一樣要換。到 Basic settings 分頁按「Issue」重新發行,需要 channel 的 Admin 權限。官方原句:「Issuing a new channel secret invalidates the current channel secret.」換完之後舊的 secret 立刻不能驗簽章,新環境要同時換上新值。

第二步:webhook 型的 bot 要改網址

在 Zeabur 上,webhook 網址常用的是 zeabur.app 子網域。這個網址在 Zeabur 停止服務後就連不到,一定要改到新主機的網址。如果 webhook 本來就是你自己的網域,可以沿用同一個網址,把 DNS 指到新主機,切換後一樣要做下面的驗證。

Telegram:重新呼叫 setWebhook

用新的 token 呼叫 setWebhook,把網址改成新主機。官方規定 webhook 必須是 HTTPS,目前支援的埠是 443、80、88、8443。可以加 secret_token 參數,Telegram 會在每次請求的標頭 X-Telegram-Bot-Api-Secret-Token 帶上這個值,讓你確認請求真的來自自己設的 webhook。

curl "https://api.telegram.org/bot<新的 token>/setWebhook?url=https://<新網址>/<路徑>&secret_token=<自訂字串>"
curl "https://api.telegram.org/bot<新的 token>/getWebhookInfo"

getWebhookInfo 會回傳目前的網址、還沒送達的 update 數量(pending_update_count)和最近一次送達失敗的錯誤訊息。網址對、沒有錯誤訊息,就是設好了。

不要加 drop_pending_updates=True,除非你確定要丟掉搬家期間累積的訊息,官方說這個參數會「drop all pending updates」。

LINE:在 Console 改 Webhook URL 再按 Verify

照 LINE 官方教學:登入 LINE Developers Console → 選 provider → 選 Messaging API channel → Messaging API 分頁 → Webhook URL 底下按 Edit,填新網址後按 Update → 按 Verify,看到 Success 才算通過 → 確認「Use webhook」是開啟的。

官方有兩個規定要注意:webhook URL 必須是 HTTPS,憑證要由一般瀏覽器信任的憑證機構簽發,不接受自簽憑證;每個 channel 只能設一個 webhook URL,所以切換是一次性的,新主機要先能正常回應再改。不想用 Console 的話,也可以用官方 API PUT /v2/bot/channel/webhook/endpoint 改網址、POST /v2/bot/channel/webhook/test 測試。

Discord:改 Interactions Endpoint URL

只有用 HTTP 收互動(slash command、按鈕)的 Discord 應用程式才有這一步。到應用程式設定的 General Information 頁,把 Interactions Endpoint URL 改成新網址。

官方寫明,新網址存檔前要能做到兩件事,否則不會通過驗證:

  1. 收到 Discord 送來的 PING(type: 1)時,回 200 和 type: 1 的 PONG。
  2. 驗證每次請求的 X-Signature-Ed25519 與 X-Signature-Timestamp 標頭,簽章不對就回 401。

Discord 之後還會定期送出故意錯誤的簽章做檢查,沒擋下來的話,官方會移除你的 Endpoint URL,並用 email 和系統私訊通知。新環境的簽章驗證要跟舊環境一樣完整。

長連線型 bot 不需要公開網址

Telegram 的 getUpdates 是 long polling,Discord 的 Gateway 是 bot 主動開的 WebSocket 長連線。兩者都是 bot 主動連出去拿訊息,新主機不用開放對外的連入埠,也不用網域和 HTTPS 憑證,可以放在沒有對外 port 的主機或內網裡。Discord 官方也寫明,用 Gateway 收互動的應用程式,不需要設定 Interactions Endpoint URL。

Telegram 要注意一點:官方原句「You will not be able to receive updates using getUpdates for as long as an outgoing webhook is set up.」原本用 webhook、搬家後想改成 long polling 的,要先呼叫 deleteWebhook,getUpdates 才收得到。

搬去哪:bot 要能一直在線

bot 是長駐程式。長連線型的 bot 要一直保持連線,webhook 型的 bot 也要隨時能接收請求,所以新家要能讓程式一直跑著。

不適合:只在有請求時才執行的 serverless。 以 Vercel Functions 為例,官方原句是「If a function runs for longer than its set maximum duration, Vercel will terminate it.」,最大執行時間依方案從 300 秒到 800 秒,延長版(beta)最多 30 分鐘。Gateway 或 long polling 這種要連線好幾天的程式,放在這裡會被中斷。webhook 型的 bot 每則訊息是一次請求,可以拆成 serverless 函式,但要改寫程式結構,不是單純搬家。

適合:能長駐的容器平台或 VPS。 例如 Railway、Render、Fly.io 這類容器平台,或自己的 VPS、自家機房。原本在 Zeabur 用 Dockerfile 或映像部署的,多半可以直接沿用。各平台的差別,見〈Zeabur 替代方案總比較 2026〉。不管搬到哪,都要設定程式掛掉時自動重啟,並記得前面 Discord 的 IDENTIFY 上限。

排程(cron)搬家:三種做法

如果你在 Zeabur 上有定時跑的 Python 腳本,搬法看它寫在哪裡:

  • 寫在 bot 程式裡(例如 bot 內建的排程器):跟著 bot 一起搬,不用另外處理,只要確認新主機的時區設定。
  • 獨立的排程服務或腳本:可以換成下面三種做法之一。
做法適合什麼要注意什麼時區
GitHub Actions schedule程式已在 GitHub、每次跑完就結束的腳本最短每 5 分鐘一次;高負載時可能延遲,整點是高負載時段,負載夠高時排隊中的工作可能被丟棄;只在預設分支跑;公開 repo 60 天沒有活動,排程會自動停用預設 UTC,可另設 IANA 時區
Cloudflare Workers Cron Triggers呼叫 API、寫入資料這類輕量工作程式要改寫成 Worker(JavaScript、TypeScript 或 Python Workers);免費方案每個帳號 5 個 Cron Trigger、每次 CPU 時間 10 毫秒;新增或修改排程最多要 15 分鐘才生效UTC
VPS 上的 systemd timer 或 crontab跟 bot 放在同一台、要讀本機檔案或跑很久的工作主機要自己維護;systemd timer 設 Persistent=true,可以補跑關機期間錯過的排程systemd 可在排程裡寫時區;crontab 依主機時區,cronie 可用 CRON_TZ

GitHub Actions:記得時區

GitHub 官方寫明,排程預設用 UTC(原文:「By default, scheduled workflows run in UTC.」),可以另外指定 IANA 時區。下面是每天台北時間 01:07 跑一次的寫法,分鐘數刻意避開整點:

on:
  schedule:
    - cron: '7 1 * * *'
      timezone: "Asia/Taipei"

bot token 或 API key 不要寫進 workflow 檔,用 repository secret 存,在 workflow 裡用 ${{ secrets.<名稱> }} 取用。

Cloudflare Workers:寫在 Wrangler 設定檔

官方原句「Cron Triggers execute on UTC time.」台北時間 01:07 要寫成 UTC 17:07:

[triggers]
crons = [ "7 17 * * *" ]

用 Wrangler 管理的 Worker,官方建議 Cron Trigger 只在 Wrangler 設定檔裡改。

VPS:systemd timer

一個排程要兩個檔:一個 .service 寫要跑什麼,一個同名的 .timer 寫什麼時候跑。timer 範例:

# /etc/systemd/system/daily-job.timer
[Timer]
OnCalendar=*-*-* 01:07:00 Asia/Taipei
Persistent=true

[Install]
WantedBy=timers.target

設好後用 systemctl enable --now daily-job.timer 啟用,systemctl list-timers 看下一次和上一次執行時間。

搬完要驗的 7 件事

檢查怎麼看通過標準
舊 token 已作廢Telegram 用舊 token 呼叫 getMe;Discord、LINE 看後台已重發舊 token 呼叫失敗
新 token 只在新環境搜新環境以外的地方:Zeabur 舊服務的環境變數、程式碼、repo只出現在新環境的環境變數或 secret
LINE channel secret 已換送一則測試訊息給 bot新環境簽章驗證通過,bot 有回應
Webhook 指向新網址Telegram 看 getWebhookInfo;LINE 按 Verify;Discord 存檔 Endpoint URL網址是新主機、沒有錯誤訊息、LINE 顯示 Success
長連線型 bot 在線Discord 看 bot 是否顯示上線;Telegram 傳一則訊息bot 有回應
排程第一次執行成功GitHub Actions 的執行紀錄;Cloudflare 的過去事件;systemctl list-timers第一次排定的時間有成功紀錄,時間符合台北時間
舊 Zeabur 服務已停Zeabur 主控台確認 bot 與排程服務都已停止新舊兩邊不會同時處理同一則訊息,排程不會跑兩次

最後一項特別注意排程:舊的排程腳本如果用的是沒換的金鑰,Zeabur 上的排程會繼續跑,跟新環境的一起重複執行。

揭露

火曜領航有提供 bot 與排程搬家、主機代管服務。這篇的步驟不需要找任何人也能自己做。

如果您的服務還在 Zeabur 上,需要人幫忙盤點、搬遷或輪換金鑰,可以到〈PaaS 停運搬家與資安檢查服務〉看四種做法,或直接填寫詢價表單,我們會在一個工作日內回覆搬遷順序建議。

常見問題

換 token 後,舊的 bot 會怎樣?

LINE 官方寫明,重新發行 long-lived channel access token 會讓目前的失效(可選擇讓舊的最多再撐 24 小時),重新發行 channel secret 會讓舊的 secret 失效,所以舊環境不能再用舊 token 呼叫 API,也驗不過新的 webhook 簽章。Telegram 和 Discord 官方文件沒寫舊 token 何時失效。建議新環境準備好再重發,並自己把 Zeabur 上的舊服務停掉,不要依賴 token 失效。

LINE bot 可以不換 webhook 網址嗎?

看網址是誰的。如果 webhook URL 是你自己的網域,可以沿用,把 DNS 指到新主機即可,但新主機的 HTTPS 憑證要由受信任的憑證機構簽發,LINE 不接受自簽憑證。如果用的是 zeabur.app 子網域,就一定要改。改完或切完 DNS,都到 Console 按一次 Verify,看到 Success 才算完成。

Discord bot 一定要對外網址嗎?

不一定。Discord 預設用 Gateway 長連線收互動,這種 bot 不需要設 Interactions Endpoint URL,也不需要對外網址。只有選擇用 HTTP 收互動的應用程式,才需要一個公開、能回應 PING 並驗證簽章的網址。

GitHub Actions 的排程準不準?

不保證準時。GitHub 官方寫明,高負載時排程可能延遲,每小時整點是高負載時段,負載夠高時,排隊中的工作可能被丟棄;最短間隔是每 5 分鐘一次。官方建議把排程排在整點以外的時間。需要準時的工作,放在自己主機的 systemd timer 比較穩定。

搬家期間,訊息會不會漏掉?

看平台。Telegram 官方寫明,bot 還沒收的 update 會存在伺服器上,但不會超過 24 小時,所以 24 小時內完成切換,新 bot 上線後還收得到;設 webhook 時不要加 drop_pending_updates。LINE 有「Webhook redelivery」功能,預設關閉,開了以後 bot 伺服器暫時沒回應的 webhook 會重送,但官方說不保證一定送達,重送次數與間隔也不公開。Discord 我們查的官方文件沒寫離線期間的訊息會不會補送,切換盡量排在離峰時間。

參考來源

以上資料皆於 2026 年 10 月 18–19 日查詢。

最後更新: