A real-time team activity monitoring system built on RabbitMQ and two Telegram bots.
Instead of a simple "send one message → receive one message" flow, this system implements aggregated team activity monitoring:
- Bot #1 (Reporter) — each team member reports their current status via a command
- Bot #2 (Dashboard) — reads all pending statuses from the queue every minute and posts a summarized "Office Pulse" digest to a group chat
[Employee] → /working → [Bot #1] → [RabbitMQ Queue] → [Bot #2] → [Group Chat]
rabbitmq-bots/
├── docker-compose.yml # RabbitMQ + both bots in a shared network
├── .env.example # Environment variables template
├── bot1-reporter/
│ ├── Dockerfile
│ ├── requirements.txt
│ └── bot.py # Producer: accepts commands, writes to queue
└── bot2-dashboard/
├── Dockerfile
├── requirements.txt
└── bot.py # Consumer: drains queue, sends digest
| Component | Technology |
|---|---|
| Message broker | RabbitMQ 3.13 (with Management UI) |
| Containerization | Docker + Docker Compose |
| Language | Python 3.12 |
| Telegram SDK | python-telegram-bot 21.5 |
| AMQP client | pika 1.3.2 |
- Open @BotFather
/newbot→ get BOT1_TOKEN (Reporter)/newbot→ get BOT2_TOKEN (Dashboard)- Get the target group
chat_idvia @userinfobot
cp .env.example .envBOT1_TOKEN=1234567890:AAF... # reporter bot token
BOT2_TOKEN=0987654321:AAG... # dashboard bot token
DASHBOARD_CHAT_ID=-1001234567890 # group chat id
# RabbitMQ (keep as-is when using docker-compose)
RABBITMQ_HOST=rabbitmq
RABBITMQ_PORT=5672
RABBITMQ_USER=admin
RABBITMQ_PASS=admin123
RABBITMQ_QUEUE=office_pulse
# Queue polling interval in seconds (default: 60)
CHECK_INTERVAL=60docker compose up --build -dCheck container status:
docker compose psLive logs:
docker compose logs -f bot1-reporter
docker compose logs -f bot2-dashboardStop everything:
docker compose downOnce running, open in your browser:
http://localhost:15672
| Field | Value |
|---|---|
| Login | admin |
| Password | admin123 |
Go to Queues → office_pulse to see pending messages in real time.
Accepts status updates from employees in a private chat.
| Command | Status | Emoji |
|---|---|---|
/working |
Starting work | 💼 |
/meeting |
Going to a meeting | 🤝 |
/break |
Taking a break | ☕ |
/done |
Finishing work | ✅ |
/status <text> |
Custom status | 📢 |
Commands accept an optional note:
/working refactoring the auth module
/meeting with the client about UI design
{
"user_id": 123456789,
"username": "john_doe",
"full_name": "John Doe",
"action": "working",
"emoji": "💼",
"label": "Starting work",
"note": "refactoring the auth module",
"ts": "2025-01-21T09:00:00+00:00"
}Messages are published with delivery_mode=2 (persistent) — they survive a RabbitMQ restart.
Posts aggregated digests to a group chat.
Poll schedule:
- Immediately on startup
- Then every
CHECK_INTERVALseconds (default: 60)
📊 Office Pulse | 21.01 09:15
────────────────────────────
New statuses: 4
💼 John Doe — Starting work [09:00]
└ refactoring the auth module
🤝 Jane Smith — Going to a meeting [09:05]
☕ Bob — Taking a break [09:10]
✅ Alice — Finishing work [09:12]
────────────────────────────
👥 1 working, 1 in meeting, 1 on break, 1 done
When the queue is empty:
📭 Office Pulse
─────────────────
Queue is empty — no new statuses.
# 1. Start the system
docker compose up --build -d
# 2. Send a command to Bot #1 in Telegram:
/working building a new feature
# 3. Check the queue in Management UI:
# http://localhost:15672 → Queues → office_pulse → Ready: 1
# 4. Wait up to a minute, or restart bot2 for an immediate check:
docker compose restart bot2-dashboard
# 5. The group chat will receive a digest from Bot #2By default Bot #2 checks the queue every minute. Change it in .env:
CHECK_INTERVAL=30 # every 30 seconds
CHECK_INTERVAL=900 # every 15 minutes- Docker ≥ 24
- Docker Compose plugin (included in Docker Desktop)
- Two Telegram bots created via @BotFather