Robbi is a Telegram bot that monitors a Massa blockchain node, tracks balance history, and provides crypto price data and system stats.
- Massa node monitoring — Periodically checks node status every 60 minutes and alerts when the node goes down
- Balance history — Persisted to JSON file (
config/balance_history.json), survives Docker restarts. Records balance, CPU temperature, and RAM usage per snapshot - Scheduled reports — Automatic status reports at 7 AM, 12 PM, and 9 PM with 24h balance change, average temperature, and history data
- Crypto price tracking — Real-time Bitcoin (API-Ninjas) and Massa/USDT (MEXC) prices
- System monitoring — Per-core CPU usage, RAM, and per-sensor temperature details
- Node performance — RPC latency measurement and uptime percentage (last 24h)
- Docker management — Start/stop the Massa node container, execute Massa client commands (wallet_info, buy_rolls, sell_rolls), and support bot-container restart helpers via the Docker SDK (socket-based, no CLI needed)
- User authentication — All commands restricted to whitelisted user via
auth_requireddecorator - Interactive confirmations — Inline keyboard buttons for operations (
/flush,/hist,/docker)
src/
├── main.py # Entry point: config, bot_data setup, handler registration
├── config.py # Constants, conversation states, logging config, command list
├── jrequests.py # Backward-compatibility facade (re-exports from services/)
├── Dockerfile
├── entrypoint.sh
├── handlers/
│ ├── common.py # auth_required decorator, handle_api_error helper
│ ├── node.py # /node, /flush, /hist, /docker commands
│ ├── price.py # /btc, /mas commands
│ ├── system.py # /hi, /temperature, /perf commands
│ └── scheduler.py # Periodic node ping (APScheduler, every 60 min)
├── services/
│ ├── docker_manager.py # Docker SDK wrapper (start/stop/restart, exec massa-client)
│ ├── history.py # Balance history load/save/filter (JSON persistence)
│ ├── http_client.py # Safe HTTP request wrapper with retry logic
│ ├── massa_rpc.py # Massa blockchain JSON-RPC calls
│ ├── plotting.py # Chart generation (matplotlib) — validation, resources, balance
│ ├── price_api.py # External price API wrappers (API-Ninjas, MEXC)
│ └── system_monitor.py # System stats via psutil (CPU, RAM, temperatures)
└── media/ # Images used in bot responses
tests/ # pytest test suite (unit tests for all modules)
topology_template.json # Configuration template — copy to topology.json and fill in values
Shared state (allowed_user_ids, massa_node_address, ninja_key, balance_history, node_container_name, robbi_container_name, etc.) is stored in application.bot_data and accessed via context.bot_data in handlers — no global variables. A threading lock protects concurrent history updates.
A topology_template.json file is provided at the repository root. Copy it to topology.json and fill in your values:
cp topology_template.json topology.jsonThe topology.json file provides all configuration:
{
"telegram_bot_token": "YOUR_API_KEY",
"user_white_list": {
"admin": "YOUR_USER_ID"
},
"massa_node_address": "YOUR_MASSA_ADDRESS",
"ninja_api_key": "YOUR_NINJA_API_KEY",
"node_container_name": "massa-container",
"robbi_container_name": "robbi-container",
"massa_client_password": "YOUR_MASSA_CLIENT_PASSWORD",
"massa_wallet_address": "YOUR_MASSA_WALLET_ADDRESS",
"massa_buy_rolls_fee": 0.01
}| Key | Description |
|---|---|
telegram_bot_token |
Telegram bot token from BotFather |
user_white_list.admin |
Telegram user ID authorized to use the bot |
massa_node_address |
Massa wallet address for node monitoring |
ninja_api_key |
API-Ninjas key for Bitcoin price |
node_container_name |
Name of the Docker container running the Massa node (default: massa-container) |
robbi_container_name |
Name of the Docker container running Robbi itself (default: robbi-container) |
massa_client_password |
Password for ./massa-client -p |
massa_wallet_address |
Wallet address used for buy_rolls / sell_rolls commands |
massa_buy_rolls_fee |
Fee for buy/sell rolls transactions (default: 0.01) |
All commands require authentication via topology.json whitelist.
| Command | Description |
|---|---|
/hi |
Greeting with a custom image and current git commit hash |
/node |
Node status: balance, roll count, OK/NOK counts, active rolls + validation chart |
/btc |
Bitcoin price: USD price, 24h change, high/low, volume |
/mas |
Massa/USDT price from MEXC: price, change, high/low, volume |
/temperature |
System stats: per-sensor temperatures, per-core CPU usage, RAM |
/perf |
Node performance: RPC latency and uptime percentage (last 24h) |
/hist |
Balance history chart (balance, temperature, RAM) + optional text summary |
/flush |
Clear logs with confirmation dialog (option to also clear balance history) |
/docker |
Docker management menu (see below) |
The /docker command opens a multi-level interactive menu:
🐳 Docker Node Management
├── ▶️ Start → Confirmation → Start the node container
├── ⏹️ Stop → Confirmation → Stop the node container
├── 🔁 Restart Bot → Confirmation → Send "Ok" → Wait 1s → Restart the Robbi bot container
└── 💻 Massa Client
├── 💰 Wallet Info → Execute wallet_info
├── 🎲 Buy Rolls → Input roll count → Confirmation → Execute buy_rolls
├── 💸 Sell Rolls → Input roll count → Confirmation → Execute sell_rolls
└── ⬅️ Back → Return to main menu
Note: Docker commands use the Python Docker SDK which communicates directly via the Docker socket. The bot container does not need the
dockerCLI installed — only the socket mount:volumes: - /var/run/docker.sock:/var/run/docker.sock
- Python 3.12+
- A Telegram bot created via BotFather
- A Massa node with accessible JSON-RPC API
- API keys:
- API-Ninjas — Bitcoin price
- MEXC — Massa price
pip install -r requirements.txtKey packages: python-telegram-bot, requests, matplotlib, apscheduler, psutil, tzlocal, docker
cp topology_template.json src/topology.json # or place topology.json in the working directory
cd src
python main.pyThe Dockerfile (located in src/) clones the repository from GitHub and expects topology.json to be present in the src/ build context:
At container startup, entrypoint.sh attempts git pull origin main before launching python src/main.py.
If the pull fails (network/auth), the bot still starts with the local code already present in the image.
cp topology_template.json src/topology.json
docker build -t robbi ./src
docker run -d \
-v ./docker-volumes/robbi:/app/config \
-v /var/run/docker.sock:/var/run/docker.sock \
robbiOr with docker-compose, mount volumes for balance history persistence and Docker access:
volumes:
- ./docker-volumes/robbi:/app/config
- /var/run/docker.sock:/var/run/docker.sockdocker compose up -dActivity is logged to bot_activity.log.
The project has a full unit test suite under tests/. Run with:
pytestConfiguration is in pytest.ini. A detailed description of all tests is available in test_plan.md.
CI runs tests automatically on every push via GitHub Actions (.github/workflows/tests.yml). Commit messages are also linted via .github/workflows/commitlint.yml.
| File | Description | Lifecycle |
|---|---|---|
bot_activity.log |
Activity log | Persistent, clearable via /flush |
config/balance_history.json |
Balance snapshots | Persistent (Docker volume) |
*_plot.png / *_balance_history.png / *_resources_history.png |
Generated charts with unique filenames (validation, balance history, resources) | Temporary, deleted after sending |
- Periodic pings — Every 60 minutes, the bot checks the Massa node and records the balance
- Scheduled reports — At 7:00, 12:00, and 21:00 (if node is up), sends a detailed status report including:
- Balance comparison: first recorded vs current value
- Change amount and percentage (📈/📉 indicators)
- Last 24h balance history
- Graph cleanup — Charts are deleted after being sent to the user
- Error handling — API timeouts and errors are logged and reported with appropriate feedback images
| Issue | Solution |
|---|---|
| "Access denied" message | Verify your Telegram user ID in topology.json |
| No node data | Check Massa node is running and JSON-RPC endpoint is reachable |
| Missing temperature data | Sensor may not be available on your system (non-critical) |
| Graph generation fails | pip install --upgrade matplotlib |
| Docker commands fail with "No such file or directory" | Ensure docker Python package is installed (not the CLI) and the socket is mounted |