Contributing to Easygram
Thank you for your interest in contributing! This guide covers everything you need to get started.
Prerequisites
| Tool | Minimum Version |
|---|---|
| Java | 17 |
| Maven | 3.8+ |
| Git | any recent version |
Getting the Code
# Fork the repo on GitHub, then clone your fork
git clone https://github.com/<your-username>/easygram.git
cd easygram
# Add the upstream remote
git remote add upstream https://github.com/oson-code/easygram.git
Building the Project
# Full build (compiles all modules, runs tests)
mvn install
# Skip tests for a faster build during development
mvn install -DskipTests
# Build a specific module
mvn install -pl core-api -am
Project Structure
easygram/
├── core-api/ # Public API: annotations, reply types, interfaces
├── core/ # Core implementation: dispatcher, filters, auto-config
├── core-i18n/ # i18n support: LocalizedReply, LocalizedTemplate
├── core-chatstate/ # Chat state persistence interfaces
├── core-observability/ # Micrometer metrics and actuator endpoint
├── longpolling/ # Long-polling transport
├── webhook/ # Webhook transport
├── messaging-api/ # Messaging abstraction (BotUpdatePublisher)
├── messaging-producer/ # Producer type selection auto-config
├── messaging-consumer/ # Consumer type selection auto-config
├── messaging-kafka/ # Kafka publisher implementation
├── messaging-kafka-consumer/ # Kafka consumer transport
├── messaging-rabbit/ # RabbitMQ publisher implementation
├── messaging-rabbit-consumer/ # RabbitMQ consumer transport
├── spring-boot-starter/ # Aggregator starter (includes all transports)
└── samples/ # Example bots
Dependency direction: core-api has no framework dependencies. Everything else depends on core-api. core depends on core-api. Transport/messaging modules depend on core.
Running the Samples
cd samples/<sample-name>
export BOT_TOKEN="your_telegram_bot_token"
mvn spring-boot:run
Code Style
- Java 17 — use records, sealed classes, text blocks where appropriate
- Lombok — use
@Slf4j,@RequiredArgsConstructor, etc. Avoid@Dataon mutable types - Immutability — reply types are immutable; wither methods (
withMarkup, etc.) return new instances - Builder pattern — public API types expose a static inner
Builderclass with abuilder()factory andbuild()terminal method - Template tokens — use
#{0},#{1}, ... (0-based) for positional substitution inPlainTextTemplateandLocalizedTemplate - Javadoc — all public types and methods must have Javadoc; include
@sincewith the version introduced - No wildcard imports — configure your IDE to expand them
Reporting Bugs
- Search existing issues first
- Open a new issue with the Bug label
- Include:
- Easygram version
- Java and Spring Boot versions
- Minimal reproducer
- Expected vs actual behaviour
- Full stack trace if applicable
Requesting Features
- Search existing issues for similar requests
- Open a new issue with the Enhancement label
- Describe the use case and why it cannot be solved with existing APIs
Submitting a Pull Request
-
Create a branch from
main:git checkout -b feature/my-feature -
Make your changes — keep them focused on a single concern
-
Build and verify:
mvn install -
Commit following the conventions below
-
Push and open a PR against
main:git push origin feature/my-feature -
In your PR description, explain what changed, reference any related issue (
Fixes #123), and list breaking changes.
Commit Message Conventions
Use Conventional Commits format:
<type>(<scope>): <short summary>
| Type | When to use |
|---|---|
feat | New feature |
fix | Bug fix |
docs | Documentation only |
refactor | Code change that is neither a fix nor a feature |
test | Adding or updating tests |
chore | Build, CI, or tooling changes |
Examples:
feat(core-api): add builder pattern to PlainReply
fix(webhook): validate secret-token header before deserialization
docs(transports): add jprq local testing guide to webhook-guide
License
By contributing you agree that your contributions will be licensed under the MIT License.