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