Unit 12.4A · Term 4

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)

Lesson Presentation

12.4A-keyword-database.pdf · Slides for classroom use

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

  1. Normalization: Convert user input to lowercase (.lower()) so "Hello" matches "hello".
  2. Partial Match: Check if the keyword is inside the message (e.g., "What is the price?" contains "price").
  3. 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

Apply

Create a "School Schedule Bot". Keywords: "Monday", "Tuesday", etc. Responses: The list of subjects for that day.

Apply

Add a "fun" command that replies with a random joke from a list when the user types "joke".

Create

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?

To ensure case-insensitive matching (so "Hi", "HI", and "hi" all trigger the greeting).

Q2: What is a "default response"?

The message sent when the bot doesn't find any matching keywords (e.g., "Sorry, I didn't understand that.").

Q3: How do you handle multiple keywords triggering the same response?

Use a list of patterns (like in the JSON example) or multiple if checks that map to the same answer key.