# Reply Handler

This page explains when the `ReplyHandler` runs, where its return value is sent, and how panics are handled.

## Contract

```go
type ReplyHandler func(ctx context.Context, input Input) string
```

Each platform package declares this type with its own `Input`. `Reply(handler)` stores one handler; calling it again replaces the previous one. The SDK goroutine that received the event calls the handler and waits for it, so a slow handler delays that event's reply.

| Return value | Result |
|---|---|
| Non-empty string | Sent as a plain-text reply (see targets below) |
| `""` | Nothing is sent; use this when the handler sends media, interactive prompts, or several messages itself |

## What triggers the handler

| Platform | Events |
|---|---|
| Telegram | Every message update (text, caption, photo, document; groups included, no mention check); `SendSelect` button taps; `SendMultiSelect` **Done** taps |
| Discord | Every `MessageCreate` except the bot's own messages; `SendInput` modal submits; `SendSelect` / `SendMultiSelect` picks |
| LINE | Message events of type text, image, video, audio, and file (groups and rooms included, no mention check) |

Other event types are ignored.

## Where the reply goes

| Platform | Trigger | Reply target |
|---|---|---|
| Telegram | Message | Same chat, as a reply to the user's message |
| Telegram | Select / multi-select | Same chat, as a reply to the prompt message |
| Discord | Message | Same channel, as a reply to the user's message |
| Discord | Modal submit / select | Reply to the `replyTo` passed to `SendInput` / `SendSelect`; the prompt message when `replyTo` was `""` |
| LINE | Any | `ReplyMessage` with the event's one-time reply token |

## Handler context

| Platform | `ctx` passed to the handler |
|---|---|
| Telegram | Context supplied by the polling loop (derived from the `Start` context) |
| Discord | The bot's internal context created in `Start`; events received while not running are dropped |
| LINE | Per webhook request: the bot context with a 30-second timeout, shared by every event in that request |

## Panics

A panic inside the handler is recovered and logged with `slog.Warn("reply handler panic")`; the SDK goroutine keeps running.

| Platform | Panic value is a `string` | Any other panic value |
|---|---|---|
| Telegram | That string is sent as the reply | Nothing is sent |
| LINE | That string is sent as the reply | Nothing is sent |
| Discord | Nothing is sent | Nothing is sent |

## Related pages

- [Bot Lifecycle](/core-concepts)
- [Telegram Interactions](/telegram-interactions), [Discord Interactions](/discord-interactions)
- [LINE Messages](/line-messages)
