handle-callback-query

star 247

Handles inline keyboard button presses and provides user feedback via answerCallbackQuery. Use when processing callback queries, answering button clicks, or updating messages after inline button interaction.

vendelieu By vendelieu schedule Updated 2/15/2026

name: handle-callback-query description: Handles inline keyboard button presses and provides user feedback via answerCallbackQuery. Use when processing callback queries, answering button clicks, or updating messages after inline button interaction.

Handle Callback Query

Quick Start

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

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:

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

With options:

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":

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):

@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

Install via CLI
npx skills add https://github.com/vendelieu/telegram-bot --skill handle-callback-query
Repository Details
star Stars 247
call_split Forks 17
navigation Branch main
article Path SKILL.md
More from Creator