База данных пользователей
Anton YurashПредисловие
Почти всегда хочется иметь возможность видеть список всех пользователей бота, чтобы собирать статистику. Также было бы круто иметь возможность делать рассылки пользователям бота, к примеру уведомление о технических работах, что бот не будет корректно работать несколько часов, или рекламную рассылку, если вашим ботом пользуется много людей.
Для получения списка всех пользователей бота, к сожалению у телеграмма нет api и нам придется решать это своими усилиями. Для этого будем использовать базу данных. Часто для ботов используют реляционные базы данных: SQLite, PostgreSQL. Но чтобы разобраться с ними и научится работать корректно нужен не один час, а большинство фич их широкого функционала вы не будете использовать в процессе разработки ботов.
По этому в свое время я решил использовать нереляционную MongoDB. Чтобы установить ее на свой линукс и разобраться с ней я потратил минут 30, при том что до этого я не работал вообще ни с какими базами данных.
Спустя несколько лет и перепробовав несколько разных БД я только убедился что мое решение в свое время было правильным. Единственной БД, которую я использовал на продакшне в боте помимо MongoDB был Redis. У него есть преимущество - он значительно быстрее любых других баз данных (данные хранятся в оперативной памяти, а не в статической, как во остальных БД), но его минус - отсутствие некоторых привычных контейнеров и данные приходится декодировать ибо они хранятся в байтах.
Установка MongoDB
Windows
Открываем консоль как в первом уроке. (Win+R -> "cmd" -> enter).
wmic os get caption wmic os get osarchitecture
Так мы узнаем какая у нас ОС и архитектура. Зависимо от этих данных качаем отсюда .msi установщик. Кликаем на установщик и ставим себе MongoDB.
Linux
Для последних релизов Ubuntu/Debian есть очень простое решение как установить и добавить в автозапуск MongoDB. Открываем терминал и пишем:
sudo apt-get install mongodb
Готово.
Для других дистрибутивов переходим по ссылке.
MacOS
Качаем бинарь отсюда.
Разархивируем через терминал:
tar -zxvf mongodb-osx-ssl-x86_64-3.6.4.tgz
Создаем папку и копируем:
mkdir -p mongodb cp -R -n mongodb-osx-ssl-x86_64-3.6.4/ mongodb
Добавляем ее в PATH:
export PATH=<mongodb-install-directory>/bin:$PATH
Если есть brew:
brew update brew install mongodb
Подключаем MongoDB в наш проект
Устанавливаем пакет Python
Надеюсь у вас корректная структура проекта, и/или вы прошли этот урок.
Открываем проект и добавляем в requirements.txt
pymongo
После этого вводим:
sudo pip3 install -r requirements.txt
Все. Мы установили пакет для python для работы с нашей базой данных.
Пишем код добавления пользователей в базу данных
Создаем файл db.py
. Пишем в него такой код:
import pymongo client = pymongo.MongoClient('mongodb://localhost/tutorial_bot') users_db = client.get_database()["users_db"]
Таким образом мы создали базу "tutorial_bot", подключились к ней и создадим коллекцию "users_db" как только запишем в нее первого юзера.
Чтобы сделать добавление пользователя в базу данных после того как он впервые написал боту (нажал Start) добавим такой код в bot_handlers.py:
Импорт:
from db import users_db
В функцию def send_welcome(message)
:
if not users_db.find_one({"chat_id": message.chat.id}): users_db.insert_one({"chat_id" : message.chat.id})
Проверили, есть ли пользователь в базе и если его там нет, то добавляем. Для рассылок достаточно знать chat id
.
Применение
Можем сделать интереснее - если пользователь нажал /start впервые - говорить "Добро пожаловать в бота", а если не впервые - говорить ему "Снова привет!)" Так мы применим нашу базу данных и сможем ее протестировать.
Добавим новое сообщение в messages.py
:
HELLO_MESSAGE = 'Добро пожаловать в нашего бота!' HELLO_AGAIN_MESSAGE = 'Снова привет!)'
В bot_andlers.py
добавим нашу логику:
from bot import bot # Импортируем объект бота from messages import * # Инмпортируем все с файла сообщений from db import users_db # Импортируем базу данных @bot.message_handler(commands=['start']) def send_welcome(message): # Если пользователя нет в базе if not users_db.find_one({"chat_id": message.chat.id}): users_db.insert_one({"chat_id" : message.chat.id}) bot.send_message(message.chat.id, HELLO_MESSAGE) # Если пользователь есть в базе else: bot.send_message(message.chat.id, HELLO_AGAIN_MESSAGE) @bot.message_handler(content_types=["text"]) # Любой текст def repeat_all_messages(message): bot.send_message(message.chat.id, message.text) if __name__ == '__main__': bot.polling(none_stop=True)
Вот и все, запускаем бота и проверяем. Должно получится вот так:
На всякий случай вот код урока на github.
Спасибо за внимание!
<- Вторая часть | Четвертая часть ->
Все части обучения:
- Наш первый бот
- Структура проекта бота (создаём проект)
- База данных пользователей
- Рассылки