Skip to main content
Version: 0.0.6

Migrating from 0.0.4 to 0.0.5

Overview

Version 0.0.5 is a framework-quality release focused on four improvements:

  1. Property namespace renametelegram.bot.*easygram.* with IDE autocomplete support
  2. Module consolidation — six fragmented messaging modules merged into one messaging-api
  3. MDC tracing infrastructure — automatic bot.update.id, bot.chat.id, bot.user.id in every log line
  4. Structured logging — TRACE/DEBUG/INFO/WARN across the entire processing pipeline

Breaking Change 1 — Property Namespace Rename

All configuration properties have been renamed from telegram.bot.* to easygram.*.

Quick migration

Find and replace in your application.yml / application.properties:

Old prefixNew prefix
telegram.bot.tokeneasygram.token
telegram.bot.transporteasygram.update.transport
telegram.bot.webhook.*easygram.update.webhook.*
telegram.bot.i18n.*easygram.i18n.*
telegram.bot.messaging.*easygram.messaging.*
telegram.bot.kafka-consumer.*easygram.messaging.kafka.* + easygram.messaging.type: CONSUMER
telegram.bot.rabbit-consumer.*easygram.messaging.rabbit.* + easygram.messaging.type: CONSUMER

Before (0.0.4):

telegram:
bot:
token: ${BOT_TOKEN}
transport: LONG_POLLING

After (0.0.5):

easygram:
token: ${BOT_TOKEN}
# easygram.update.transport defaults to LONG_POLLING — omit block for long-polling bots
update:
transport: LONG_POLLING

Default values renamed

Old defaultNew default
telegram-updates (topic/queue)easygram-updates
telegram-exchange (exchange)easygram-exchange
telegram.updates (routing key)easygram.updates

Observability metric/span rename

Old nameNew name
telegram.bot.update (timer + span)easygram.update

Update any Grafana dashboards or alerting rules that reference the old metric name.

IDE autocomplete

spring-boot-configuration-processor is now included in core, webhook, messaging-api, and core-i18n. Your IDE will auto-suggest all easygram.* property keys.


Breaking Change 2 — Messaging Module Consolidation

Six messaging modules have been removed and merged into the existing messaging-api module.

Dependencies to remove

<!-- REMOVE all of these -->
<dependency>
<groupId>uz.osoncode.easygram</groupId>
<artifactId>messaging-kafka</artifactId>
</dependency>
<dependency>
<groupId>uz.osoncode.easygram</groupId>
<artifactId>messaging-rabbit</artifactId>
</dependency>
<dependency>
<groupId>uz.osoncode.easygram</groupId>
<artifactId>messaging-producer</artifactId>
</dependency>
<dependency>
<groupId>uz.osoncode.easygram</groupId>
<artifactId>messaging-consumer</artifactId>
</dependency>
<dependency>
<groupId>uz.osoncode.easygram</groupId>
<artifactId>messaging-kafka-consumer</artifactId>
</dependency>
<dependency>
<groupId>uz.osoncode.easygram</groupId>
<artifactId>messaging-rabbit-consumer</artifactId>
</dependency>

Replace with single dependency

<!-- ADD this single replacement -->
<dependency>
<groupId>uz.osoncode.easygram</groupId>
<artifactId>messaging-api</artifactId>
<version>0.0.5</version>
</dependency>

Or just use the starter (already includes messaging-api):

<dependency>
<groupId>uz.osoncode.easygram</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>0.0.5</version>
</dependency>

Package names — no change required

All class package names are unchanged. No import statements need to be updated:

PackageStatus
uz.osoncode.easygram.messaging.*✅ Unchanged
uz.osoncode.easygram.messaging.kafka.*✅ Unchanged
uz.osoncode.easygram.messaging.rabbit.*✅ Unchanged
uz.osoncode.easygram.messaging.producer.*✅ Unchanged
uz.osoncode.easygram.messaging.consumer.*✅ Unchanged

Breaking Change 3 — BotFilterOrder Constants Shifted

BotFilterOrder now has a new MDC_CONTEXT constant at the absolute lowest priority (Integer.MIN_VALUE). All existing constants have shifted up by 1.

Constant0.0.4 value0.0.5 value
MDC_CONTEXT(did not exist)Integer.MIN_VALUE
CONTEXT_SETTERInteger.MIN_VALUEInteger.MIN_VALUE + 1
OBSERVATIONInteger.MIN_VALUE + 1Integer.MIN_VALUE + 2
API_SENDERInteger.MIN_VALUE + 2Integer.MIN_VALUE + 3

Impact: Only affects you if you wrote a custom BotFilter with a hardcoded integer value equal to one of the old constants (Integer.MIN_VALUE, MIN_VALUE + 1, or MIN_VALUE + 2).

Fix: Use the named constants instead of hardcoded integers:

// Before (fragile hardcoded value)
@Override
public int getOrder() {
return Integer.MIN_VALUE + 1; // used to mean "just after context setter"
}

// After (correct — references the named constant)
@Override
public int getOrder() {
return BotFilterOrder.CONTEXT_SETTER + 10;
}

New Feature — MDC Correlation Context

BotMdcFilter is now automatically registered as the first filter in the chain (order Integer.MIN_VALUE). Every log line emitted by framework code or your own @BotController / BotFilter beans automatically includes:

MDC KeyExample value
bot.update.id12345678
bot.transportLONG_POLLING
bot.chat.id987654321
bot.user.id111222333

No code changes required. To surface these fields in log output, update your Logback pattern:

<!-- logback-spring.xml -->
<pattern>%d{HH:mm:ss.SSS} %-5level [upd:%X{bot.update.id}] [chat:%X{bot.chat.id}] %logger{36} - %msg%n</pattern>

See Observability → MDC Correlation Context for the full reference.


New Feature — Structured Pipeline Logging

Every stage of the update processing pipeline now emits structured logs at appropriate levels. Enable them per environment:

# Production (startup events only)
logging:
level:
uz.osoncode.easygram: INFO

# Debugging handler matching / state transitions
logging:
level:
uz.osoncode.easygram: DEBUG

# Deep debugging argument resolution and method invocation
logging:
level:
uz.osoncode.easygram: TRACE

New Feature — AnswerCallbackQuery on PlainTextTemplate and LocalizedTemplate

PlainTextTemplate and LocalizedTemplate now support the same callback-answer API that PlainReply and LocalizedReply have had since 0.0.5. The resolved template text (after all #{index} substitutions and ${key} bundle lookups) is used as the popup notification.

// PlainTextTemplate — toast popup
@BotCallbackQuery("next")
public PlainTextTemplate onNext(User user) {
return PlainTextTemplate.of("Step #{0} complete, #{1}!", step, user.getFirstName())
.asAnswerCallbackQuery();
}

// LocalizedTemplate — alert dialog
@BotCallbackQuery("confirm")
public LocalizedTemplate onConfirm() {
return LocalizedTemplate.of("${action.confirmed}")
.asAnswerCallbackQuery()
.withCallbackAlert();
}

// Builder
PlainTextTemplate.builder()
.template("Order #{0} confirmed!")
.args(orderId)
.answerCallbackQuery(true)
.callbackAlert(true)
.callbackCacheTime(10)
.build();

No code changes required unless you previously worked around the limitation by returning Collection<Object> with a separate AnswerCallbackQuery element.


New Feature — Markup Support in @BotExceptionHandler

@BotExceptionHandler methods now participate in the full markup pipeline:

  • @BotReplyMarkup("id") on the method — attaches a registered keyboard to the error response.
  • @BotClearMarkup on the method — sends ReplyKeyboardRemove.
  • State-bound keyboards — if a keyboard is registered for a state and the current chat is in that state, it is automatically attached.
  • MarkupAware fluent API — returning PlainReply.of("…").withMarkup("id") or .withKeyboard(keyboard) from an exception handler works as expected.
// @BotReplyMarkup on an exception handler
@BotReplyMarkup("error_kb")
@BotExceptionHandler(Exception.class)
public String handleGeneric(Exception e) {
return "An error occurred.";
}

// Rich return type with markup
@BotExceptionHandler(ValidationException.class)
public PlainReply handleValidation(ValidationException e) {
return PlainReply.of("Invalid: " + e.getMessage()).withMarkup("retry_kb");
}

No code changes required — this is purely additive. Exception handlers that do not use markup annotations or MarkupAware return types are unaffected.


Summary Table

ChangeTypeAction required
telegram.bot.*easygram.* property renameBreakingFind/replace in YAML/properties files
Default values renamed (telegram-updateseasygram-updates, etc.)BreakingUpdate broker configs if you overrode defaults
telegram.bot.update metric → easygram.updateBreakingUpdate Grafana dashboards and alerts
6 messaging modules removedBreakingReplace deps with single messaging-api
BotFilterOrder.CONTEXT_SETTER value changedBreakingUse named constant, not hardcoded Integer.MIN_VALUE
BotFilterOrder.OBSERVATION value changedBreakingUse named constant, not hardcoded Integer.MIN_VALUE + 1
BotFilterOrder.API_SENDER value changedBreakingUse named constant, not hardcoded Integer.MIN_VALUE + 2
BotFilterOrder.MDC_CONTEXT addedNew constantNone (opt-in)
BotMdcFilter registered automaticallyNew featureUpdate Logback pattern to surface MDC keys
IDE autocomplete for all easygram.* propertiesNew featureNone — works automatically
Pipeline TRACE/DEBUG/INFO/WARN loggingNew featureConfigure log level per environment
PlainTextTemplate / LocalizedTemplate callback-answer APINew featureNone — additive
@BotReplyMarkup / state keyboards in @BotExceptionHandlerNew featureNone — additive