Telegram Anti-Ad Bot: Python to Cloudflare Worker
Preface
Previously, I implemented a simple anti-advertising bot for personal use in Python, implementing the speaking verification feature.
Recently my server expired, and a thought suddenly crossed my mind — can it be converted to a Cloudflare Worker?
Agent-Oriented Development
Hermes connects to the free public-welfare site agentrouter's deepseek-v4-flash* This development wasn't a simple one-shot. The final effect itself wasn't something I had figured out from the beginning. I gradually clarified my requirements throughout the entire process.
Below I'll record some thoughts on the development approach.
Issues I considered for the join-group verification bot, will skip them here.
My original Python solution has a whitelist list, and the verified user userid is saved in it. This way, when the bot detects new messages in the group, it checks whether the sender is in the whitelist.
This information needs to be saved — there's no way around it. So I used a KV.
As a result, during testing, I found that KV has a state-latency issue for workers.
Specifically:
1. The user completes the entire verification process. There is a whitelist record in KV.
2. I operate the Cloudflare panel to delete the user from the KV whitelist record, then trigger another test.
3. The user speaks in the group, but is not muted.
4. After a few minutes, the user speaks again and is muted (correct, expected result).
The good news is, in the normal flow, the worker saves the user in the KV whitelist record, and when the user then sends a message, it works normally.
In other words, shortly after the worker operates on KV, when it accesses KV again, it uses the KV data it just operated on.
But! Here comes the "but"!
God knows how my weird brain works. I suddenly realized that Telegram users can set custom tags. This is a new feature opened this year — previously only group admins could set custom tags, but this year it was opened to all group members.
So, I can use whether or not a custom tag is set as the whitelist judgment information.
This way I don't need to operate on KV at all. Ha! Ha! Ha!
* My group is a VPN/proxy group, so I let the script set the FQer custom tag. If your group is a fan group, you can also set it to something like TUTU's Friend. Or if your group is for playing with Agents, you can set it to CLAWer haha
My original Python solution has a feature: after muting a user, the messages they posted in the group are forwarded to a storage channel, and after the user completes verification, the messages are forwarded back from the storage channel to the group. To preserve the correspondence between the
user userid and the message id in the storage channel, writing to KV is required. I really like this feature, so I kept it, despite the KV consumption.If you want zero KV operations/consumption, just don't bind this KV. (Correspondingly, you don't need to configure the STORAGE_CHANNEL_ID variable either)
Github
https://github.com/crazypeace/tg-send-msg-exam-bot-worker