Zero Boilerplate
One dependency, one property. Annotation-driven routing eliminates manual update polling loops and dispatcher wiring. See the Quick Start guide.
Pluggable Transports
Switch between long-polling, webhook, Kafka consumer, or RabbitMQ consumer with a single configuration property — no code changes required. See Transports.
Declarative Routing
Route by command, text, regex pattern, callback query, contact, or location. Parameters such as User, Chat, and custom domain objects are resolved and injected automatically. See Handlers.
Stateful Conversations
Build multi-step registration flows and wizards with @BotChatState and @BotForwardChatState. Backed by an in-memory store by default; replace with Redis or a database without modifying handlers. See Chat State.
Fully Extensible
Every bean uses @ConditionalOnMissingBean. Override filters, argument resolvers, return-type handlers, state services, and more by registering your own @Bean. See Custom Filters.
Production Ready
Internationalization, @BotControllerAdvice exception handling, a prioritized filter pipeline, Micrometer observability, and broker publishing to Kafka or RabbitMQ. See Observability.
Why Easygram?
- Minimal Setup — One dependency, one property, and you're running
- Annotation-Driven — Declarative routing with
@BotCommand,@BotText,@BotTextPattern, and more - Type-Safe Injection — Parameters resolved at startup with compile-time checking
- Stateful Flows — Multi-step wizards with built-in chat state management
- Pluggable — Swap transports, backends, and services without changing handlers
- Observable — Micrometer metrics, distributed tracing, and health indicators built in
@BotController
public class MyBot {
@BotCommand("/start")
public String onStart(User user) {
return "Hello, " + user.getFirstName();
}
@BotTextPattern("\\d+")
@BotChatState("WAITING_AGE")
@BotForwardChatState("DONE")
public String onAge(@BotTextValue String age) {
return "Got it. You are " + age + " years old.";
}
@BotDefaultHandler
public String fallback() {
return "I did not understand that.";
}
}