Телеграм-бот — це віртуальний користувач Telegram, з яким можна спілкуватися, як із живою людиною. Перед нами стоїть дуже цікаве завдання. Ми повинні створити «розумного» бота, який уміє:
  • вести діалог;
  • практикуватися у побаченнях;
  • генерувати яскраві та цікаві описи для сайтів знайомств;
  • допомагати при листуванні на сайті знайомств.
Щоб бот усьому цьому навчився і виглядав розумним, ми додамо до нього ChatGPT.

1. Попередня підготовка до роботи

Перш ніж почати програмувати, нам потрібно підготувати робоче місце. Для цього нам знадобиться:
  • сам Python SDK (Python Interpreter);
  • додаток для написання та запуску програм — PyCharm Community Edition;
  • шаблон нашого проєкту;
  • Telegram: бажано для зручності завантажити десктопну версію, принаймні для першої лекції.

2. Установка PyCharm та завантаження проєкту

Завантажити безкоштовну версію PyCharm Community Edition можна з сайту розробника для Windows, MacOS або Linux. Шаблон проєкту бажано розархівувати і запам'ятати, де знаходиться папка. Якщо вже завантажували, знайдіть, де саме вона зберігається. Відкрийте PyCharm. Якщо це перший запуск, швидше за все, ви побачите вікно з пропозицією створити проєкт, відкрити його або завантажити із системи контролю версій. Попередня підготовка та конспект до заняття №1 - 1 Якщо ви вже працювали в PyCharm і у вас відкритий інший проєкт, натисніть у Windows/Linux File – Open, у MacOS PyCharm – Open. Попередня підготовка та конспект до заняття №1 - 2Далі в обох випадках знайдіть папку TinderBolt там, де ви її зберегли. І знову натисніть Open. Попередня підготовка та конспект до заняття №1 - 3Перед вами відкриється шаблон проєкту. Ліворуч ви побачите дерево проєкту, праворуч буде показано активний файл. Дерево проєкту складається з різних директорій і файлів. Потрібні нам файли з Python-кодом знаходяться прямо у папці TinderBolt: Попередня підготовка та конспект до заняття №1 - 4Тепер вам потрібно вказати інтерпретатор Python для вашого проєкту — просто клікніть на посилання зверху: Попередня підготовка та конспект до заняття №1 - 5Якщо все пройшло успішно, ви побачите, як перший рядок коду підкреслений червоним: Попередня підготовка та конспект до заняття №1 - 6Якщо ви ніколи не програмували, можливо, структура проєкту, та й сам код у файлах здасться вам чимось незрозумілим і занадто складним. Насправді розуміння всього цього просто потребує практики. Поки що ми тільки збираємося навчатися на рівні Python Junior, а «джуни» зазвичай не створюють структуру проєкту, а лише пишуть окремі його частини. Тож протягом наступних занять ми з вами зімітуємо роботу початківця-програміста на проєкті, шаблон якого створив якийсь senior чи архітектор.

3. Трохи теорії перед першою лекцією

Python-програма чи Python-проєкт

Загалом програма — це послідовність команд, які розуміє та виконує комп’ютер. Ці команди пише програміст, у нашому випадку — мовою Python. Щоб програмістам було простіше працювати, у Python-проєкту є певна структура. На фізичному рівні це файли та папки, розташовані у певній ієрархії, як ви могли бачити у відкритому проєкті TinderBolt. Основна кількість файлів у типовому Python-проєкті — це файли з Python-кодом, але також є файли з ресурсами (наприклад, текстові файли чи графічні аватарки), файли з налаштуваннями тощо. У найпростішому випадку програма може складатися з одного файлу з Python-кодом. Python, встановлений на комп’ютер, зможе перевести цей код на зрозумілу для комп’ютера мову (скомпілювати), а потім запустити програму.

Проста програма

Приклад такої простої програми:

print("Це моя програма")
Ця програма виведе на екран текст:
Це моя програма
Тут майже все очевидно, але про всяк випадок поясню: щоб вивести якийсь текст на екран, потрібно: а) взяти його в подвійні лапки і b) написати команду print() – усе як у прикладі вище. Змінні в Python створюються у момент присвоєння їм значень – спеціально оголошувати змінні не потрібно. Приклад:

name = "Alexander"
age = 35
city = "Це моя програма"

Умовний оператор

Умова (if else) виглядає майже так само, як і в інших мовах програмування:

if name == "Alexander":
    print("Hi Alexander, The Great")
else:
    print("Hi ", name)
Після умови та після else потрібно ставити двокрапку. Круглі дужки для умови не потрібні.

Блок коду

Важливо! Кілька команд об'єднуються у блок коду не за допомогою фігурних дужок {}, а просто зсувом на 4 пробіли вправо. Це дозволяє коду в Python бути дуже компактним, але вимагає стежити за пробілами – зайві пробіли ставити деінде не можна.

Коментарі

Коментарі починаються із символу # і тривають до кінця рядка. Приклади:

# приклад умови if else
if name == "Alexander":  #перевіряємо, що змінна дорівнює  Alexander
    print("Hi Alexander, The Great")
else:
    print("Hi ", name)
Коментарі можна залишати для колег, які читатимуть ваш код, або для себе, щоб не забути деталей. Важливо, щоб коментарі були змістовними.

Функції

Функції оголошуються за допомогою ключового слова def. Приклад:

def sum (a, b):
    return a+b

Порівняння

Оператор = – це не знак рівності, а присвоєння.

name = "Alexander"
age = 35
city = "Це моя програма"
Якщо ви хочете порівняти змінні, потрібно використовувати подвійний знак рівності – <==>.

4. Доповнення та короткий конспект до заняття №1

Будь-який Python-проєкт складається з певних файлів і папок. Це можуть бути файли з Python-кодом, файли з налаштуваннями, ресурси для роботи нашої програми. Наприклад, зображення, які вона завантажуватиме, або текстові файли, інформацію з яких вона тим чи іншим чином зчитуватиме. Давайте поговоримо про структуру нашого проєкту, а точніше – про найголовніші його файли. Файли з кодом розташовані безпосередньо у папці TinderBolt. Попередня підготовка та конспект до заняття №1 - 7У папці resources знаходяться зображення, текстові повідомлення та промпти для chatGPT. Попередня підготовка та конспект до заняття №1 - 8Ми писатимемо весь код у файлі bot.py, безпосередньо на місці коментаря «тут будемо писати наш код». Попередня підготовка та конспект до заняття №1 - 9

Опис файлів:

  • bot.py — містить всю логіку нашого бота: надсилає повідомлення користувачеві, отримує повідомлення від нього та обробляє введені команди й натискання кнопок.
  • gpt.py — містить службовий клас ChatGPTService, який спрощує роботу нашого бота з ChatGPT і робить взаємодію з ним більш зручною та зрозумілою. util.py — містить кілька службових функцій, які дозволяють не писати надто довгу логіку під час марафону там, де це не потрібно.
Весь код у цих файлах забезпечений коментарями, тож ви зможете розібратися, як він працює, якщо матимете бажання. Це корисно. API — це абревіатура від «Application Programming Interface», що перекладається як «інтерфейс програмування додатків». Це набір функцій для спілкування програм між собою. Тобто API дозволяє програмам спілкуватися одна з одною, а програмістам — використовувати можливості інших програм у своїх.

Крок 1. Встановлення бібліотек

Якщо у верхній частині файлу bot.py у вас імпорт бібліотек підсвічується червоним, це означає, що все гаразд. Але бібліотеки все ж доведеться завантажити. Для цього потрібно відкрити Термінал. Попередня підготовка та конспект до заняття №1 - 10І виконайте у ньому дві команди:

pip install python-telegram-bot
та

pip install openai
Якщо все пройшло успішно, то перший рядок файлу bot.py перестане підсвічуватися червоним, і ви зможете використовувати свої бібліотеки.

Крок 2. Реєстрація бота та отримання токена

На 9-му рядку нашого файлу bot.py є такий код:

app = ApplicationBuilder().token("telegram-token").build()
Ось цей telegram-token нам потрібно замінити на реальний Telegram Token. Щоб отримати значення токена, потрібно зареєструвати нашого бота на сервері Telegram:
  1. Зайдіть у Telegram.
  2. У пошуку знайдіть бота з іменем BotFather (такий собі "батько всіх ботів").
  3. Напишіть команду /start.
  4. Натисніть на /newbot. Попередня підготовка та конспект до заняття №1 - 11
  5. Обираємо ім'я для нашого бота.
  6. Тепер обираємо ім'я користувача (username) для свого бота. Ім'я має бути унікальним і закінчуватися на «bot».
  7. Якщо все гаразд, бот надішле нам привітальне повідомлення, у якому буде вказане ім'я користувача, а як токен можна використовувати токен для HTTP API, що його надав бот, а також посилання на нашого бота. Попередня підготовка та конспект до заняття №1 - 12
  8. Тепер повертаємося до PyCharm, у файл bot.py, і вставляємо наш токен між подвійними лапками:
    
    app = ApplicationBuilder().token("809898698769:jafafdlkdjkjjfkdjd77yh").build()
    

Крок 3. Запуск бота

Наш бот поки нічого не вміє, але вже працює. Щоб запустити програму в PyCharm, потрібно натиснути на зелену стрілочку у верхньому правому куті вікна ▶ (при цьому у вікні бажано відкрити файл bot.py). Попередня підготовка та конспект до заняття №1 - 13 Або ж клацніть правою кнопкою миші на імені файлу bot.py у дереві проєкту та знайдіть там стрілочку з написом Run “bot”. Попередня підготовка та конспект до заняття №1 - 14 Так запускається будь-яка програма на Python. Ми запускаємо всі команди, що містяться у файлі bot.py. Тепер, коли програму запущено, ми можемо повертатися в Telegram: наш бот працює. Клікаємо за посиланням, отриманим у вітальному повідомленні, і ми в бота в гостях. Ми можемо натиснути на кнопку Start або написати /start (це кнопка початку спілкування з ботом). Щоправда, спілкуватися він поки що не вміє, тому нічого не станеться. Тому просто зупинимо програму і перейдемо до написання коду. Як ми спілкуємося з ботом чи живою людиною? Ми отримуємо її повідомлення і пишемо свої. Найчастіше це текстові повідомлення, але також це можуть бути картинки, а в разі бота — ще й команди. Як ми вже писали вище, для спілкування програм між собою є спеціальні пакети API. Зрозуміло, програмісти вже написали API для Телеграм-ботів на Python, і наш ментор їх використовував, щоб створити методи для спілкування саме з нашим ботом. У принципі, це могли зробити і ми, але тоді наша робота ускладнилася б у рази, а ми тільки починаємо вчитися, нам і так складно.

Крок 4. Навчаємо бота відповідати

Щоб бот нам щось написав, потрібно створити асинхронну функцію hello. Напишемо її там, де був коментар «тут будемо писати наш код». Перша версія функції може виглядати так:

async def hello(update, context):
    await send_text(update, context, "Привіт!")
Ця функція на будь-яке повідомлення користувача відповідатиме «Привіт!». Тепер цю функцію потрібно пов’язати з ботом. Для цього після рядка з токеном додаємо:

app.add_handler(MessageHandler(filters.TEXT, hello))
За допомогою цієї команди ми вказуємо додатку нашого бота (app), що йому потрібно додати у свою логіку ще один обробник повідомлень від користувача add_handler(MessageHandler(filters.TEXT, hello)) Кінцевий код виглядатиме так:

async def hello(update, context):
    await send_text(update, context, "Привіт!")
app = ApplicationBuilder().token("0980989809:fjkdfjlsdjfisdm").build()
app.add_handler(MessageHandler(filters.TEXT, hello))
app.run_polling()

Крок 5. Вчимо бота отримувати повідомлення від користувача

Щоб у функції hello отримати текст повідомлення, яке написав користувач, використовуємо об’єкт update і написати код типу:

user_message = update.message.text
Новий варіант функції hello може виглядати так:

async def hello(update, context):
    await send_text(update, context, "Привіт!")
    await send_text(update, context, "Ти написав" + update.message.text)
Важливо! Слова async і await обов’язкові, оскільки бібліотека python-telegram-bot повністю асинхронна. Тому ми повинні теж писати асинхронні функції — і використовувати ключове слово async перед оголошенням наших функцій. Перед викликом же асинхронної функції потрібно обов'язково писати ключове слово await.

Крок 6. Надсилаємо повідомлення з кнопками

Щоб надіслати користувачеві повідомлення з кнопками, використовуємо функцію send_text_buttons. У неї передаємо:
  • параметри update та context;
  • текст для користувача;
  • список кнопок у фігурних дужках.
Кожна кнопка задається у форматі:
  • унікальне ім’я кнопки;
  • текст на кнопці.
Приклад:

ync def hello(update, context):
    async def hello(update, context):
    await send_text_buttons(update, context, "Оберіть режим роботи", {  # Текст перед кнопкою
        "btn_start": " Старт ", # Текст і команда кнопки "Старт"
        "btn_stop": " Стоп "  # Текст і команда кнопки "Стоп"
    })
Тепер, якщо ми запустимо бота, у нас відобразиться дві кнопки: Попередня підготовка та конспект до заняття №1 - 15Якщо ви хочете, щоб ваша програма щось робила під час натискання на кнопки, то вам потрібно створити ще одну асинхронну функцію і пов'язати її з ботом. Приклад:

async def hello_button(update, context):
    query = update.callback_query.data   #код кнопки
    await update.callback_query.answer() #відмічаємо, що опрацювали натиск на кнопку
    await send_text(update, context, "Ви натиснули на кнопку " + query)
Зв'язати функцію з ботом можна додавши ще один обробник:

app = ApplicationBuilder().token("0980989809:fjkdfjlsdjfisdm").build()
app.add_handler(MessageHandler(filters.TEXT, hello))
app.add_handler(CallbackQueryHandler(hello_button))
app.run_polling()

Крок 7. Навчаємо бота надсилати картинки

Нарешті, надсилати в чат картинки можна за допомогою методу send_photo(). Приклад:

async def hello(update, context):
    await send_photo(update, context, "main")
Йому можна надсилати картинки за ім'ям (ключем), а самі картинки лежать у папці resources\images у нашому проєкті.

Крок 8. Робота з командами Telegram

Команди в Telegram починаються з / косої риски. Власне, з однією з них ми вже працювали, це команда /start. Давайте спробуємо змусити нашу програму відреагувати на команду /start. Наприклад, якщо користувач надіслав команду старт, то йому у відповідь надіслати картинку. Для цього нам потрібно створити асинхронну функцію start(), виглядати її код може приблизно так:

async def start(update, context):
    await send_photo(update, context, "main")
Але тепер і цю функцію потрібно пов'язати з нашим ботом, щоб вона викликалася, коли користувач введе команду start. Зробити це досить просто: потрібно додати ще один handler:

app.add_handler(CommandHandler("start", start))
Важливо! Кожна команда є насамперед просто повідомленням, а потім уже командою: команда — це повідомлення, яке починається з символу /. Якщо ви не хочете, щоб функція hello обробляла ваші команди як повідомлення, то потрібно відключити їй обробку команд. Зробити це можна кодом типу такого:

app = ApplicationBuilder().token("0980989809:fjkdfjlsdjfisdm").build()
app.add_handler(CommandHandler("start", start))

app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, hello)) # отключаем команды

app.add_handler(CallbackQueryHandler(hello_button))
app.run_polling()

Що потрібно зробити перед і під час першої лекції

  1. Встановити все необхідне для роботи.
  2. Послухати лекцію і повторити все за ментором.
За підсумком у нас має бути бот, який:
  1. має ім'я, назву і посилання на себе
  2. запускається
  3. зчитує повідомлення користувача
  4. відсилає картинку й опис своєї роботи, якщо користувач надіслав йому команду /start
  5. відсилає просте текстове повідомлення
Не все може бути зрозуміло, але важливо не заплутатися і все зробити, повторити за ментором. Деякі моменти стануть зрозумілі пізніше.

Підказки до виконання завдання №1

Перевірка коректності коду та оновлення змін у проєкті

Щоб побачити зміни, які ти вносиш безпосередньо в роботі Телеграм-бота, не забудь після написання свого коду застосувати всі зміни (перезапустити програму) в PyCharm. Для цього потрібно в нижній горизонтальній панелі натиснути на зелену круглу стрілку: Попередня підготовка та конспект до заняття №1 - 16Пам'ятай про те, що твої назви змінних, функцій і кнопок мають бути читабельними: за назвою має бути зрозуміло, що вони роблять або для чого призначені.

Форматування тексту

Щоб виділити в боті текст курсивом, потрібно на початку і в кінці необхідного фрагмента додати нижні підкреслення: _текст_ Щоб виділити текст жирним, потрібно на початку та наприкінці необхідного фрагмента додати зірочки: *текст*