Подключить базу данных к телеграм боту
С помощью ботов можно упростить себе задачу коммуникации с пользователями, создав для них умного помощника. Боты понимают текстовые команды и могут обращаться к API вашего вебсайта, сервиса или быть самостоятельным продуктом с уникальными услугами. Обычно, для создания бота требуется сервер, но в этой статье мы разберём подход, позволяющий обойтись без него. Он идеален при резких колебаниях количества запросов и прекрасно выдерживает пиковые нагрузки.
Настроить Телеграм-бота на Облачных функциях, используя официальный API и заготовленный нами пример, можно в 3 этапа:
- Запрограммировать логику работы Телеграм-бота.
- Зарегистрировать нового бота в Telegram.
- Связать бота и его логику воедино.
Запрограммировать логику работы Телеграм-бота
Пройдите следующие шаги с нашим примером бота, чтобы освоиться:
Зарегистрировать нового бота в Telegram
Чтобы Telegram знал о существовании нашего бота, его нужно зарегистрировать. Для этого существует только один способ:
-
Найдите бота @BotFather в Телеграм. Это официальный бот, созданный специально для управления ботами.
Отправьте ему команду:
Запишите полученный токен от @BotFather — это ключ для работы с Telegram API.
Теперь у нас API, регистрация бота в Telegram и его токен. Осталось связать это вместе.
Как связать бота и его логику воедино?
На этом этапе надо сделать так, чтобы бот знал токен пользователя, а Telegram знал, где его API:
- Найдите переменную окружения «TOKEN» в настройках функции. Мы оставили её пустой на первом этапе.
- Укажите в этой переменной токен вашего бота, который получили от @BotFather.
- Нажмите Сохранить и развернуть.
Способ 1. Через бота @SelectelServerless_bot
Бот ответит тем, что получит из Telegram API. Если всё хорошо, это будет «true».
Чтобы удостовериться в том, что всё корректно, отправьте команду:
В ответ должна прийти информация о webhook, в том числе указанный вами URL.
Способ 2. Из заготовленной формы
Примечание: может понадобиться наличие VPN.
Готов для работы бот, доступный в Телеграме, отвечающий на команды и способный автоматически масштабироваться под нагрузкой и без сервера.
В этом уроке мы добавим бэкэнд базы данных SQLite в нашего бота Telegram и позволим ему запоминать информацию для конкретных пользователей на неопределенный срок. Мы создадим простой список дел, который позволит пользователям добавлять новые элементы или удалять существующие.
В Части 1 этого урока мы создали базовый чат-бот Telegram с нуля, используя Python. Наш бот был не слишком умен и просто повторял все, что ему отправляли, обратно пользователю. Созданный нами бот является хорошей основой для широкого спектра возможных ботов, поскольку мы можем принимать входные данные, обрабатывать их и возвращать результат — основу классических вычислений. Однако главным ограничением нашей предыдущей лодки было то, что она не могла хранить какую-либо информацию. У него не было долговременной памяти.
В этом уроке мы добавим бэкэнд базы данных SQLite к нашему боту и позволим ему запоминать информацию для конкретных пользователей бесконечно. Мы создадим простой список дел, который позволит пользователям добавлять новые элементы или удалять существующие.
В дополнение к базовым знаниям Python, необходимым для части 1, было бы неплохо, если бы вы немного познакомились с реляционными базами данных для этого урока. В идеале вы уже должны быть знакомы с такими понятиями, как таблицы, строки, столбцы, и написать по крайней мере базовую инструкцию SELECT * FROM SQL. Но если вы этого не сделали, вы, вероятно, все равно сможете не отставать.
Обзор
В этом уроке мы рассмотрим следующее:
К концу этого урока вы узнаете, как использовать некоторые из более продвинутых функций API Telegram (в частности, функцию пользовательской клавиатуры) и как добавить базу данных SQLite в свои чат-боты.
Создание помощника по базе данных
Мы будем следовать хорошей практике кодирования и держать наш код, связанный с базой данных, отдельно от основной логики нашего бота. Любой код, который касается базы данных, будет ограничен новым сценарием, dbhelper.py и мы импортируем этот скрипт в основной скрипт бота.
Моделирование проблемы
Всякий раз, когда вам нужно создать базу данных, первым шагом является тщательное обдумывание того, как именно вы собираетесь представить проблему. Мы будем следовать итеративному подходу к созданию этого бота, что означает, что на каждом этапе мы сделаем проблему как можно более простой, а затем решим ее, прежде чем повторять проект, чтобы создать более тонкое решение.
Наш Чат-бот должен будет иметь возможность добавить новый элемент в базу данных элементов, которые он запоминает для пользователя, а также должен будет удалить элемент, как только пользователь пометит этот элемент как выполненный. Кроме того, он должен быть в состоянии получить все элементы, чтобы отобразить их пользователю. Наконец, он должен иметь возможность создать таблицу базы данных на случай, если нам понадобится создать новую базу данных (например, при перемещении нашей лодки на новую машину). Вся эта функциональность должна содержаться в вашем dbhelper.py скрипт, так как все это напрямую взаимодействует с базой данных.
В dbhelper.py код
Создайте новый файл с именем dbhelper.py в том же каталоге, что и ваш скрипт чат-бота, и добавьте следующий код:
В этом коде у нас есть пять методов:
- ____in it__() принимает имя базы данных (по умолчанию храните данные в файле с именем todo.sqlite ) и создает соединение с базой данных.
- setup() создает новую таблицу с именем items в нашей базе данных. Эта таблица содержит один столбец (называемый описание )
- add_item() берет текст для элемента и вставляет его в нашу таблицу базы данных.
- delete_item() принимает текст для элемента и удаляет его из базы данных
- get_items() возвращает список всех элементов в нашей базе данных. Мы используем понимание списка, чтобы взять первый элемент каждого элемента, так как SQLite всегда будет возвращать данные в формате кортежа, даже если есть только один столбец, поэтому в этом примере каждый элемент, который мы извлекаем из базы данных, будет похож на ("купить продукты") (кортеж), который понимание списка преобразует в "купить продукты" (простая строка).
Этот класс DBHelper , который мы только что создали, может использоваться нашим Чат-ботом для добавления, удаления и отображения элементов. Давайте изменим код Чат-бота, чтобы использовать эту новую функциональность.
Изменение кода бота
Добавьте следующие две строки в верхней части todobot.py скрипт:
С помощью приведенного выше кода мы можем получить доступ к методам получения, добавления и удаления элементов через переменную db .
Нам также нужно где-то вызвать метод setup() базы данных. Хотя нам нужно сделать это только один раз, и это может быть сделано в отдельном скрипте, мы вызовем его в основной функции нашего бота, чтобы он вызывался каждый раз, когда мы запускаем бота. Потому что, если у вас есть IF NOT EXISTS часть в нашем CREATE TABLE операторе, мы все равно создадим таблицу только один раз.
Добавьте следующую строку кода в начало функции main() :
Тестирование нашей первой попытки составить список дел
Добавление пользовательской клавиатуры Telegram
Добавьте функцию build_keyboard() в todobot.py который возьмет список элементов и построит клавиатуру, чтобы пользователь мог легко удалить элементы.
Нам также нужно научить нашу функцию send_message() включать пользовательскую клавиатуру, когда мы этого хотим. Мы добавим клавиатуру в качестве необязательного параметра в эту функцию, и если она включена, мы передадим клавиатуру вместе с остальной частью вызова API. Измените функцию send_message () , чтобы она выглядела следующим образом:
Выбор времени отправки клавиатуры
Мы не всегда хотим отправлять клавиатуру пользователю. По умолчанию мы хотим, чтобы пользователю было как можно проще добавлять новые элементы в список. Поэтому мы отправим обычную клавиатуру по умолчанию, чтобы позволить пользователю ввести новый элемент для добавления в список, а затем потребуем, чтобы пользователь ввел специальную команду, чтобы пометить элементы как выполненные.
Теперь мы изменим функцию handle_updates () , чтобы отправлять пользовательскую клавиатуру пользователю всякий раз, когда он указывает, что хочет пометить элементы как выполненные. Мы также отправим клавиатуру после того, как пользователь только что отметил элемент, поэтому несколько элементов можно легко удалить подряд. Обновленная функция должна выглядеть следующим образом.
Добавление права собственности на элементы
Мы хотим изменить бота таким образом, чтобы вместо того, чтобы каждый раз возвращать каждый элемент в базе данных, он возвращал только элементы, связанные с определенным chat_id . Для этого нам нужно сохранить chat_id владельца вместе с каждым элементом в базе данных. Поэтому нам нужно добавить еще один столбец в нашу базу данных, а также логику базы данных и логику приложения, чтобы учесть эти изменения.
Обновление dbhelper.py файл
Первые изменения, которые мы внесем, находятся в dbhelper.py файл. Нам нужно обновить:
- Метод setup() для добавления столбца владелец при настройке новой базы данных
- Метод add_item() принимает chat_id (который мы используем для идентификации владельцев) в качестве дополнительного аргумента и добавляет его в базу данных вместе с элементом
- Метод delete_item () , чтобы он удалял только элементы, соответствующие и , принадлежащие указанному владельцу
- Метод get_items() возвращает только элементы, принадлежащие указанному владельцу
Четыре обновленных метода для нашего класса DBHelper можно увидеть ниже.
Обновление todobot.файл py
Изменения здесь проще из-за абстракции, предоставляемой DBHelper . Изменения, которые мы должны внести, находятся в функции handle_updates () , и все, что нам нужно сделать, это передать chat_id вместе с DBHelper всякий раз, когда мы вызываем один из методов, которые мы только что обновили. Новый код для handle_updates() выглядит следующим образом:
Последние штрихи
Проглатывание команд и добавление приветственного текста
Добавьте следующие блоки elif в функцию handle_updates() непосредственно перед текстом elif в строке .
Добавление индексов базы данных
Выбор места размещения индексов баз данных-это классический компромисс между пространством и временем в информатике. Если мы добавим больше индексов, наша база данных часто будет работать быстрее, но займет значительно больше места для хранения. Поскольку мы имеем дело с очень маленькими данными, мы добавим индекс в оба наших столбца. Добавление индекса в столбец owner означает, что метод get_items() будет быстрее, так как он будет быстро получать все элементы от конкретного владельца. Добавление индекса в столбец items означает, что метод delete_item() будет работать быстрее, так как ему не придется искать все элементы пользователя, чтобы найти один из них с соответствующим текстом.
Измените setup() метод Debhelper , чтобы он выглядел следующим образом:
Опять же, мы могли бы просто запустить это один раз как отдельный скрипт, так как индексы будут сохраняться, но неплохо сохранить их в функции setup() на случай, если нам понадобится настроить бота на новой машине или создать новую базу данных по какой-либо причине.
За основу возьмем заготовку, написанную в статье про бота для Telegram на Php, потому что в основном такие сложности возникают у читателей в комментариях этого материала.
Основа
Имеется скрипт-заготовка бота и имеется mysql, а так-же phpmyadmin, который мы и будем использовать для создания базы.
ВНИМАНИЕ! Тут опечатка у поля Name должен быть тип или TEXT или VARCHAR!
Замечу, что все это можно было сгенерить используя SQL, но для простоты делать этого мы тут не будем.
Однако сначала подключение.
Подключение к базе данных
Используем этот файл в начале нашего бота, размещая там строчку
Сохраняем оба файла и переходим на страничку бота. Если там нет ошибок, значит соединение установлено. Собственно файлы бота выглядят вот так теперь:
И на страничке бота ошибок нет:
Модель базы
Теперь делаем обертку для нашей базы данных.
Что нам надо уметь?
Ну вот и пишем нужные нам методы.
Вставка пользователей в базу
Добавим этот метод в файл users.php, который, разумеется, надо сначала создать. Этот файл и будет нашей моделью для работы с базой.
Подключать его надо ниже под db_connect.php, вот так:
Теперь давайте протестируем как работает этот метод. Человек должен добавляться в базу при поступлении от него первой команды. Поэтому лучше всего будет добавить метод make_user в начало секции on то есть вот, примерно, так:
Если у вас уже этот обработчик есть просто добавьте строчку make_user($message->getFrom()->getUsername(),$cid); в нужное место.
Ну и, собственно, сохраняем, а потом пишем что-нибудь боту. Это должно добавить новую запись в таблицу.
Ремарка: у меня phpmyadmin глючит(чинить лень ибо это ни на что не влияет), поэтому внутрь таблицы я зайти не могу(а значит не могу и скриншет содержимого сделать), это исключительно проблема моего собственного сервера, у вас таких проблем быть не должно.
Впрочем это никак не повредит мне в разработке т.к. я отлично представляю себе как работает mysql.
Проверка на наличие пользователя в базе
Для этого будем использовать запрос select и mysql_fetch_array вот так:
Теперь мы можем проверять есть этот пользователь в базе или нет. Делаем в методе on так:
Отлично, теперь сущности не плодятся:
Сохранение пользовательских данных
Теперь надо добавить методы задания настроек пользователем и считывания этих настроек, соответственно. Вообще зачем эти настройки нужны? А нужны они нам для множества разных вещей, от работы с несколькими состояниями бота, до, например, приема отзывов на бота.
Для проверки этих методов засунем в on такой код:
Теперь можно написать что-нибудь в бота и посмотреть на результат. Сначала надпись будет в базу помещена, а потом выдана нам в формате массива.
Все работает, так, как я и задумывал.
Пример использования
Теперь давайте сделаем небольшое взаимодействие с этим инструментарием.
При вызове команды /dbact мы сможем пройти такой вот диалог:
Для подобных сложных взаимодействий, когда надо, например, получить последовательно ряд результатов от пользователя и нужна база данных. Без нее подобные вещи становятся не осуществимыми.
Для примера сделаем возможность пользователю выбирать язык интерфейса (мультиязычность), и соответствующую настройку будем хранить вместе с данными пользователя.
Как организовать сбор данных?
Для начала создадим таблицу users в базе MySQL (используйте кодировку utf8mb4_unicode_ci)
Класс User по работе с таблицей, к нему мы будем обращаться для создания, получения или обновления данных о пользователях.
Добавим новый метод setPdo в класс по организации соединения с СУБД MySQL, сам класс Db вы можете посмотреть в предыдущей статье "Авторизация на сайт через Телеграм без использования официального виджета", также в прикрепленном к статье файле будут все приведенные скрипты.
Вынесем все необходимые в рамках этой статьи методы взаимодействия с Telegram Bot API в отдельный класс Bot, не забудьте заменить ___TOKEN__ВАШЕГО__БОТА___ на токен от своего бота.
Класс при необходимости можно расширить, а методы дополнить, но это на ваше усмотрение.
Добавляем боту мультиязычность
В качестве примера применения базы пользователей сделаем боту мультиязычный интерфейс, для этого необходимо при старте пользователю выводить возможность выбора языка в случае, если ранее им язык не был выбран. Мультиязычность позволит вам как создателю бота расширить круг пользователей, повысить лояльность и соответственно получить больше клиентов.
Класс Lang работает с файлами, которые содержат текстовые данные на разных языках в формате JSON. На сервере сделаем для них отдельную директорию lang и поместим ее в корень.
Структура приложения по итогу будет выглядеть так:
Метод getParam() принимает один обязательный параметр и один необязательный. Обязательный параметр - это ключ в массиве данных языкового файла, по нему мы будем получать значение контента. В качестве не обязательного параметра можно передать массив (ключ - значение) для подстановки необходимых нам динамических данных, например имя пользователя:
Lang.php
Файлы с контентом ru.json и en.json
Переходим к самому интересному, это класс WebHook. После того как пришел запрос от пользователя мы создаем необходимые объекты и отправляем на проверку языковой настройки. В случае если у пользователя еще не выбран язык (это возможно при первом старте бота) то ему выводится предложение со списком языковых настроек. Если у него язык уже выбран, то все данные передаются в роутер, и там в зависимости от команды выполняются необходимые действия. В нашем варианте выводится приветствие.
Еще есть команда на смену языка /lang при ее выполнении пользователю предлагается список на смену языковой настройки.
Index.php - это файл, на который необходимо настроить вебхук.
Заключение
После успешной настройки вышеописанного приложения у вас будет основа для разработки мультиязычного приложения на базе Телеграм. Исходный код можно скачать и использовать на свое усмотрение.
Комментарии
Внимание!
Убедитесь, что эта страница открыта в браузере, а не в приложении Telegram. В противном случае авторизация пройдет только в приложении Telegram.
Читайте также: