Chatbot Development: API, Events & Advanced Logic
Developing a functional chatbot requires strategic planning, API integration, and event-driven logic. In this comprehensive lesson, we cover everything from basic keyword matching to advanced UI elements like interactive calendars, time selectors, and media processing using Python.
Learning Objectives
- 12.6.4.4 Get API configuration for a chatbot
- 12.6.4.5 Create a database of answers by keywords
- 12.6.4.6 Process chat events and implement complex decision trees
1. The Chatbot Iceberg & Development Stages
What the user sees is only the tip of the iceberg. A basic bot replies to text, but a Great Chatbot handles complex backend systems.
| Stage | Key Actions & Focus |
|---|---|
| 1. Analytical | Familiarization with messengers (Telegram, VK). Evaluation of capabilities. Choosing the platform. |
| 2. Planning | Searching for the main idea. Mapping the user journey (Decision Trees). Reviewing competitor bots. |
| 3. Practical | Bot development (Python code), API configuration, UI/UX implementation, and testing. |
2. Basic Logic: Processing Events & Keywords
Chatbots rely on event-driven programming. The bot "listens" for user actions using decorators (@bot.message_handler). We use a Keyword-based approach to analyze user input.
import telebot
# 1. API Configuration
bot = telebot.TeleBot("PUT_YOUR_API_TOKEN_HERE")
# 2. Event Handler (Listens for text messages)
@bot.message_handler(content_types=['text'])
def keyword_responses(message):
# 3. Standardize input to lowercase for accurate keyword matching
user_text = message.text.lower()
# 4. Database of answers based on keywords
if "hello" in user_text or "hi" in user_text:
bot.send_message(message.chat.id, "Hello! How can I assist you today?")
elif "price" in user_text:
bot.send_message(message.chat.id, "Our courses start at 5000 KZT.")
else:
bot.send_message(message.chat.id, "I don't understand you.")
# 5. Polling (Keeps the bot running continuously)
bot.polling(none_stop=True)3. Rich Media: Sending Images and Files
A modern chatbot must be visual. You can send photos, documents, and audio using native API methods. This is highly useful for sending event posters (like Hack.OS schedules), product menus, or digital receipts.
@bot.message_handler(commands=['poster'])
def send_event_poster(message):
# rb means 'read binary'. Ensure the image is in the same folder as your Python script.
photo = open('hack_os_poster.jpg', 'rb')
bot.send_photo(message.chat.id, photo, caption="Welcome to Hack.OS 2026! ๐")
# You can also send documents (PDFs, DOCX)
# doc = open('schedule.pdf', 'rb')
# bot.send_document(message.chat.id, doc)4. Interactive UI: Keyboards & Menus
There are two primary types of keyboards in Telegram. They eliminate the need for users to type exactly matching keywords, drastically reducing errors.
| Type | Description | Code Snippet |
|---|---|---|
| Reply Keyboard | Replaces the system keyboard at the bottom. Sends a standard text message when pressed. Best for Main Menus. | markup = types.ReplyKeyboardMarkup(resize_keyboard=True) |
| Inline Keyboard | Attached directly below a message. Triggers a hidden callback_data signal instead of text. Best for Dynamic Choices. |
markup = types.InlineKeyboardMarkup() |
5. Advanced Layouts: Calendars & Time Selectors
To build a booking system, you need structured grids for dates or times. We can manipulate the row_width property of an Inline Keyboard, or use the .row() method to force specific buttons onto specific lines.
Live Code: Time Selector Grid
@bot.message_handler(commands=['book'])
def select_time(message):
markup = types.InlineKeyboardMarkup()
# Creating a 3x2 grid for time slots
btn1 = types.InlineKeyboardButton("10:00", callback_data="t_10")
btn2 = types.InlineKeyboardButton("11:00", callback_data="t_11")
btn3 = types.InlineKeyboardButton("12:00", callback_data="t_12")
btn4 = types.InlineKeyboardButton("14:00", callback_data="t_14")
btn5 = types.InlineKeyboardButton("15:00", callback_data="t_15")
btn6 = types.InlineKeyboardButton("16:00", callback_data="t_16")
# .row() forces these specific buttons into a single horizontal line
markup.row(btn1, btn2, btn3)
markup.row(btn4, btn5, btn6)
bot.send_message(message.chat.id, "Select your presentation time:", reply_markup=markup)
# Handling the button press
@bot.callback_query_handler(func=lambda call: call.data.startswith('t_'))
def handle_time(call):
selected = call.data.split('_')[1]
bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id,
text=f"โ
Time {selected}:00 is confirmed!")
bot.answer_callback_query(call.id)6. State Management: Multi-step Forms
To collect multiple pieces of data (e.g., Name -> Grade -> Track), the bot must "remember" what it just asked. We use register_next_step_handler to force the bot to wait for the user's next message and route it to a specific function.
user_data = {} # Temporary database
@bot.message_handler(commands=['register'])
def start_registration(message):
chat_id = message.chat.id
user_data[chat_id] = {} # Initialize empty storage
msg = bot.send_message(chat_id, "Step 1: Please type your Full Name:")
bot.register_next_step_handler(msg, process_name)
def process_name(message):
chat_id = message.chat.id
user_data[chat_id]['name'] = message.text
msg = bot.send_message(chat_id, "Step 2: Enter your Grade (e.g., 10A):")
bot.register_next_step_handler(msg, process_grade)
def process_grade(message):
chat_id = message.chat.id
name = user_data[chat_id]['name']
grade = message.text
bot.send_message(chat_id, f"๐ Registration Complete!\nName: {name}\nGrade: {grade}")Common Pitfalls
Callback Data Size Limits
Telegram limits callback_data to 64 bytes. Never put full sentences in the callback data. Use short codes like "dt_24_02" for dates, and parse them in your logic.
Infinite Polling Blocks
Code written below bot.polling(none_stop=True) will never execute. This command must be the absolute last line of your Python script.
Practical Projects
Create a bot that replies to "Hello" (in any case) with "Hello!". For any other text, it should reply "I received your message: [text]".
Using api.openweathermap.org, create a chatbot that asks the user for a city name and replies with the real-time temperature.
Build a bot for the upcoming hackathon.
1. Show a Reply Menu: "Register", "View Poster".
2. "View Poster" sends an image using bot.send_photo().
3. "Register" starts a multi-step form (Name, Age).
4. After Name and Age, show an Inline Calendar/Grid to select the presentation day (Feb 13 or Feb 14). Output a final confirmation ticket.