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:
| Type | Description |
|---|---|
@BotDynamicCallbackQuery | Routes a handler method by payload type |
BotDynamicCallbackData | Immutable payload model: String type + Map<String,Object> data |
BotDynamicCallbackQueryService | SPI 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
| Change | Type | Action required |
|---|---|---|
@BotDynamicCallbackQuery annotation | New feature | None (opt-in) |
BotDynamicCallbackData model | New feature | None (opt-in) |
BotDynamicCallbackQueryService SPI | New feature | None (default impl auto-registered) |
BotKeyboardFactory.dynamicInlineButton() | New feature | None (opt-in) |
BotKeyboardFactory.InlineKeyboardBuilder.dynamicRow() | New feature | None (opt-in) |
BotKeyboardFactory constructor changed | API addition | Update custom beans that extend the factory |