Оригінальна публікація: How to Create a Telegram Bot using Python

Автоматизовані чат-боти надзвичайно корисні для взаємодій. Чат-боти можна створити для Slack, Discord та інших платформ.

У цій публікації я навчу вас створювати чат-бот у телеграмі, який надсилає гороскоп. Розпочнемо!

Як отримати токен бота

Щоб налаштувати новий бот, потрібно поговорити з BotFather. Ні, це не людина — він також бот, і бос всіх інших ботів.

  1. Знайдіть @botfather у телеграмі.
Screenshot-2022-12-16-092357
Телеграм-бот BotFather

2.  Розпочніть переписуватись з BotFather, натиснувши кнопку «Розпочати» (start).

Screenshot-2022-12-16-092531
Натисніть на кнопку «Розпочати» (start).

3.  Введіть /newbot та дотримуйтесь підказок для створення нового бота. BotFather надасть токен, який ви використовуватимете для автентифікації свого бота та надання йому доступу до API телеграму.

Screenshot-2022-12-16-093337
Отримання токену доступу

Примітка: переконайтеся, що ви надійно зберігаєте токен. Вашим ботом може керувати кожен, хто має токен доступу.

Як налаштувати середовище розробки

Налаштуємо середовище розробки! Для створення телеграм-бота доступно безліч бібліотек, але ми використовуватимемо бібліотеку pyTelegramBotAPI. Це проста, але розширна реалізація Python для API телеграм-бота із синхронними та асинхронними можливостями.

Встановіть бібліотеку pyTelegramBotAPI, використовуючи pip:

pip install pyTelegramBotAPI

Потім відкрийте свій улюблений редактор коду та створіть файл .env, щоб зберігати свій токен, як показано нижче:

export BOT_TOKEN=тут-ваш-токен-боту

Після цього запустіть команду source .env, щоб прочитати змінні середовища з файлу .env.

Як створити свій перший бот

Всі реалізації API зберігаються у класі під назвою TeleBot. Він пропонує багато способів прослуховування вхідних повідомлень, а також функції send_message(), send_document() та інші, щоб надсилати повідомлення.

Створіть новий файл bot.py та вставте наступний код:

import os

import telebot

BOT_TOKEN = os.environ.get('BOT_TOKEN')

bot = telebot.TeleBot(BOT_TOKEN)

У коді вище ми використовуємо бібліотеку os, щоб прочитати змінні середовища, збережені у нашій системі.

Якщо ви пам’ятаєте, у минулому кроці ми експортували змінну середовища під назвою BOT_TOKEN. Значення BOT_TOKEN зчитується у змінній під назвою BOT_TOKEN. Крім того, ми використовуємо клас TeleBot, щоб створити екземпляр бота та передаємо йому BOT_TOKEN.

Потім потрібно зареєструвати обробники повідомлень. Ці обробники повідомлень містять фільтри, які має пройти повідомлення. Якщо повідомлення проходить фільтр, викликається декорована функція, а вхідне повідомлення надається як аргумент.

Визначимо обробник повідомлень, який обробляє вхідні команди /start та /hello.

@bot.message_handler(commands=['start', 'hello'])
def send_welcome(message):
    bot.reply_to(message, "Howdy, how are you doing?")

Для функції, декорованої обробником повідомлень, прийнятне будь-яке ім’я, але вона може мати лише один параметр (повідомлення).

Додамо ще один обробник, який повертає усі вхідні повідомлення відправнику.

@bot.message_handler(func=lambda msg: True)
def echo_all(message):
    bot.reply_to(message, message.text)

Наведений вище код використовує вираз lambda, щоб протестувати повідомлення. Оскільки нам потрібно відправляти усі повідомлення назад, ми завжди повертаємо True від функції lambda.

Тепер ви маєте простий бот, який відповідає на команди /start та /hello, а також надсилає усі інші надіслані повідомлення відправнику. Додайте наступне до кінця файлу, щоб запустити бот:

bot.infinity_polling()

Тепер наш телеграм-бот готовий! Запустимо файл Python та перейдемо до телеграму, щоб протестувати бота.

Знайдіть бота за іменем користувача, якщо не можете його знайти. Протестуйте його, надсилаючи команди /hello та /start, а також інші тексти.

Screenshot-2022-12-16-101334
Тестування бота

Примітка: всі обробники повідомлень тестуються в тому порядку, в якому вони оголошені у вихідному файлі.

Щоб дізнатись більше про використання бібліотеки pyTelegramBotAPI, див. документацію.

Як програмувати бот з гороскопом

Зараз переключимося на створення бота з гороскопом. Ми використовуватимемо ланцюжкування повідомлень у боті. Спочатку бот запитуватиме ваш знак зодіаку та день, а потім відповідатиме гороскопом на певний день.

Позаочі бот взаємодіє із API, щоб отримати дані про гороскоп.

Ми використовуватимемо Horoscope API, який я побудував в іншому туторіалі. Якщо ви хочете навчитись його створювати, перегляньте цей туторіал. Перш ніж почати, дослідіть API тут.

Як отримати дані про гороскоп

Створимо функцію корисності, щоб отримувати дані гороскопу для певного дня.

import requests

def get_daily_horoscope(sign: str, day: str) -> dict:
    """Get daily horoscope for a zodiac sign.
    Keyword arguments:
    sign:str - Zodiac sign
    day:str - Date in format (YYYY-MM-DD) OR TODAY OR TOMORROW OR YESTERDAY
    Return:dict - JSON data
    """
    url = "https://horoscope-app-api.vercel.app/api/v1/get-horoscope/daily"
    params = {"sign": sign, "day": day}
    response = requests.get(url, params)

    return response.json()

У наведеному вище коді Python ми створили функцію, яка приймає два рядкові аргументи — sign та day — і повертає дані JSON. Ми надіслали запит GET на URL API і передали sign та day як параметри запиту.

Якщо протестувати функцію, отримаєте щось схоже:

{
   "data":{
      "date": "Dec 15, 2022",
      "horoscope_data": "Lie low during the day and try not to get caught up in the frivolous verbiage that dominates the waking hours. After sundown, feel free to speak your mind. You may notice that there is a sober tone and restrictive sensation today that leaves you feeling like you will never be able to break free from your current situation. Don't get caught in this negative mindset."
   },
   "status": 200,
   "success": true
}

Примітка: ви можете дізнатись більше про бібліотеки requests у Python в цьому туторіалі.

Як додати обробник повідомлень

Тепер ми маємо функцію, яка повертає гороскоп. Зараз створимо обробник повідомлень, який запитує користувача про знак зодіаку.

@bot.message_handler(commands=['horoscope'])
def sign_handler(message):
    text = "What's your zodiac sign?\nChoose one: *Aries*, *Taurus*, *Gemini*, *Cancer,* *Leo*, *Virgo*, *Libra*, *Scorpio*, *Sagittarius*, *Capricorn*, *Aquarius*, and *Pisces*."
    sent_msg = bot.send_message(message.chat.id, text, parse_mode="Markdown")
    bot.register_next_step_handler(sent_msg, day_handler)

Наведена вище функція дещо відрізняється від інших функцій, які ми визначили раніше. Гороскоп буде викликаний командою /horoscope. Ми надсилаємо текстове повідомлення користувачеві, але зауважте, що ми встановили parse_mode на Markdown під час надсилання повідомлення.

Оскільки ми використовуватимемо ланцюжкування повідомлень, ми використали метод register_next_step_handler(). Цей метод приймає два параметри: повідомлення, надіслане користувачем, та функцію зворотного виклику, яку потрібно викликати одразу після повідомлення.  Тому ми передаємо змінну sent_msg та нову функцію day_handler, яку визначимо наступною.

Визначимо функцію day_handler(), яка приймає повідомлення.

def day_handler(message):
    sign = message.text
    text = "What day do you want to know?\nChoose one: *TODAY*, *TOMORROW*, *YESTERDAY*, or a date in format YYYY-MM-DD."
    sent_msg = bot.send_message(
        message.chat.id, text, parse_mode="Markdown")
    bot.register_next_step_handler(
        sent_msg, fetch_horoscope, sign.capitalize())

Ми отримуємо знак зодіаку з атрибута message.text. Він також запитує бажаний день гороскопу, як і попередня функція.

Вкінці ми використовуємо той самий метод register_next_step_handler() і передаємо sent_msg, функцію зворотного виклику fetch_horoscope та sign.

Зараз визначимо функцію fetch_horoscope(), яка приймає повідомлення та знак зодіаку.

def fetch_horoscope(message, sign):
    day = message.text
    horoscope = get_daily_horoscope(sign, day)
    data = horoscope["data"]
    horoscope_message = f'*Horoscope:* {data["horoscope_data"]}\\n*Sign:* {sign}\\n*Day:* {data["date"]}'
    bot.send_message(message.chat.id, "Here's your horoscope!")
    bot.send_message(message.chat.id, horoscope_message, parse_mode="Markdown")

Це остання функція, в якій ми отримуємо знак зодіаку з параметру функції та день з атрибуту message.text.

Потім ми отримуємо гороскоп, використовуючи функцію get_daily_horoscope() та створюємо наше повідомлення. Наприкінці ми надсилаємо повідомлення з гороскопом.

Демо-версія бота

Після запуску файлу Python ви можете перевірити функціональність. Ось демо-версія:

Рекомендовані наступні кроки

Наразі бот припиняє працювати, як тільки ми зупиняємо Python. Щоб він завжди працював, ви можете розгорнути бота на платформах типу Heroku, Render тощо.

Ось посилання на репозиторій GitHub для цього проєкту. Перегляньте його.

Ви можете додати більше функціональностей до бота, дослідивши API телеграму.

Дякую, що прочитали! Можете підписатись на мене у твіттері.