# Vendelieu Telegram Bot Handle Callback Query

> Handle Callback Query

- Skill: `tomevault-io/vendelieu-telegram-bot-handle-callback-query` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/vendelieu-telegram-bot-handle-callback-query`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/vendelieu-telegram-bot-handle-callback-query/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/vendelieu-telegram-bot-handle-callback-query

---


# Handle Callback Query

## Quick Start

Register a handler and **always** answer the callback query to stop the loading state:

```kotlin
bot.setFunctionality {
    onCallbackQuery {
        val cq = update.callbackQuery
        answerCallbackQuery(cq.id).options { text = "Done!" }.send(user, bot)
        when (cq.data) {
            "yes" -> message("You said yes!").send(user, bot)
            "no" -> message("You said no.").send(user, bot)
        }
    }
}
```

## Handler Registration

- **DSL**: `onCallbackQuery { }` — typed `ActivityCtx<CallbackQueryUpdate>`
- **Annotation**: `@CommandHandler.CallbackQuery(["prefix"])` with optional `autoAnswer = true`

## Accessing Callback Data

- `update.callbackQuery` — the CallbackQuery
- `callbackQuery.id` — required for answerCallbackQuery
- `callbackQuery.data` — button data (1-64 bytes), may be null
- `callbackQuery.from` — user who pressed
- `callbackQuery.message` — message with the button (if any)

## Answering the Query

**Always call** `answerCallbackQuery` to remove the loading state:

```kotlin
answerCallbackQuery(callbackQuery.id).send(user, bot)
```

With options:

```kotlin
answerCallbackQuery(callbackQuery.id).options {
    text = "Saved!"           // Notification text (0-200 chars)
    showAlert = true         // Alert instead of top notification
    url = "https://..."      // URL to open (e.g. t.me/bot?start=xxx)
    cacheTime = 60           // Cache result (seconds)
}.send(user, bot)
```

## Parsing Callback Data

Use prefixes for routing: `"action:id"`, `"vote:123"`:

```kotlin
cq.data?.split(":", limit = 2)?.let { (action, id) ->
    when (action) {
        "vote" -> handleVote(id.toLong())
        "page" -> showPage(id.toInt())
    }
}
```

## @ParamMapping

Maps handler parameters to keys in the parsed parameters map. Use with `@CommandHandler.CallbackQuery` when the ArgumentParser extracts named values from callback data (e.g. `page=1`, `id=123`):

```kotlin
@CommandHandler.CallbackQuery(["vote"], autoAnswer = true)
suspend fun handleVote(
    @ParamMapping("id") itemId: Long,
    user: User,
    bot: TelegramBot
) {
    message("Voted for $itemId").send(user, bot)
}
```

- `@ParamMapping("name")` — parameter is resolved from `parameters["name"]` (parsed by ArgumentParser)
- Supported types: String, Int, Long, Short, Float, Double
- Use when callback data exceeds simple routing and you need typed parameters

## Updating the Message

After handling, optionally edit the message or its markup:

- `editMessageText` — change text
- `editMessageReplyMarkup` — change/remove buttons

## Reference

- [AnswerCallbackQuery.kt](telegram-bot/src/commonMain/kotlin/eu/vendeli/tgbot/api/answer/AnswerCallbackQuery.kt)
- [CallbackQuery.kt](telegram-bot/src/commonMain/kotlin/eu/vendeli/tgbot/types/common/CallbackQuery.kt)
- [ParamMapping.kt](telegram-bot/src/commonMain/kotlin/eu/vendeli/tgbot/annotations/ParamMapping.kt)
- [FunctionalDSLUtils.kt](telegram-bot/src/commonMain/kotlin/eu/vendeli/tgbot/utils/common/FunctionalDSLUtils.kt)

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/vendelieu) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-11 -->

