# Bot 生命週期

本頁說明 `New`、`Start`、`Close`、`Status` 在各平台做了什麼。

## 呼叫順序

1. `New(...)` 建立 SDK client 並驗證必要參數。Discord 與 LINE 在這一步不打網路；Telegram 的 SDK 會呼叫一次 `getMe`（5 秒逾時），所以錯誤的 Telegram token 在 `New` 就會失敗。此時所有平台都還不接收事件。
2. `Reply(handler)` 註冊 handler。可在 `Start` 前或後呼叫；沒有 handler 時抵達的事件會以 `slog.Warn("Reply is not set")` 記錄後丟棄。
3. `Start(ctx)` 驗證憑證，再開始接收事件。
4. `Close()` 停止接收，並清除該 bot 的互動狀態。

## 各平台的 Start

| 平台 | 憑證檢查（失敗即回 error） | 接著 | 第二次 `Start` |
|---|---|---|---|
| Telegram | `GetMe` | `GetWebhookInfo`；若已設定 webhook URL 則 `DeleteWebhook`（兩者失敗都只 warn）；long polling 在 goroutine 執行 | 回 `nil` |
| Discord | REST `User("@me")` | `Session.Open()` 開啟 WebSocket gateway | 回 `nil` |
| LINE | `GetBotInfo` | 在 `:<port>` 執行 `net.Listen`（綁定失敗立即回 error），再於 goroutine 執行 `http.Server.Serve` | 回 `nil` |

`Start` 會從你傳入的 `ctx` 衍生內部 context。取消該 `ctx` 會停止 Telegram polling；Discord 與 LINE 在 bot 關閉後不再呼叫 handler。

## 各平台的 Close

| 平台 | 步驟 |
|---|---|
| Telegram | 取消 polling 並等待 polling goroutine 結束；停止所有 status timer；把所有未完成的多選標記為完成並移除 |
| Discord | 取消 context 並關閉 gateway session；停止 status timer；移除未完成的 input 與 select 狀態 |
| LINE | 取消 context；以 5 秒 timeout 執行 `http.Server.Shutdown`；等待 server goroutine 結束 |

對從未啟動或已關閉的 bot 呼叫 `Close` 會回 `nil`。

## Status

`Status()` 在 bot 的 mutex 下讀取快照。身分欄位來自 `Start` 的憑證檢查，在那之前保持空值。

| 平台 | 欄位 |
|---|---|
| Telegram | `Running bool`、`Username string`、`UserID int64` |
| Discord | `Running bool`、`Username string`、`UserID string` |
| LINE | `Running bool`、`UserID string`、`BasicID string`、`DisplayName string` |

## 相關頁面

- [Reply Handler](/zh/reply-handler)
- [Telegram 設定](/zh/telegram)、[Discord 設定](/zh/discord)、[LINE 設定](/zh/line)
