# Status Messages

`SendStatus` and `FinishStatus` keep one editable "thinking" message per Telegram chat or Discord channel while your handler works. LINE has no status API.

## Signatures

```go
// core/telegram
func (b *Bot) SendStatus(ctx context.Context, chatID int64, replyTo int, text string, opts ...StatusOption) error
func (b *Bot) FinishStatus(ctx context.Context, chatID int64) error

// core/discord
func (b *Bot) SendStatus(ctx context.Context, channelID, replyTo, text string, opts ...StatusOption) error
func (b *Bot) FinishStatus(ctx context.Context, channelID string) error
```

## Options

| Option | Platform | Effect | Default |
|---|---|---|---|
| `WithStatusEmoji(emoji)` | Telegram, Discord | Reaction added to the `replyTo` message | `🤔` (also used when `emoji` is `""`) |
| `WithStatusSendType(t SendType)` | Telegram | Parse mode for the status text (`TypeMarkdown` = MarkdownV2, `TypeHTML`) | plain text |

The emoji and parse mode are captured by the first `SendStatus` call for that chat or channel; options passed later are ignored. `replyTo` is taken from the latest call until the status message has been created, then fixed. On Telegram the emoji must be one Telegram allows as a reaction; the library does not validate it.

## Update flow

| Step | Behavior |
|---|---|
| First flush | Adds the reaction to `replyTo` (failure is only logged), then sends the status text as a reply to `replyTo`. With `replyTo` zero / `""`, both the reaction and the reply link are skipped |
| Later calls | Edit the same message |
| Rate | At most one send or edit per second per chat/channel. A call inside that window stores the text and a timer flushes the latest text; intermediate texts are dropped |
| Same text | Skipped without an API call. Telegram's `message is not modified` error is also ignored |
| Return value | The send/edit error when the call flushed immediately; `nil` when the text was queued |

## Finish

`FinishStatus` stops the pending timer, removes the bot's reaction from `replyTo` (failure is only logged), and deletes the status message. It returns `nil` when there is no status for that chat or channel.

If a send or edit is in flight, `FinishStatus` waits for it and the cleanup runs right after it; it returns early with `ctx.Err()` if your `ctx` ends first. `Close()` stops all status timers without deleting messages.

## Example

```go
bot.Reply(func(ctx context.Context, in telegram.Input) string {
    bot.SendStatus(ctx, in.ChatID, in.MessageID, "Searching...")
    result := work(ctx)
    bot.SendStatus(ctx, in.ChatID, in.MessageID, "Writing answer...")
    bot.FinishStatus(ctx, in.ChatID)
    return result
})
```

## Related pages

- [Reply Handler](/reply-handler)
- [Telegram API](/api-reference-telegram), [Discord API](/api-reference-discord)
