# Telegram Interactions

This page covers free-text input, single select, and multi select prompts in `core/telegram`, and how each answer reaches your `Reply` handler.

All three methods take `(ctx, chatID int64, replyTo int, text string, ...)`, return the prompt `*models.Message`, reject an empty `text` with `text is required`, and accept `WithSendType` for the prompt's parse mode. `replyTo > 0` attaches the prompt as a reply to that message.

## Free-text input: SendInput

```go
prompt, err := bot.SendInput(ctx, in.ChatID, in.MessageID, "What is your name?")
```

The prompt carries `ForceReply`, so the user's client opens the keyboard in reply mode. The answer arrives as an ordinary message update: `in.Text` holds the answer, and `in.Raw.Message.ReplyToMessage.ID` equals `prompt.ID`. The library keeps no state for input prompts; matching the answer to the prompt is up to your handler.

## Single select: SendSelect

```go
prompt, err := bot.SendSelect(ctx, in.ChatID, in.MessageID, "Pick a color", []string{"Red", "Green", "Blue"})
```

| Step | Behavior |
|---|---|
| Send | One inline button per non-empty item, one per row; the button text and callback data are both the item. At least one non-empty item is required |
| Tap | The library answers the callback query, clears the keyboard from the prompt, then calls `Reply` with `CallbackData` = the item and `MessageID` = the prompt ID |

Telegram limits callback data to 64 bytes, so longer items are rejected by Telegram when the prompt is sent.

## Multi select: SendMultiSelect

```go
prompt, err := bot.SendMultiSelect(ctx, in.ChatID, in.MessageID, "Pick toppings", []string{"Cheese", "Ham", "Olive"})
```

| Step | Behavior |
|---|---|
| Send | One toggle button per non-empty item (`⬜ item`), plus a final **Done** button. The item `__bot_multiselect_done__` is reserved and returns an error |
| Toggle | The library flips the item and redraws the keyboard (`✅ item`). The handler is **not** called. Redraws are limited to one per second per prompt; rapid taps collapse into one edit |
| Done | The library clears the keyboard and calls `Reply` once with `CallbackPicks` = the selected items in their original order (empty when nothing is selected) and `MessageID` = the prompt ID |

State for a multi-select prompt lives in memory keyed by chat and prompt ID. It is dropped 5 minutes after **Done**, or on `Close()`. Taps after **Done** are ignored.

## Cleaning up a prompt

The select keyboards are removed automatically, but the prompt text stays. To remove it, call `bot.Delete(ctx, chatID, prompt.ID)`, then `Send` a summary as a reply to the original message if you want one.

## Related pages

- [Reply Handler](/reply-handler)
- [Telegram Setup](/telegram) (`Input` fields)
- [Discord Interactions](/discord-interactions) (the Discord equivalents)
