Keyword Database & Events
To make a bot "smart" without full AI, we use a keyword database. The bot checks the user's message against a list of known words and replies with a pre-written answer.
Learning Objectives
- 12.6.4.5 Create a database of keywords for the chat bot
- 12.6.4.6 Write event handlers (response generation)
Conceptual Anchor
The Index Card Box
Imagine a box of index cards. On the front of each card is a keyword (e.g., "Hello", "Price", "Hours"). On the back is the answer. When a user sends a message, the bot searches the cards for a matching keyword. If found, it reads the back. If not, it uses the "I don't understand" card.
Rules & Theory
Structuring the Database
We can use a Python dictionary or a JSON file as a simple database.
# Simple Dictionary Database
responses = {
"hello": "Hi there! How can I help?",
"price": "Our product costs $10.",
"bye": "Goodbye! Have a nice day.",
"default": "Sorry, I didn't understand that."
}Keyword Matching Logic
- Normalization: Convert user input to lowercase (
.lower()) so "Hello" matches "hello". - Partial Match: Check if the keyword is inside the message (e.g., "What is the price?" contains "price").
- Exact Match: Check if the message is the keyword exactly.
Worked Examples
1 Simple Dictionary Bot
import telebot
API_TOKEN = 'YOUR_TOKEN'
bot = telebot.TeleBot(API_TOKEN)
# Database
RESPONSES = {
"hello": "Greetings, human!",
"weather": "Look outside, I am just a script.",
"python": "Python is a great language!"
}
@bot.message_handler(func=lambda message: True)
def handle_message(message):
user_text = message.text.lower()
# Check for keywords
reply = "I don't understand."
for key in RESPONSES:
if key in user_text:
reply = RESPONSES[key]
break # Stop after first match
bot.reply_to(message, reply)
bot.infinity_polling()2 JSON File Database (Scalable)
Using an external file allows you to update answers without changing code.
import json
# content of data.json:
# {
# "intents": [
# {"tag": "greeting", "patterns": ["hi", "hello"], "responses": ["Hi!", "Hello there"]},
# {"tag": "bye", "patterns": ["bye", "cya"], "responses": ["Goodbye!"]}
# ]
# }
import random
# Load data
with open('data.json', 'r') as f:
data = json.load(f)
def get_response(msg):
msg = msg.lower()
for intent in data['intents']:
for pattern in intent['patterns']:
if pattern in msg:
# Return random response from list
return random.choice(intent['responses'])
return "Unknown command."Common Pitfalls
Overlapping Keywords
If you have keywords "book" (for reading) and "booking" (for reservations), a simple check might confuse them. Order your checks from specific to general, or use exact matching for critical commands.
Case Sensitivity
Always .lower() the input! Otherwise, "Hello" won't match "hello" in your
dictionary.
Tasks
Create a "School Schedule Bot". Keywords: "Monday", "Tuesday", etc. Responses: The list of subjects for that day.
Add a "fun" command that replies with a random joke from a list when the user types "joke".
Build a simplified FAQ bot for a fictional shop. Handle at least 5 topics (hours, location, returns, products, contact).
Self-Check Quiz
Q1: Why convert user input to lowercase?
Q2: What is a "default response"?
Q3: How do you handle multiple keywords triggering the same response?
if checks that map to the same answer key.