Акмалов Артур

Telegram Bot Python MongoDB Часть 2

telegram-bot-python

Telegram bot python

В первой части изучил основные команды синтаксис по взаимодействию с базой данных MongoDB. Теперь хотелось бы написать простой код для работы телеграм бота с базой данных. Буду использовать aiogram, самая удобная библиотека для создания телеграм ботов, имеет большое русское комьюнити 

Функции бота:

  • Добавление в базу и просмотр списка пользователей с именем и chatid (пригодится если например добавить особые права на команды для бота чтобы только определенные пользователи из этого списка моги пользоваться ботом) 
  • Сохранять сообщения в базу при команде /save (как закладки)

Будущее назначение бота — в большой группе (чате) выделять полезные сообщения и добавлять их в единую telegrpaph страницу, как сборник закладак по тематикам, для того чтобы не создавать закрепленные сообщения с полезными, интересными сообщениями, правилами. и т.д.

Установка Aiogram

Устанавливаю через pip

pip install aiogram 

Python Aiogram MongoDB

Для работы нужно будет создать бота через телеграм BotFather и получить API токен.

Создам еще один файл с конфигурациями в каталоге Python -> config.py

Где будут значения токена, ip адрес, порт, пользователь базы данных

# config.py
TOKEN = '1829713266:AAEFLE4Rg0q70JoGHYrqDuIXR5g'  # Telegram token
mongodbip = '10.127.0.120'  # Mongo DB IP address
mongodbport = 27017  # Mongo Port 
 
  • main.py — основной код
  • config.py — ключи данных

Подтягиваю все что может пригодится

import re # для работы с текстом
import logging
from datetime import datetime # при добавлении в базу использовать время
from pymongo import MongoClient
from config import TOKEN, mongodbip, mongodbport # Конф.значения
from aiogram import Bot, Dispatcher, executor, types
 

прописываю настройки подключения

Буду использовать 2 базы

user — список пользователей

tgsave — список сохраненного текста (закладок)

# MongoDB
client = MongoClient(mongodbip, mongodbport)
db = client['testdb']
users = db['users']
tgsave = db['save']

# Aiogram TG Bot
bot = Bot(token=TOKEN)
dp = Dispatcher(bot) 

Первая команда для проверки работы бота

# Start button
@dp.message_handler(commands=['start'])
async def cmd_random(message: types.Message):
    await message.answer('Бот работает')

    
# Start bot
if __name__ == '__main__':
    executor.start_polling(dp) 

Получение ID можно как боту напрямую писать получить свой ID, или добавив его в группу чтобы узнать id группы. 

# Show user name and id
@dp.message_handler(commands=['id'])
async def cmd_id(message: types.Message):
    if message.chat.id == message.from_user.id:
        await message.answer(f"Your Telegram ID {message.from_user.id}")
    else:
        await message.answer(f"This {message.chat.type} chat ID {message.chat.id}") 

Добавление пользователя в группу users. 

/add Artur 54971358

Добавляет только в случаи если Имя и chatid не пустые (через пробел)

# Add user database
@dp.message_handler(commands=['add'])
async def cmd_random(message: types.Message):
    pattern = re.compile(r'\w+')
    try:
        adduser = pattern.findall(message.text)[1]
        addchatid = pattern.findall(message.text)[2]
    except:
        adduser = None
        addchatid = None

    if addchatid is not None:
        useradd = {
            "name": adduser,
            "chatid": addchatid,
        }
        result = users.insert_one(useradd)
        print(f"Add database id: {result.inserted_id}")
        await message.answer(f'{adduser} {addchatid}') 

Получить список пользователей командой /users

# Print users
@dp.message_handler(commands=['users'])
async def cmd_random(message: types.Message):
    userslist = 'Список пользователей:\n'
    for x in users.find():
        name = x['name']
        chatid = x['chatid']
        userslist += str(name) + ' ' + str(chatid)+'\n'
    await message.answer(f'{userslist}') 

Проверка

Создал функцию для записи в базу данных tgsave. Любое интересное сообщение в группе или отправленное боту. Без разницы чье это сообщение, выбираю нажимаю ответить ввожу команду /save и бот сохраняет сообщение на которое я ответил.

# Function to insert database tgsave
def saver(data):
    return tgsave.insert_one(data).inserted_id

# Saver
@dp.message_handler(content_types=['text'])
async def main(message: types.Message):
    if message.chat.id is not None: #Если сообщение из чата
        if message.reply_to_message is not None: #Если это ответ на сообщение
            if message.text == 'save':
                data = {
                    "user": message.chat.username,
                    "text": message.reply_to_message.text,
                    'time': datetime.today()
                }
                print(saver(data))
                await message.reply(f'Сохранил')

    elif message.reply_to_message is not None: #Если это ответ на сообщение
        if message.text == 'save':
            data = {
                "user": message.from_user.username,
                "text": message.reply_to_message.text,
                'time': datetime.today()
            }
            print(saver(data))
            await bot.send_message(message.from_user.id, f'Сохранил')
        else:
            await bot.send_message(message.from_user.id, f'Непонял что делать')
    else:
        print(message.text) 

Если боту писать в личку добавляет в базу имя пользователя если писать через группу, то название группы.

Для работы в группе(чате) необходимо через BotFather в настройках бота разрешить чтение сообщений в группах.

MongoDB сам понимал какие типы данных я передаю. например chatid можно передать как int, дату также сразу изменил на тип date в БД.

Подготовка файлов

Планируется собрать докер образ, для этого необходима вытащить все используемые библиотеки с версиями.

pip freeze > requirements.txt 

Далее планирую вывести Telegram Token, данные для подключения к MongoDB вывести в .env файл. И написать docker-compose для сборки telegram bot python

Подписаться
Уведомить о
guest
0 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии