The DeFiKit Bot Maker is a Telegram bot framework built on the Hermes Agent gateway that solves one of the most annoying problems in group chat bots: infinite reply loops between bots. If you have ever watched two Telegram bots get into a back-and-forth argument in a group chat, you know the pain. The solution combines mention-only control and per-chat cooldown mechanisms. Here is how it works, and how you can build the same thing.
The Problem -- Telegram Bot-Bot Infinite Reply Loops
Telegram bots in group chats are powerful. But there is a dark side: when two or more bots share a group, they can trigger each other indefinitely. Bot A responds to a user. Bot B sees Bot A's response as a new message and responds. Bot A responds again. The loop continues until someone mutes or removes one of the bots.
This is not theoretical. In production groups with multiple bots -- moderation, price ticker, DeFi transaction -- these loops happen frequently. They flood the chat, annoy users, and waste API quota.
The DeFiKit Bot Maker solves this with two complementary mechanisms:
1. **Mention-only reply control** (`require_mention: true`) -- the bot only responds when someone explicitly mentions its username or issues a command.
2. **Per-chat cooldown** -- a 15-second debounce that prevents the bot from sending messages too frequently, breaking the loop before it starts.
The Architecture -- Hermes Gateway + Per-Chat Cooldown
The DeFiKit Bot Maker runs on the Hermes Agent framework, which provides a Python Telegram gateway with async message processing:
```python
~/.hermes/config.yaml (relevant Telegram section)
telegram:
enabled: true
token: "${TELEGRAM_BOT_TOKEN}"
gateway: python
require_mention: true
cooldown_seconds: 15
group_allowed_chats:
- "*"
```
The key components are:
- **Hermes Gateway** -- the Python message processing pipeline that receives Telegram updates, parses them, and routes them to bot handlers.
- **Per-Chat Cooldown** -- a `Dict[str, float]` mapping `chat_id` to a `cooldown_until` timestamp. Before processing a message, the bot checks if the chat is in cooldown. If it is, the message is silently dropped.
- **Mention Filter** -- when `require_mention` is true, the bot only processes messages containing its username (e.g., `@defikit_bot`) or direct replies to its messages.
- **Group Access Control** -- `group_allowed_chats: ["*"]` lets the bot join any group, but the mention filter prevents blanket responses.
Implementation -- Code Walkthrough of the Cooldown Mechanism
Let us walk through the cooldown mechanism. It is remarkably simple.
```python
import time
from typing import Dict
class CooldownManager:
"""Per-chat cooldown to prevent bot-bot loops."""
def __init__(self, default_cooldown: int = 15):
self._cooldowns: Dict[str, float] = {}
self._default_cooldown = default_cooldown
def _should_process_message(self, chat_id: str) -> bool:
cooldown_until = self._cooldowns.get(chat_id, 0.0)
now = time.time()
if now < cooldown_until:
return False
return True
def _set_cooldown(self, chat_id: str) -> None:
self._cooldowns[chat_id] = time.time() + self._default_cooldown
```
Integrated into the Hermes message pipeline:
```python
class TelegramBot:
def __init__(self, config: dict):
self.cooldown = CooldownManager(
default_cooldown=config.get("cooldown_seconds", 15)
)
self.require_mention = config.get("require_mention", True)
async def process_update(self, update: dict):
chat_id = str(update.get("message", {}).get("chat", {}).get("id", ""))
Step 1: Check cooldown
if not self.cooldown._should_process_message(chat_id):
return # Silently drop -- breaks bot-bot loops
Step 2: Check mention requirement
if self.require_mention:
if not self._is_mentioned(update):
return # Not addressed to us
Step 3: Process
response = await self._handle_message(update)
Step 4: Send and set cooldown
if response:
await self._send_message(chat_id, response)
self.cooldown._set_cooldown(chat_id)
def _is_mentioned(self, update: dict) -> bool:
message = update.get("message", {})
entities = message.get("entities", [])
for entity in entities:
if entity.get("type") in ("mention", "bot_command"):
return True
return False
```
Configuration -- require_mention and group_allowed_chats
The configuration lives in `~/.hermes/config.yaml`. Here is the full section:
```yaml
telegram:
Enable the Telegram gateway
enabled: true
Your bot token from @BotFather
token: "${TELEGRAM_BOT_TOKEN}"
Gateway type: python is default and recommended
gateway: python
Only respond when the bot is explicitly mentioned
Prevents unwanted responses to every group message
require_mention: true
Seconds between responses in the same chat
15 seconds is the sweet spot -- long enough to break loops,
short enough to not feel sluggish
cooldown_seconds: 15
Which groups the bot can join
"*" means any group -- safe with require_mention: true
group_allowed_chats:
- "*"
```
Why require_mention Matters
Setting `require_mention: true` is the single most important configuration for a group chat bot. Without it, your bot responds to every message in every group. In a busy DeFi group with hundreds of messages per hour, that means constant spam.
With `require_mention: true`, the bot stays quiet until called:
```
User A: @defikit_bot what is the current gas price?
Bot: Current gas price is 12 Gwei (low), 15 Gwei (standard), 18 Gwei (fast)
```
Without it, every message -- including other bot messages -- triggers a response, causing the infinite loop.
Why 15 Seconds for Cooldown
The 15-second cooldown is carefully chosen:
- **Long enough** to break bot-bot reply chains. With both bots using 15-second cooldowns, a loop produces at most one exchange every 15 seconds.
- **Short enough** to not frustrate human users. The cooldown applies after sending a message, not before processing one, so follow-ups work fine.
The cooldown is per-chat, not global. A bot serving 50 groups handles them all in parallel.
Deploying Your Own DeFiKit Bot Maker
Step 1: Create a Bot
Message @BotFather on Telegram and send `/newbot`. Follow the prompts to get your token:
```
1234567890:ABCdefGHIjklmNOPqrstUVwxyz-1234567
```
Step 2: Set Up Hermes
```bash
git clone https://github.com/nous-hermes/hermes.git
cd hermes
pip install -e .
```
Step 3: Configure
Create `~/.hermes/config.yaml`:
```bash
mkdir -p ~/.hermes
cat > ~/.hermes/config.yaml << 'EOF'
telegram:
enabled: true
token: "YOUR_BOT_TOKEN_HERE"
gateway: python
require_mention: true
cooldown_seconds: 15
group_allowed_chats:
- "*"
EOF
```
Step 4: Write Bot Logic
```python
my_defikit_bot.py
from hermes.telegram import TelegramGateway
async def handle_message(message: dict) -> str:
text = message.get("text", "")
if "gas" in text.lower():
return "Current gas: 12 Gwei (low), 15 Gwei (avg), 18 Gwei (fast)"
elif "price" in text.lower():
return "ETH: $3,450 | BTC: $67,200 | SOL: $145"
elif "help" in text.lower():
return (
"Commands: @bot gas, @bot price, @bot help"
)
else:
return None
gateway = TelegramGateway(config_path="~/.hermes/config.yaml")
gateway.start(handler=handle_message)
```
Step 5: Run and Test
```bash
python my_defikit_bot.py
```
Add the bot to a test group:
```
User: @my_defikit_bot price
Bot: ETH: $3,450 | BTC: $67,200 | SOL: $145
```
Step 6: Monitor and Tune
Watch for cooldown events in logs:
```
2026-05-11 14:23:01 [INFO] Dropped message from chat -1001234567890 (cooldown active, 8s remaining)
2026-05-11 14:23:15 [INFO] Processing message from chat -1001234567890
2026-05-11 14:23:15 [INFO] Sent response, cooldown set until 14:23:30
```
If too many messages are dropped, lower the cooldown. If bot loops persist, increase it.
Key Takeaways
1. **Bot-bot infinite reply loops are a real problem** in group chats. They flood chats, waste API quota, and annoy users.
2. **The cooldown mechanism is your first line of defense.** A per-chat `Dict[str, float]` tracking timestamps is simple and effective. 15 seconds is the recommended default.
3. **require_mention with group_allowed_chats: ["*"]** gives the best of both worlds: your bot can join any group but only speaks when spoken to.
4. **Hermes Agent handles the heavy lifting** -- async processing, Telegram API integration, and configuration management are all built in.
5. **Deploying is straightforward.** Create a bot with @BotFather, configure config.yaml, write a handler, and run.
The DeFiKit Bot Maker architecture proves production-grade Telegram bots don't need complex frameworks. A clean cooldown manager, sensible defaults, and mention-only control are enough to build bots that work reliably in busy group chats.