Структура Телеграмм бота на python

Пошаговое руководство написания чат-бота на языке Python.

  • Установим Python и библиотеки;
  • Получим вопросы и ответы из БД PostgreSQL;
  • Подключим морфологию;
  • Подключим чат-бот к каналу Telegram.

Colaboratory от Google

Изучение Python можно начать используя сервис Colaboratory от Google, или просто Colab. Сервис позволяет писать и выполнять код Python в браузере, не требуя собственного сервера.

Пример кода. Вопросы и ответы для чат-бота подгрузим с https://drive.google.com из текстового файла

# Однократно после запуска виртуальной машины устанавливаем библиотеки pymorphy2 и numpy !pip install pymorphy2 numpy # —————————- # подключим библиотеки import csv import pymorphy2 import re morph = pymorphy2.MorphAnalyzer(lang=’ru’) # Массив вопросов questions=[] # Массив ответов answer=[] # Подключаем файл с Google диска, содержащий вопросы/ответы # Есть ли жизнь на марсе;Есть with open(«/content/drive/MyDrive/robo-bot/question.txt», «r») as f_obj: reader = csv.reader(f_obj) for row in reader: r=s.split(‘;’) questions.append(r[0]) answer.append(r[1]) # выведем список вопросов и ответов print (questions) print (answer)

Запуск в Production

Наигравшись с кодом в Colaboratory и освоив Python развернем систему на боевом сервере Debian

Разработка Telegram Bot на Python. (1.1 Структура проекта)

Установим Python и PIP (установщик пакетов).

Так как Debian не самый новый, устанавливается версия 3.5

aptitude install python3 python3-pip # обновим пакеты если они были установлены ранее pip3 install —upgrade setuptools pip

Установим необходимые пакеты Python

# Из за устаревшей версии Debian установить psycopg2 не удалось, поставлен скомпилированный psycopg2-binary # Библиотека psycopg2 нужна для подключения к базе данных PostgreSQL # pip3 install psycopg2 pip3 install psycopg2-binary scikit-learn numpy pymorphy2

Пишем код в файле Chat_bot.py

# Импортируем библиотеки import pymorphy2 import re import psycopg2 import sklearn import numpy as np # Подключаемся к PostgreSQL conn = psycopg2.connect(dbname=’energy’, user=’mao’, password=’darin’, host=’localhost’) cursor = conn.cursor() # Настраиваем язык для библиотеки морфологии morph = pymorphy2.MorphAnalyzer(lang=’ru’) # объявляем массив кодов ответов и ответов answer_id=[] answer = dict() # получаем из PostgreSQL список ответов и проиндексируем их. # Работая с PostgreSQL обращаемся к схеме app, в которой находятся таблицы с данными cursor.execute(‘SELECT id, answer FROM app.chats_answer;’) records = cursor.fetchall() for row in records: answer[row[0]]=row[1]

Структура таблицы ответов chats_answer, формат SQL

CREATE TABLE app.chats_answer ( id SERIAL, answer VARCHAR(512), CONSTRAINT chats_answer_pkey PRIMARY KEY(id) ) WITH (oids = false); ALTER TABLE app.chats_answer OWNER TO mao;

Да, я готов об этом поговорить

Я тоже хочу спать

Продолжаем код в файле Chat_bot.py

# объявляем массив вопросов questions=[] # загрузим вопросы и коды ответов cursor.execute(‘SELECT question, answer_id FROM app.chats_question;’) records = cursor.fetchall() # посчитаем количество вопросов transform=0 for row in records: # Если текст вопроса не пустой if row[0]>»»: # Если в БД есть код ответа на вопрос if row[1]>0: phrases=row[0] # разбираем вопрос на слова words=phrases.split(‘ ‘) phrase=»» for word in words: # каждое слово из вопроса приводим в нормальную словоформу word = morph.parse(word)[0].normal_form # составляем фразу из нормализованных слов phrase = phrase + word + » » # Если длинна полученной фразы больше 0 добавляем ей в массив вопросов и массив кодов ответов if (len(phrase)>0): questions.append(phrase.strip()) answer_id.append(row[1]) transform=transform+1 # выведем на экран вопросы, ответы и коды ответов print (questions) print (answer) print (answer_id) # Закроем подключение к PostgreSQL cursor.close() conn.close()

Векторизация и трансформация

# Векторизируем вопросы в огромную матрицу # Перемножив фразы на слова из которых они состоят получим числовые значения from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.decomposition import TruncatedSVD vectorizer_q = TfidfVectorizer() vectorizer_q.fit(questions) matrix_big_q = vectorizer_q.transform(questions) print («Размер матрицы: «) print (matrix_big_q.shape) # Трансформируем матрицу вопросов в меньший размер для уменьшения объема данных # Трансформировать будем в 200 мерное пространство, если вопросов больше 200 # Размерность подбирается индивидуально в зависимости от базы вопросов, которая может содержать 1 млн. или 1к вопросов и 1 # Без трансформации большая матрицу будет приводить к потерям памяти и снижению производительности if transform>200: transform=200 svd_q = TruncatedSVD(n_components=transform) svd_q.fit(matrix_big_q) # получим трансформированную матрицу matrix_small_q = svd_q.transform(matrix_big_q) print («Коэффициент уменьшения матрицы: «) print ( svd_q.explained_variance_ratio_.sum())

Функция поиска ответа

Как ИДЕАЛЬНО писать БОТОВ на PYTHON | Aiogram & Nextcord


# Тело программы поиска ответов from sklearn.neighbors import BallTree from sklearn.base import BaseEstimator def softmax(x): #создание вероятностного распределения proba = np.exp(-x) return proba / sum(proba) class NeighborSampler(BaseEstimator): def __init__(self, k=5, temperature=10.0): self.k=k self.temperature = temperature def fit(self, X, y): self.tree_ = BallTree(X) self.y_ = np.array(y) def predict(self, X, random_state=None): distances, indices = self.tree_.query(X, return_distance=True, k=self.k) result = [] for distance, index in zip(distances, indices): result.append(np.random.choice(index, p=softmax(distance * self.temperature))) return self.y_[result] from sklearn.pipeline import make_pipeline ns_q = NeighborSampler() # answer_id — код ответа в массиве, который получается при поиске ближайшего ответа ns_q.fit(matrix_small_q, answer_id) pipe_q = make_pipeline(vectorizer_q, svd_q, ns_q)

Еще по теме:  Боты Телеграмм которые отсеживают аремя арибывания онлайн в Whatsapp

Проверка из консоли

# код для проверки работы из консоли print(«Пишите ваш вопрос, слова exit или выход для выхода») request=»» while request not in [‘exit’, ‘выход’]: # получим текст от ввода request=input() # разберем фразу на слова words= re.split(‘W’,request) phrase=»» for word in words: word = morph.parse(word)[0].normal_form # морфируем слово вопроса в нормальную словоформу # Нормализуем словоформу каждого слова и соберем обратно фразу phrase = phrase + word + » » # запустим функцию и получим код ответа reply_id = int(pipe_q.predict([phrase.strip()])) # выведем текст ответа print (answer[reply_id])

Запустим и проверим

python3 Chat_bot.py

Подключим Telegram

# установим не самую последнюю версию для валидности дальнейшего кода #pip3 install PyTelegramBotAPI pip3 install PyTelegramBotAPI==3.6.7

Все просто, зарегистрируем нового бота и получим token.

В целом все готово. Вопросы в базу данных добавляются автоматически от службы тех. поддержки. Остаётся маркетологу в админ панели на YII назначать ответы вопросам. Раз в сутки cron перезапускает скрипт чат-бота, новые фразы поступают в работу.

Весь код чат бота

В теле программы есть переменные k=5 и temperature=10.0. Их можно менять, что будет влиять на поиск, делая его более мягким или более жестким.

P.S. Умышленно привожу весь код для практики. Теорию машинного обучения с картинками можно почитать, например, в другой статье.

Источник: temofeev.ru

Про шаблон структуры телеграмм-бота. Разработка на Python. Часть третья

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

Для тех кто пропустил:

Написание телеграм-бота на Python. Часть первая
Vorontsoff 23 сентября 2022
Написание телеграм-бота на Python. Часть вторая

Vorontsoff 24 сентября 2022

Шаблон представляет собой вот такую структуру папок и файлов, начнем с корня проекта:

В корневой директории находятся два файла main.py (из этого файла бот запускается) и loader.py (из него подгружаются нужные боту переменные). Более подробно об этих файлах:

  • main.py по строкам:
    1. импорт бота из файла loader.py
    2. импорт папки обработчиков сообщений (хэндлеров)
    3. импорт команд которые будут вызываться из кнопки «Меню»
    6. установка в кнопку «Меню» команд
    7. бесконечный запуска бота
  • loader.py по строкам:
    1-3. Подгружаем необходимые модули для создания бота
    5. Создаем глобальную переменную для хранения состояний пользователя внутри сценария
    6. создается сам объект бота
  • .gitignore
    Игнорируемые файлы отслеживаются в специальном файле .gitignore, который регистрируется в корневом каталоге репозитория. В Git нет специальной команды для указания игнорируемых файлов: вместо этого необходимо вручную отредактировать файл .gitignore, чтобы указать в нем новые файлы, которые должны быть проигнорированы и не отправлены на сервер. Например файл .env, в котором содержатся ключи
  • requirements.txt этот файл нужен для того чтобы указать какие дополнительно используются модули. Которые нужно установить командой :
    pip install -r requirements.txt
  • .env здесь находятся наши токены и ключи для доступа к телеграмм-боту и сайту поиска отелей.

Переходим к папке config_data :

  • __init__.py файл может быть как пустым так и с кодом внутри него. Присутствие данного файла в папке делает её уже не просто папкой а пакетом. Команды которого будут доступны через точку.
  • config.py по строкам:
    1-2 импорт нужных элементов
    4-7 проверка на наличие файла с паролями .env , если файл не найден то работа интерпретатора прекращается с выводом соответствующего сообщения.
    Либо продолжаем работу и загружаем нужные нам пароли для доступа телеграмм и сайту hotels.com

database — в данной папке (пакете) будет храниться всё что отвечает за базы данных, в которых будет храниться история поиска.

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

keyboards — здесь будут храниться все клавиатуры которые будут взаимодействовать с пользовательским вводом.

states — отвечает за инициализацию класса состояний пользователя внутри сценария. Когда вы хотите чтобы пользователь проходил разные этапы ввода данных — используются эти состояния. Чтобы было удобно понимать следующие шаги и чтобы бот понимал в каком хендлере ему дальше работать.

utils — в этой папке хранятся вспомогательные модули, например файл set_bot_commands.py в котором генерируются стандартные команды кнопки «меню». Которые берутся из папки config_data и файла config.py

Шаблон на первый взгляд кажется большим и сложным, но при более детальном изучении, всё оказывается очень просто. Подобные шаблоны нужны как раз для того, чтобы упорядочить всевозможные события и реакции на них. Со временем программа растет, обрастает различными «фишками», функциями и чем дальше, тем трудней ориентироваться в одном файле main.py. Поэтому программа разбита на логические кусочки которые переплетаются между собой.

Вот вроде бы и всё по шаблону. Я еще сам в этом не просто «чайник» а «мегасамовар», я пытаюсь во всем этом разобраться и понять, и если где-то допускаю неточность — ну сорян! Все мы люди, все мы человеки.

Еще по теме:  Как отправить Телеграмму на увольнение через почту России

Как-то так, всем счастья, любви и здоровья. А деньги заработаем.

Источник: dzen.ru

За границей Hello World: полный гайд по разработке Telegram ботов с помощью Python и Aiogram 3. Часть 1

Захотев однажды научиться разрабатывать ботов для Telegram на языке программирования Python, я просто зашёл в Яндекс и вбил что-то вроде «telegram бот на python для новичков» и нашёл казалось бы огромное множество гайдов и туториалов. Однако копнув немного глубже стало понятно, что большая часть гайдов заканчивается на прикреплении клавиатур к сообщениям, или ещё хуже, на написании эхо-бота.

Пришлось копаться в документации, шерстить форумы и учиться на примерах кода с GitHub. Этот гайд создан как полное руководство по разработке полноценного Telegram бота для работы с нейросетями, такими как ChatGPT и Dall-e, начиная установкой IDE и получением токена и заканчивая подключением оплаты, базы данных и загрузки бота на сервер.

Я считаю что гайд будет полезен прежде всего тем, кто уже пробовал разобраться в теме и имеет базовые знания. Чтобы гайд был полезным необходимо иметь базовые знания в Python, всё остальное вы можете изучить в процессе. Продвинутым разработчикам ботов большая часть будет знакома и вряд ли принесёт пользу, однако есть шанс, что и вы найдёте для себя что-то полезное. Жду любую конструктивную критику как по коду и его стилю, так и по изложению.

Что мы получим в итоге?

В конце гайда у нас получится полностью функционирующий бот, с админкой, оплатой, базой данных, реферальной программой и подключенным API OpenAI. По мере выхода статей код будет появляться в репозитории на GitHub.

Используемые технологии

Будут использованы следующие технологии:

  • VS Code (или любой другой удобный редактор или IDE)
  • Python
  • Aiogram 3
  • PostgreSQL
  • API OpenAI

Подготовка окружения

Разработка любой программы начинается с подготовки среды, так что приступим. Для начала устанавливаем VS Code или любую другую вашу любимую IDE или редактор кода. Скачиваем установщик с сайта, запускаем, устанавливаем. По умолчанию среда уже готова к работе, но рекомендую установить дополнительные расширения для Python, а также по желанию темы и другие плюшки.

Конечно же надо установить сам Python, но раз вы читаете это, то уверен, что либо уже сделали это, либо разберётесь сами. Скажу лишь, что использую версию 3.10, однако код также должен работать на версиях Python 3.8 и выше.

В VS Code переходим на вкладку Git, скачиваем и устанавливаем Git. Далее инициализируйте репозиторий и желательно опубликуйте его на GitHub (для удобства дальнейшей работы), это можно сделать прямо из VS Code.

Создание и публикация репозитория на GitHub

После этого создадим виртуальное окружение, чтобы не засорять пакетами глобальyую среду. Подробнее про виртуальные окружения и преимущества их использования можете почитать здесь. Открываем палитру команд (Ctrl-Shift-P на Windows) и запускаем команду Python: Create Environment .

Далее выбираем venv и интерпретатор Python. Чтобы активировать виртуальное окружение, в терминале выполните команду ..venvScriptsactivate . Также выберите интерпретатор Python по умолчанию.

Выбранный интерпретатор должен находиться в папке .venv

Выбор интерпретатора по умолчанию

Теперь пришло время установить все используемые библиотеки. Их список вы можете найти у меня на github. Там же я буду выкладывать весь код по мере выхода статей. Если вы скачали файл, то установить библиотеки можно командой:

pip install -r requirements.txt

Обратите внимание что мы будем использовать aiogram версии 3, который ещё находится в бета-тестировании, 3 версия НЕ совместима с предыдущими, так что не забывайте об этом.

Следующий шаг — установка PostgreSQL. Сама установка не является чем-то сложным, поэтому не будем её подробно рассматривать. Для более удобной работы с базами данных можете установить графический клиент, такой как pgAdmin (идущий в комплекте с PostgreSQL), DBeaver или Navicat, самый удобный и используемый мною каждый день в работе (имеет бесплатную пробную версию).

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

Создание структуры

Наш бот будет разделён на несколько логических частей — файлов. Можно писать весь код в одном файле — он будет также работать, однако отладка и поиск нужной функции или класса станет сущим адом.

Файловая структура нашего бота:

  • main.py — точка входа, код запуска бота и инициализации всех остальных модулей
  • config.py — файл со всеми конфигурационными параметрами, такими как токен бота и данные подключения к БД. Хранение настроек в Python-файле является не самой лучшей практикой, однако если настройки меняются очень редко, то такой способ является самым простым. Можно также хранить настройки в переменных окружения или специальных файлах (ini, json) и через config.py лишь предоставлять абстракцию данных, однако в этом боте будет использован самый простой способ
  • db.py — функции подключения и работы с базой данных. Данный файл будет являться абстракцией базы данных от основного кода
  • text.py — все тексты, используемые ботом. В этом файле будут лежать все приветствия, сообщения об ошибках и другие текстовые данные для бота. Хранение текста в Python-файле также является не лучшей практикой, так как изменить тексты можно только через код, однако тексты меняются не так часто (чаще всего никогда), поэтому снова пойдём самым простым путём
  • kb.py — все клавиатуры, используемые ботов. В этом файле будут находиться абсолютно все клавиатуры, как статические, так и динамически генерируемые через функции
  • middlewares.py — название файла говорит само за себя. В этом файле будут лежать все используемые мидлвари (их будет всего две)
  • states.py — будет хранить вспомогательные классы для FSM (машины состояний), а также фабрики Callback Data для кнопок Inline клавиатур
  • utils.py — различные функции. В этом файле будут лежать функции для рассылки, генерации текста и изображений через API и другие
  • handlers.py — основной файл, в котором будет содержать почти весь код бота. Будет состоять из функций-обработчиков с декораторами (фильтрами)
  • admin.py — обработчики событий, клавиатуры, классы и весь остальной код админки бота. Опять же если придерживаться лучших практик, стоило бы вынести это в отдельную папку, в которой уже создать модули клавиатур, текстов, хэндлеров (обработчиков) и всего остального. Наша админка будет иметь базовый функционал, поэтому реализуем всё в одном файле
Еще по теме:  Боты ии по написанию эссе в Телеграм

В итоге ваша папка должна выглядеть так:

Получение токена

На эту тему написано настолько много материала, что крайне не хочется дублировать его, поэтому дам краткую инструкцию по получению токена:

  1. Запустите бота BotFather
  2. Создайте бота командой /newbot
  3. Следуя указаниям бота введите все данные, типа названия
  4. Скопируйте токен и вставьте его в переменную BOT_TOKEN в файле config.py

Можно также произвести настройку бота в BotFather, к примеру настроить описание, аватарку и другие параметры.

Пишем первый код!

Теперь, когда все подготовительные действия сделаны, можем приступить к написанию кода. Мы не будем писать эхо-бота, а сразу перейдём к чему-то более полезному — бот, отправляющий пользователю его ID.

В файле main.py пишем следующий код:

import asyncio import logging from aiogram import Bot, Dispatcher from aiogram.enums.parse_mode import ParseMode from aiogram.fsm.storage.memory import MemoryStorage import config from handlers import router async def main(): bot = Bot(token=config.BOT_TOKEN, parse_mode=ParseMode.HTML) dp = Dispatcher(storage=MemoryStorage()) dp.include_router(router) await bot.delete_webhook(drop_pending_updates=True) await dp.start_polling(bot, allowed_updates=dp.resolve_used_update_types()) if __name__ == «__main__»: logging.basicConfig(level=logging.INFO) asyncio.run(main())

Сначала мы импортируем все нужные нам классы и модули:

  • asyncio — для асинхронного запуска бота
  • logging — для настройки логгирования, которое поможет в отладке
  • aiogram — основной модуль библиотеки aiogram, из которого мы импортируем классы Bot и Dispatcher
  • aiogram.enums.parse_mode — содержит настройки разметки сообщений (HTML, Markdown)
  • aiogram.fsm.storage.memory — хранилища данных для состояний пользователей
  • config — настройки бота, пока что только токен
  • handlers — пока пустой, но скоро мы напишем в нём функционал нашего бота

Затем мы объявляем функцию main() , в которой будет запускаться бот. Далее мы создаём объект бота с нашим токеном. Обратите внимание на параметр parse_mode , он отвечает за используемую по умолчанию разметку сообщений. Мы используем HTML, чтобы избежать проблем с экранированием символов.

Затем мы создаём объект диспетчера, параметр storage=MemoryStorage() говорит о том, что все данные бота, которые мы не сохраняем в БД (к примеру состояния), будут стёрты при перезапуске. Этот вариант является оптимальным, так как хранение состояний диспетчера требуется редко.

Строка dp.include_router(router) подключает к нашему диспетчеру все обработчики, которые используют router, их вы увидите в следующем файле. Строка await bot.delete_webhook(drop_pending_updates=True) удаляет все обновления, которые произошли после последнего завершения работы бота. Это нужно, чтобы бот обрабатывал только те сообщения, которые пришли ему непосредственно во время его работы, а не за всё время. следующая строка запускает бота. Давайте запустим и проверим, как работает наш бот. После запуска вы должны увидеть следующий вывод в лог:

Логи при успешном запуске бота

Это означает, что наш бот запущен и слушает обновления, однако пока что он ничего не делает, так как мы не добавили ни одного обработчика. Давайте исправим это, написав в файле handlers.py следующий код:

Второй обработчик реагирует на все сообщения, так как у него не задан ни один фильтр. В теле функции мы снова отвечаем пользователю сообщением и подставляем в него значение msg.chat.id . Запустим снова код и посмотрим на результат. Обратите внимание, что запускать надо не handlers.py, а main.py, так как именно он является точкой входа в нашу программу. В консоли снова появится аналогичное сообщение об успешном запуске бота, можно перейти в чат с ботом и отправить ему команду /start .

Рейтинг
( Пока оценок нет )
Загрузка ...