База данных пользователей

База данных пользователей

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.

Спасибо за внимание!

Anton Yurash

<- Вторая часть | Четвертая часть ->

Все части обучения:

  1. Наш первый бот
  2. Структура проекта бота (создаём проект)
  3. База данных пользователей
  4. Рассылки