Core services

Introduction#

Foundation services: database access, Telegram I/O, notification orchestration, and the shared bits every runner and server leans on.

Project structure#

The application is organized into modular layers:

  • Core configuration and utilities
  • Clients for external systems (MongoDB, Telegram Bot API)
  • Services for business logic (database, notifications, web push, admin)
  • Runners for operational tasks (update and notification dispatch)
  • Servers for runtime (Telegram bot and scheduler)
  • CLI entry point for orchestration

Core components#

This section documents the three core services that underpin the application.

DatabaseService#

Responsibilities:

  • MongoDB connectivity and collection access via DBClient
  • Notice CRUD: existence checks, insertions, retrieval, and status reporting
  • Structured job upserts and retrieval
  • Placement offers merge logic with event emission for notifications
  • Official placement data deduplication and storage
  • User management: add/reactivate, deactivate, listing, and statistics
  • Policy management: upsert by year and retrieval
  • Utility helpers: serialization and statistics aggregation

It can:

  • Notice lifecycle: existence checks, insertion with timestamps, retrieval, and marking as sent
  • Job lifecycle: upsert with merge semantics and retrieval
  • Placement offers: merge roles and students, compute newly added students, emit events
  • User lifecycle: add/reactivate/deactivate and stats
  • Policy lifecycle: upsert by year and retrieval

Error handling:

  • Centralized safe printing and exception wrapping for robustness
  • Graceful fallbacks when collections are uninitialized

Persistence patterns:

  • Timestamp fields for auditability
  • Sent flags to coordinate delivery workflows
  • Content hashing for official placement data deduplication

TelegramService#

Responsibilities:

  • Telegram bot initialization via TelegramClient
  • Message sending to default channel, specific users, and broadcasting to all users
  • Message formatting: MarkdownV2 and HTML conversion with escaping
  • Long message splitting with chunking and retry logic
  • Connection testing and reliable retries with exponential backoff

It can:

  • Single and chunked message sending with parse modes
  • User-targeted messaging and bulk broadcasts
  • HTML and MarkdownV2 formatting with escaping and fallbacks
  • Rate-limit handling via Telegram API responses

Integration patterns:

  • Delegates to TelegramClient for HTTP requests
  • Uses DatabaseService for user lookups during broadcasts

NotificationService#

Responsibilities:

  • Aggregates multiple channels (Telegram, Web Push) behind a unified interface
  • Routes messages to enabled channels and coordinates broadcasts
  • Sends unsent notices to target channels and marks them as sent upon success
  • Orchestrates delivery workflows across channels

It can:

  • Channel registration and dynamic addition
  • Broadcast to all users per channel
  • Delivery coordination for unsent notices
  • Results aggregation per channel

Integration patterns:

  • Works with DatabaseService to fetch unsent notices
  • Accepts channel implementations that expose channel_name and broadcast_to_all_users/send_message

WebPushService#

Responsibilities:

  • Implements INotificationChannel for Web Push notifications
  • Uses VAPID for authentication and pywebpush for delivery
  • Manages subscriptions via DatabaseService and removes expired ones
  • Broadcasts to all users with push subscriptions

It can:

  • Conditional enablement based on VAPID configuration
  • Per-subscription push delivery with error handling
  • Subscription lifecycle management hooks

AdminTelegramService#

Responsibilities:

  • Administrative commands for the Telegram bot
  • User listing, targeted broadcasting, forced updates, logs viewing, and scheduler control
  • Admin authentication against configured chat ID

Integration patterns:

  • Uses DatabaseService for user and statistics queries
  • Uses TelegramService for message delivery
  • Interacts with scheduler daemon controls

Architecture overview#

The system follows a layered architecture :

  • Core configuration and logging
  • Clients for external APIs (MongoDB, Telegram Bot API)
  • Business services encapsulating domain logic
  • Runners for operational tasks
  • Servers for runtime exposure
  • CLI for orchestration

Detailed component analysis#

DatabaseService analysis#

DatabaseService encapsulates MongoDB operations and exposes a clean interface for notices, jobs, placement offers, users, and policies. It delegates collection access to DBClient and centralizes error handling and logging.

Key operations:

  • Notice CRUD: existence checks, insertions, retrieval, and marking as sent
  • Job upsert: merge semantics for existing jobs
  • Placement offers: merge roles and students, compute newly added students, emit events
  • User management: add/reactivate/deactivate and stats
  • Policy management: upsert by year and retrieval

Error handling:

  • Safe printing and exception wrapping
  • Graceful fallbacks when collections are uninitialized

TelegramService analysis#

TelegramService wraps Telegram messaging, delegating HTTP interactions to TelegramClient and handling formatting and rate limits.

Message flow:

  • Long messages are split into chunks and sent sequentially with delays
  • Formatting conversions support both MarkdownV2 and HTML with fallbacks
  • Rate-limit handling via Telegram API responses

NotificationService analysis#

NotificationService orchestrates delivery across multiple channels and coordinates with DatabaseService for unsent notices.

Delivery workflow:

  • Fetch unsent notices from DatabaseService
  • Broadcast to target channels (Telegram/Web Push)
  • Mark as sent upon successful delivery

WebPushService analysis#

WebPushService implements INotificationChannel for Web Push notifications using VAPID authentication.

AdminTelegramService analysis#

AdminTelegramService provides administrative commands for the Telegram bot, including user listing, broadcasting, forced updates, logs viewing, and scheduler control.

Dependency analysis#

The application uses dependency injection and factory functions to wire services together.

Service initialization patterns:

  • Factory functions create and wire services with configuration
  • NotificationRunner and UpdateRunner demonstrate dependency injection with optional overrides
  • BotServer and SchedulerServer instantiate services and configure scheduling

Performance considerations#

  • DatabaseService:
  • Existence checks and retrieval use indexed fields (IDs) to minimize overhead
  • Batch operations for placement offers with merge logic reduce redundant writes
  • Hashing for official placement data prevents duplicate inserts
  • TelegramService:
  • Long messages are split with newline-aware chunking to respect character limits
  • Rate-limit handling via Telegram API responses with exponential backoff
  • Broadcast loops include small delays to avoid rate limits
  • NotificationService:
  • Iterates through unsent notices and broadcasts per channel, marking as sent upon success
  • Results aggregated per channel for visibility
  • WebPushService:
  • Conditional enablement avoids unnecessary overhead when VAPID keys are missing
  • Error handling for expired subscriptions to keep subscription lists healthy

[No sources needed since this section provides general guidance]

Troubleshooting guide#

Common issues and resolutions:

  • MongoDB connection failures:
  • Verify MONGO_CONNECTION_STR environment variable and network connectivity
  • Check DBClient connection and ping response
  • Telegram bot configuration:
  • Ensure TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID are set
  • Use test_connection to validate bot token
  • Rate limiting:
  • Telegram API returns 429 with Retry-After header; service waits and retries
  • Adjust broadcast delays if still encountering limits
  • Web Push:
  • Confirm VAPID keys are configured; service disables itself if missing
  • Expired subscriptions are removed automatically on WebPushException with 404/410
  • Logging:
  • Use setup_logging to configure file and stream handlers
  • Enable verbose mode (-v) for debug-level logs

Conclusion#

Database, Telegram, notification orchestration, and the shared helpers runners and servers call. Keep I/O in clients and business rules in services.