Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Многие знают, что у пана Снорковского есть крупный чатик. И в такой беседе тяжело запомнить у кого когда день рождения, и у кого какой ник на DTF. Он спросил у меня, как такое автоматизировать, я ему скинул все готовое, а для вас решил сделать такой туториал. Думаю у многих есть разного размера чаты, и возможно вам захочется тоже такого бота себе заиметь. Так еще и сами его сделаете.

Предисловие

Вы положительно откликнулись на прошлый гайд, поэтому я буду делать разные интересные штучки для вас почаще.

И да, кто писал в прошлый раз свои предложения, какой гайд сделать, не переживайте, я все помню, я выписал себе ваши просьбы отдельно, мы до них дойдем, на все нужно время.

Также я запущу серию лонгов "Погромирование для DTFеров", где мы будем с нуля разбирать Python, и потом будем писать на нем всякие разные штучки. Если в гайдах я упускаю объяснение кода и всех нюансов, то тут все будет разложено по полочкам, что бы как можно больше людей могло влиться в это дело. Часто слышу, что программирование это сложно, и что многие хотели бы делать игры, но код их пугает. Я хочу помочь вам развеять ваши сомнения и провести по пути этих цветных непонятных слов как можно понятнее.

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

Подготовка

Если вы какие-то шаги делали еще по прошлому гайду, просто пропускайте их.

Скачиваем Visual Studio Code:

Установка стандартная.

Скачиваем Python:

ОБЯЗАТЕЛЬНО проставьте галочку на "Add Python to PATH". И дальше обычная установка.

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Эти программы есть и на Windows, и на MacOS и на Linux. Просто на эти ссылки кликаете, и на той же странице у вас будет кнопка DOWNLOAD.

Открываем VSCode:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Кликаем по иконке с четырьмя квадратами слева. В поисковой строке пишем "python":

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Скачиваем вот это расширение с цифрой 7 на иконке. Это целый пак базовых расширений.

Теперь в поисковой строке пишем "sqlite3 editor":

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Скачиваем вот это расширение от пользователя yy0931.

Теперь на той же панели слева кликаем по иконке с двумя файликами.

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Пишем код

Создайте на рабочем столе папку (лучше на английском и вместо пробелов используйте _). Ну или где вам удобно. Открывайте ее в редакторе.

File -> Open Folder -> ищем нашу папку на рабочем столе -> Выбрать

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Создадим виртуальную среду. Туда мы будем устанавливать необходимые библиотеки.

Жмем Ctrl + Shift + P или command + Shift + P, в зависимости от вашей ОС. В окне пишем python create environment.

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Кликаем на соответствующую строку.

Тут выбираем Venv. А дальше кликаем на Python, он там у вас один должен быть.

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

В папке нашего проекта должна появиться папка .venv. Это та самая виртуальная среда. Теперь ее нужно активировать.

Кликай на Terminal -> New Terminal

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Внизу открылось волшебное окно.

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

В терминале пишите.

Если у вас Windows:

.venv\scripts\activate

Если MacOS:

source .venv/bin/activate
Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

И жмакаем Enter.

Если все работает, то вы увидите в начале следующей строки (.venv). На винде так это еще и зеленым будет выделятся, точно не пропустите.

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Дальше в том же терминале пишем:

pip install aiogram==3.18

Это библиотека для создания бота в телеграме.

Вот так это будет выглядеть, когда все установиться:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

На этом все, теперь создаем в нашей папке еще одну папку bot.

На имя папки наводитесь, там будут вот такие иконки:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Кликаете на папку с плюсиком, и дальше вводите название папки, как я уже писал выше, bot.

Теперь сделайте вот так:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

В папке bot создайте еще три папки, и два файла: start_bot.py и create_bot.py. Файл можно создать так же как мы создавали папку, рядом будет иконка файлика с плюсиком.

Или нажмите правой кнопкой мыши по папке, и выберите New File...

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

На всякий случай уточню, что файлы __init__.py имеют ДВА нижних подчеркивания по бокам, именно по ДВА, не по одному.

Код для db_handlers -> __init__.py:

from . import admin_db_handlers from . import user_db_handlers

Код для db_handlers -> admin_db_handlers.py:

import sqlite3 from datetime import date def add_new_user(user_info): with sqlite3.connect('database.db') as connection: cursor = connection.cursor() cursor.execute("SELECT username FROM Users WHERE username = ?", (user_info['username'],)) existing_user = cursor.fetchone() if not existing_user: cursor.execute(""" INSERT OR IGNORE INTO Users ( username, name, dtf_link, discord_nickname, twitch_link, steam_link, steam_region, birthday ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) """, (user_info['username'], user_info['name'], user_info['dtf_link'], user_info['discord_nickname'], user_info['twitch_link'], user_info['steam_link'], user_info['steam_region'], user_info['birthday'])) connection.commit() def check_birthday_today(): with sqlite3.connect('database.db') as connection: cursor = connection.cursor() current_date = date.today() current_date = f"{current_date.day}.{current_date.month}" print(current_date) cursor.execute("SELECT username FROM Users WHERE birthday = ?", (current_date,)) existing_users = cursor.fetchall() connection.commit() return existing_users

Код для db_handlers -> create_table.py:

import sqlite3 def create_table(): conn = sqlite3.connect('bot/database.db') cursor = conn.cursor() cursor.execute(''' CREATE TABLE IF NOT EXISTS Users ( user_id INTEGER PRIMARY KEY UNIQUE, username TEXT, name TEXT, dtf_link TEXT, discord_nickname TEXT, twitch_link TEXT, steam_link TEXT, steam_region TEXT, birthday TEXT ) ''') conn.commit() conn.close() if __name__ == '__main__': create_table()

Код для db_handlers -> user_db_handlers.py:

import sqlite3 def get_user_info(username): with sqlite3.connect('database.db') as connection: cursor = connection.cursor() cursor.execute("SELECT * FROM Users WHERE username = ?", (username,)) existing_user = cursor.fetchone() return existing_user

Код для handlers -> __init__.py:

from . import admin_handlers from . import user_handlers

Код для handlers -> admin_handlers.py:

from aiogram.types import Message from aiogram.filters import Command from aiogram.fsm.state import State, StatesGroup from aiogram.fsm.context import FSMContext from settings import prompts from .user_handlers import router from settings.config import ADMIN from db_handlers.admin_db_handlers import add_new_user, check_birthday_today class NewUserForm(StatesGroup): username = State() name = State() dtf_link = State() discord_nickname = State() twitch_link = State() steam_link = State() steam_region = State() birthday = State() @router.message(Command('checkbirthday')) async def cmd_check_birthday(message: Message): if message.from_user.id != ADMIN: return birthday_list = check_birthday_today() if not birthday_list: await message.answer(prompts.NOT_BIRTHDAY_TODAY) return for birthday in birthday_list: await message.answer(prompts.CHECK_TODAY_BIRTHDAY.format(birthday)) @router.message(Command('newuser')) async def cmd_new_user(message: Message, state: FSMContext): if message.from_user.id != ADMIN: return await state.set_state(NewUserForm.username) await message.answer(prompts.ENTER_USERNAME_FORM_MESSAGE) @router.message(NewUserForm.username) async def username_form(message: Message, state: FSMContext): await state.update_data(username=message.text) await state.set_state(NewUserForm.name) await message.answer(prompts.ENTER_NAME_FORM_MESSAGE) @router.message(NewUserForm.name) async def name_form(message: Message, state: FSMContext): await state.update_data(name=message.text) await state.set_state(NewUserForm.dtf_link) await message.answer(prompts.ENTER_DTF_LINK_FORM_MESSAGE) @router.message(NewUserForm.dtf_link) async def dtf_link_form(message: Message, state: FSMContext): await state.update_data(dtf_link=message.text) await state.set_state(NewUserForm.discord_nickname) await message.answer(prompts.ENTER_DISCORD_NICKNAME_FORM_MESSAGE) @router.message(NewUserForm.discord_nickname) async def discord_nickname_form(message: Message, state: FSMContext): await state.update_data(discord_nickname=message.text) await state.set_state(NewUserForm.twitch_link) await message.answer(prompts.ENTER_TWITCH_LINK_FORM_MESSAGE) @router.message(NewUserForm.twitch_link) async def twitch_link_form(message: Message, state: FSMContext): await state.update_data(twitch_link=message.text) await state.set_state(NewUserForm.steam_link) await message.answer(prompts.ENTER_STEAM_LINK_FORM_MESSAGE) @router.message(NewUserForm.steam_link) async def steam_link_form(message: Message, state: FSMContext): await state.update_data(steam_link=message.text) await state.set_state(NewUserForm.steam_region) await message.answer(prompts.ENTER_STEAM_REGION_FORM_MESSAGE) @router.message(NewUserForm.steam_region) async def steam_region_form(message: Message, state: FSMContext): await state.update_data(steam_region=message.text) await state.set_state(NewUserForm.birthday) await message.answer(prompts.ENTER_BIRTHDAY_FORM_MESSAGE) @router.message(NewUserForm.birthday) async def birthday_form(message: Message, state: FSMContext): birthday_text = '' if message.text[0] == '0': birthday_text = message.text[1:] else: birthday_text = message.text await state.update_data(birthday=birthday_text) data = await state.get_data() add_new_user(data) await state.clear() await message.answer(prompts.FORM_SUCCESS_CREATE_MESSAGE)

Код для handlers -> user_handlers.py:

from aiogram import Router from aiogram.filters import Command from aiogram.types import Message from settings import prompts from db_handlers.user_db_handlers import get_user_info router = Router() @router.message(Command('getuserinfo')) async def cmd_get_user_info(message: Message): username = message.text.replace('/getuserinfo', '').strip() user_info = get_user_info(username) await message.answer(prompts.GET_USER_INFO_MESSAGE.format( user_info[1], user_info[2], user_info[3], user_info[4], user_info[5], user_info[6], user_info[7], user_info[8]))

Код для settings -> __init__.py:

from . import config from . import prompts

Код для settings -> config.py:

TOKEN = "ваш токен" ADMIN = 0000000000

Код для settings -> prompts.py:

ENTER_USERNAME_FORM_MESSAGE = "Введите никнейм пользователя без @:" ENTER_NAME_FORM_MESSAGE = "Введите имя пользователя:" ENTER_DTF_LINK_FORM_MESSAGE = "Вставьте ссылку на DTF пользователя:" ENTER_DISCORD_NICKNAME_FORM_MESSAGE = "Введите никнейм пользователя в Discord:" ENTER_TWITCH_LINK_FORM_MESSAGE = "Вставьте ссылку на Twitch пользователя:" ENTER_STEAM_LINK_FORM_MESSAGE = "Вставьте ссылку на Steam пользователя:" ENTER_STEAM_REGION_FORM_MESSAGE = "Введите регион Steam'а пользователя:" ENTER_BIRTHDAY_FORM_MESSAGE = "Введите день рождени пользователя (в формате ДД.ММ):" FORM_SUCCESS_CREATE_MESSAGE = "Пользователь успешно добавлен!" GET_USER_INFO_MESSAGE = "Информация о пользователе {}:\n\nИмя: {}\nDTF: {}\nDiscord: {}\nTwitch: {}\nSteam: {}\nРегион Steam: {}\nДень рождения: {}" CHECK_TODAY_BIRTHDAY = "Сегодня день рождения у {}!" NOT_BIRTHDAY_TODAY = "Сегодня именинников нет."

Что бы это все заработало, вам нужны две вещи.

Первая – создать бота в тг и получить токен.

Пишем BotFather'у:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Тыкаем кнопку Create a New Bot:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Заполняем поля:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Копируем токен:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

И вставляем в файл config.py, токен должен находиться в кавычках:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Второе – ваш айдишник. Пишем боту:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Он вам выдаст ваш айди, копируйте его, и вставляйте вместо нулей в файле config.py:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Запуск

Переходим в файл create_table.py:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Запускаем его, нажав на кнопку запуска справа сверху или нажав на клавишу F5:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Если сверху будут вылазить мини окна, выбирайте там всегда первое, python debugger там будет, например.

Этот файл надо запустить ТОЛЬКО ОДИН РАЗ, он создает локальную базу данных. Она у вас слева появиться в файлах, называется database.db. Нажмите на нее, и при помощи расширения, которое мы устанавливали вначале, файл откроется вот так:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

В будущем вы сможете вручную менять какие-то данные при необходимости.

Теперь в терминале с активированной виртуальной средой пишите:

cd bot

После чего пользователи Windows пишут:

python start_bot.py

А пользователи macOS пишут:

python3 start_bot.py​

Поздравляю, бот запущен, теперь вы можете пользоваться командами:

/checkbirthday – выдает пользователей, у которых сегодня день рождения (может использовать только админ).

/newuser – позволяет добавить в БД нового пользователя (может использовать только админ).

/getuserinfo – выдает информацию о конкретном пользователе. После команды пишите пробел и имя пользователя, о котором хотите больше узнать.

Для того что бы не писать в чат каждый раз команду, вы можете добавить их в список команд, сделать это можно тут:

Гайд: как создать бота для группового чата, который будет выводить инфо участников и напоминать про дни рождения

Переходите в своего бота в BotFather, кликаете Commands, и вот такое окошко будет. Заполните сами команды и их описание. Но команду /getuserinfo все равно надо будет писать ручками, потому что вам надо еще ник дописать.

И не забудьте бота добавить в нужный вам чат.

Ответы на возможные вопросы:

Почему SQLite? Потому что людям для такого бота и не нужна полноценная БД, тем более для гайда, который я старался сделать проще.

Напоминалка о ДР, но ничего не напоминает. Почему надо самому тыкать кнопку что бы узнать у кого день рождения? Потому что бот будет работать в 99,9% случаев у людей на их же компе, и он не будет делать это круглосуточно, следовательно напоминание по времени бессмысленно, но оно все же необходимо.

Вот и все, вот такой получился бот. Надеюсь для кого-то это было полезно. Ну а если у вас что-то не получается, пишите мне в ЛС, я вам помогу чем смогу. В прошлый раз я был приятно удивлен, как много людей мне писали, и я на данный момент помог всем, кроме одного, там совсем тяжело, и дело уже не в боте, надо ковыряться в компе сидеть самому, что б понять в чем дело.

Ну и конечно же пишите, что бы вы еще хотели видеть. Кто писал свои пожелания в прошлый раз, можете не дублировать, я себе все записал уже.

43
3
3
1
1
1
69 комментариев