Skip to main content
Version: 0.0.6

Migrating from 0.0.3 to 0.0.4

Overview

Version 0.0.4 introduces Dynamic Callback Queries — a first-class pattern for routing Telegram inline button callbacks through server-side payloads. This release contains no breaking changes; all existing code compiles and runs without modification.


New Features

Dynamic Callback Queries — @BotDynamicCallbackQuery

Telegram limits inline button callback data to 64 bytes. The new dynamic callback query system lets you store rich structured payloads server-side and reference them by a UUID key placed in the button's callbackData.

New types in core-api:

TypeDescription
@BotDynamicCallbackQueryRoutes a handler method by payload type
BotDynamicCallbackDataImmutable payload model: String type + Map<String,Object> data
BotDynamicCallbackQueryServiceSPI for storing and resolving payloads

Example — handler:

@BotDynamicCallbackQuery("product_buy")
public String onBuy(BotDynamicCallbackData data) {
Long id = (Long) data.getData().get("id");
return "Bought product #" + id + "!";
}

Example — building the button:

InlineKeyboardMarkup keyboard = keyboardFactory.inline(request)
.dynamicRow("btn.buy",
BotDynamicCallbackData.builder()
.type("product_buy")
.put("id", productId)
.build())
.build();

See the full guide: Dynamic Callback Queries.


BotKeyboardFactory — dynamic button helpers (core-i18n)

Two new overloads generate a UUID key, store the payload, and return a button automatically:

// Direct helper
InlineKeyboardButton btn = keyboardFactory.dynamicInlineButton("btn.buy", payload, request);

// Fluent builder
keyboardFactory.inline(request)
.dynamicRow("btn.buy", payload)
.dynamicRow(
BotKeyboardFactory.entry("btn.view", viewPayload),
BotKeyboardFactory.entry("btn.cancel", cancelPayload))
.build();

No action required unless you supply a custom BotKeyboardFactory bean — in that case update your constructor to accept BotDynamicCallbackQueryService (see below).


Default in-memory service

An InMemoryBotDynamicCallbackQueryService bean is registered automatically and is replaceable via @ConditionalOnMissingBean. To swap in a Redis or database-backed store:

@Bean
public BotDynamicCallbackQueryService myDynamicCallbackService() {
return new MyRedisDynamicCallbackService(redisTemplate);
}

Action required for custom BotKeyboardFactory beans

If you declared a custom BotKeyboardFactory bean that extends the default one, update its constructor to pass BotDynamicCallbackQueryService:

Before (0.0.3):

@Bean
public BotKeyboardFactory botKeyboardFactory(BotMessageSource messageSource) {
return new BotKeyboardFactory(messageSource);
}

After (0.0.4):

@Bean
public BotKeyboardFactory botKeyboardFactory(BotMessageSource messageSource,
Optional<BotDynamicCallbackQueryService> dynamicService) {
return new BotKeyboardFactory(messageSource, dynamicService.orElse(null));
}

If you do not use dynamicInlineButton or dynamicRow, passing null is safe.


Summary table

ChangeTypeAction required
@BotDynamicCallbackQuery annotationNew featureNone (opt-in)
BotDynamicCallbackData modelNew featureNone (opt-in)
BotDynamicCallbackQueryService SPINew featureNone (default impl auto-registered)
BotKeyboardFactory.dynamicInlineButton()New featureNone (opt-in)
BotKeyboardFactory.InlineKeyboardBuilder.dynamicRow()New featureNone (opt-in)
BotKeyboardFactory constructor changedAPI additionUpdate custom beans that extend the factory