Telegram Anti-Spam Bot: Dynamic Question Generator
In the previous episode, we implemented the basic framework of an anti-spam bot
What if we want to implement a rich way of generating question-answer pairs?
Let's look at the current code.
After generating a question-answer pair, it's saved, and then new members answer the question and the answer is checked.So, let's do this.
In the directory where the python file main.py is located, there is a pset directory.
The pset directory contains multiple .py files.
Each of these .py files contains at least 1 function: buildQA
buildQA returns 2 strings, one is the question, and one is the correct_answer
I want to randomly call the buildQA function from one of the .py files in the pset directory in main.py
Throw this text at M$ copilot (or any GPT you have on hand), and you'll easily get an answer.
Apply the modification plan to the project.
In the main py file, add this function
def get_random_module():
# Find all .py files in the pset directory (excluding __init__.py)
files = [
f[:-3] for f in os.listdir("pset")
if f.endswith(".py") and f != "__init__.py"
]
# Randomly select one
chosen = random.choice(files)
# Dynamically import
module = importlib.import_module(f"pset.{chosen}")
return module
Then change the place where the question-answer was originally generated to this
# Generate verification question and answer
mod = get_random_module()
question, correct_answer = mod.buildQA()
Then create a new add.py file in the pset directory with the following content:
import random
def buildQA():
num1 = random.randint(1, 10)
num2 = random.randint(1, 10)
question = f"{num1} + {num2}"
correct_answer = num1 + num2
return question, correct_answer
See, isn't it simple? The amount of code modified is only 25 lines (including comments and blank lines)
In the same way, create more files in the pset directory to implement different question-answer pairs.
For example, youtube.py
def buildQA():
question = 'What is my Youtube channel url?'
correct_answer = 'https://www.youtube.com/@crazypeace'
return question, correct_answer
Finally, during debugging, some small issues from the previous version were fixed, such as changing HTML format to Markdown format, converting integers to strings, etc.
Final effect
Github
* Considering that there will be a few more episodes of updates in the future. So the code for this episode is also copied as tg-join-group-exam-bot2.py in the project.
See the project readme for deployment instructions
The current benefit of the project is that even if the user can't understand the main program file of more than 200 lines, it's okay. They can define their own question-answer pairs through a simple 4-line .py file.
Now, apart from arithmetic questions, other question-answer pairs are still relatively rigid. We'll come up with some flexible solutions later.
Welcome to follow my blog
========
update 2025-10-9
Take correct_answer = 'https://www.youtube.com/@crazypeace' as an example
In practice, the user might answer
https://youtube.com/@crazypeace
www.youtube.com/@crazypeace
...
So it's best to set the answer to youtube.com/@crazypeace
Then, in the code, change from strict matching to fuzzy matching
if correct_answer.lower() in user_answer.lower():

