Найти тему
Милов Анатолий

В общих деталях про вашего первого Телеграма-бота. Обзор основных решений на Python и nocode

Оглавление

Привет!

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

Боты могут работать 24/7, проводить автоматическую рассылку новостей или акций, автоматически отвечать на вопросы клиентов, управлять бронированиями, информировать клиента о статусе его заказа и так далее...

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

Но перед тем как начать, нужно зайти в @BotFather от Telegram для создания нового бота. После команды /newbot BotFather и небольшо процесса нейминга бота, вам отправится токен аутентификации, который будет использоваться для доступа к Telegram Bot API.

Он понадобится как и в решениях на Питоне, так и на nocode платформах.

С использованием Python

Рассмотри две основные библиотеки - telebot и aiogram.

Telebot

Telebot, также известная как pyTelegramBotAPI, — это популярная библиотека на Python, предназначенная для создания ботов в Telegram. С ней можно легко и просто взаимодействовать с Telegram Bot API.

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

pip install pyTelegramBotAPI

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

TeleBot - основной класс для работы с ботом:

import telebot

bot = telebot.TeleBot('токен')

Message - класс, представляющий сообщение от пользователя:

@bot.message_handler(func=lambda message: True)

def echo_all(message):

bot.reply_to(message, message.text)

InlineKeyboardMarkup, InlineKeyboardButton - классы для создания инлайн-клавиатур:

markup = telebot.types.InlineKeyboardMarkup()

button = telebot.types.InlineKeyboardButton(text="Click me", callback_data="test")

markup.add(button)

bot.send_message(chat_id, "Choose one option:", reply_markup=markup)

ReplyKeyboardMarkup, KeyboardButton - классы для создания обычных клавиатур:

markup = telebot.types.ReplyKeyboardMarkup(row_width=2)

button1 = telebot.types.KeyboardButton("Option 1")

button2 = telebot.types.KeyboardButton("Option 2")

markup.add(button1, button2)

bot.send_message(chat_id, "Choose an option:", reply_markup=markup)

message_handler, callback_query_handler - декораторы для обработки сообщений и нажатий на кнопки инлайн-клавиатур:

@bot.message_handler(commands=['start', 'help'])

def send_welcome(message):

bot.reply_to(message, "How can I help you?")

@bot.callback_query_handler(func=lambda call: True)

def callback_query(call):

bot.answer_callback_query(call.id, "Action received")

send_message - метод для отправки сообщений.

bot.send_message(chat_id, "Hello, bro!")

send_photo, send_audio, send_document, send_video - методы для отправки медиафайлов:

photo = open('photo.png', 'rb')

bot.send_photo(chat_id, photo)

edit_message_text - метод для изменения текста существующего сообщения:

bot.edit_message_text(chat_id=chat_id, message_id=message_id, text="New text")

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

@bot.message_handler(commands=['greet'])

def greet(message):

bot.send_message(message.chat.id, "Hello!")

@bot.message_handler(func=lambda message: message.text.isnumeric())

def handle_number(message):

bot.reply_to(message, f"That's a nice number: {message.text}")

Чтобы бот начал обрабатывать входящие сообщения, необходимо запустить его с помощью метода polling:

bot.polling()

Конечно, это далеко не все возможности Telebot! Подробней можно ознакомиться в документации.

А пока попробуем реализовать простого бота для примера, который позволяет записываться на прием в салон красоты с использованием расписания из базы данных и прочих функций. Для работы с БД нам понадобится sqlalchemy.

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

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

from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey, Boolean

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy.orm import sessionmaker, relationship

from datetime import datetime, timedelta

Base = declarative_base()

class Salon(Base):

__tablename__ = 'salons'

id = Column(Integer, primary_key=True)

name = Column(String)

class Service(Base):

__tablename__ = 'services'

id = Column(Integer, primary_key=True)

name = Column(String)

duration = Column(Integer) # продолжительность услуги в минутах

class Schedule(Base):

__tablename__ = 'schedules'

id = Column(Integer, primary_key=True)

salon_id = Column(Integer, ForeignKey('salons.id'))

service_id = Column(Integer, ForeignKey('services.id'))

date = Column(DateTime) # день и время начала

available = Column(Boolean, default=True) # доступность для записи

salon = relationship("Salon")

service = relationship("Service")

class Appointment(Base):

__tablename__ = 'appointments'

id = Column(Integer, primary_key=True)

schedule_id = Column(Integer, ForeignKey('schedules.id'))

client_name = Column(String)

client_contact = Column(String)

confirmed = Column(Boolean, default=False) # подтверждение записи

schedule = relationship("Schedule")

engine = create_engine('sqlite:///beauty_salon.db')

Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)

session = Session()

Для работы бота мы определим команды: /start, /book:

from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup

from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, CallbackContext, MessageHandler, Filters

import logging

logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)

TOKEN = 'токен бота'

updater = Updater(token=TOKEN, use_context=True)

dispatcher = updater.dispatcher

def start(update: Update, context: CallbackContext):

update.message.reply_text('Добро пожаловать! Введите /book для записи на услугу.')

def book(update: Update, context: CallbackContext):

keyboard = [

[InlineKeyboardButton("Маникюр", callback_data='1')],

[InlineKeyboardButton("Стрижка", callback_data='2')],

[InlineKeyboardButton("Массаж", callback_data='3')]

]

reply_markup = InlineKeyboardMarkup(keyboard)

update.message.reply_text('Выберите услугу:', reply_markup=reply_markup)

def handle_booking(update: Update, context: CallbackContext):

query = update.callback_query

query.answer()

service_id = int(query.data)

# Подгрузим доступные слоты из базы данных

available_slots = session.query(Schedule).filter(Schedule.service_id == service_id, Schedule.available == True).all()

keyboard = [[InlineKeyboardButton(slot.date.strftime("%Y-%m-%d %H:%M"), callback_data=f"slot_{slot.id}")] for slot in available_slots]

reply_markup = InlineKeyboardMarkup(keyboard)

query.edit_message_text(text="Выберите удобное время:", reply_markup=reply_markup)

def confirm_booking(update: Update, context: CallbackContext):

query = update.callback_query

query.answer()

schedule_id = int(query.data.split('_')[1])

update.message.reply_text('Введите ваше имя и контактный телефон в формате: Имя, Телефон')

context.user_data['schedule_id'] = schedule_id # Сохраняем ID для дальнейшего использования

def save_appointment(update: Update, context: CallbackContext

):

user_input = update.message.text.split(',')

if len(user_input) != 2:

update.message.reply_text("Пожалуйста, введите данные корректно.")

return

name, contact = user_input

appointment = Appointment(schedule_id=context.user_data['schedule_id'], client_name=name.strip(), client_contact=contact.strip(), confirmed=True)

session.add(appointment)

session.commit()

update.message.reply_text("Спасибо за вашу запись! Мы ждем вас в назначенное время.")

dispatcher.add_handler(CommandHandler('start', start))

dispatcher.add_handler(CommandHandler('book', book))

dispatcher.add_handler(CallbackQueryHandler(handle_booking, pattern='^\d+$'))

dispatcher.add_handler(CallbackQueryHandler(confirm_booking, pattern='^slot_\d+$'))

dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, save_appointment))

updater.start_polling()

updater.idle()

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

С телеботом более менее понятно, перейдем к следующей библиотке aiogram.

Aiogram

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

Основный компоненты в aiogram аналогичны Телебот:

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

Обработчики представляют собой функции, которые выполняются при получении определенного типа обновления. Например, обработчик текстового сообщения может реагировать на текстовые команды пользователя.

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

Middlewares позволяют выполнять доп. логику до или после обработки обновления, такую как логирование, проверка аутентификации и другие.

Типы определяют различные типы данных, используемые в API телеграма.

Примеры:

Простой бот:

from aiogram import Bot, Dispatcher, types

from aiogram.contrib.middlewares.logging import LoggingMiddleware

from aiogram.utils import executor

API_TOKEN = 'токен'

bot = Bot(token=API_TOKEN)

dp = Dispatcher(bot)

dp.middleware.setup(LoggingMiddleware())

@dp.message_handler(commands=['start'])

async def send_welcome(message: types.Message):

await message.reply("Привет! Я бот!")

@dp.message_handler(commands=['help'])

async def send_help(message: types.Message):

await message.reply("Это помощь.")

if __name__ == '__main__':

executor.start_polling(dp, skip_updates=True)

Обработка текстовых сообщений с фильтром:

from aiogram import Bot, Dispatcher, types

from aiogram.utils import executor

from aiogram.dispatcher.filters import Text

API_TOKEN = 'your_api_token_here'

bot = Bot(token=API_TOKEN)

dp = Dispatcher(bot)

@dp.message_handler(Text(contains='Привет'))

async def greet(message: types.Message):

await message.reply("Привет! Как дела?")

@dp.message_handler(Text(equals='Пока'))

async def say_goodbye(message: types.Message):

await message.reply("Пока! Хорошего дня!")

if __name__ == '__main__':

executor.start_polling(dp, skip_updates=True)

Отправка пикч:

from aiogram import Bot, Dispatcher, types

from aiogram.utils import executor

API_TOKEN = 'your_api_token_here'

bot = Bot(token=API_TOKEN)

dp = Dispatcher(bot)

@dp.message_handler(commands=['send_image'])

async def send_image(message: types.Message):

# путь к файлу изображения

photo_path = 'path_to_your_image.jpg'

# отправка

with open(photo_path, 'rb') as photo:

await bot.send_photo(message.from_user.id, photo, caption='Ваше изображение')

if __name__ == '__main__':

executor.start_polling(dp, skip_updates=True)

Inline-кнопки:

from aiogram import Bot, Dispatcher, types

from aiogram.utils import executor

API_TOKEN = 'токен'

bot = Bot(token=API_TOKEN)

dp = Dispatcher(bot)

@dp.message_handler(commands=['inline'])

async def send_inline_keyboard(message: types.Message):

# Создание объекта InlineKeyboardMarkup

inline_keyboard = types.InlineKeyboardMarkup()

# Добавление кнопок в ряды

inline_keyboard.add(types.InlineKeyboardButton(text='Кнопка 1', callback_data='button1'),

types.InlineKeyboardButton(text='Кнопка 2', callback_data='button2'))

# Отправка сообщения с Inline-клавиатурой

await message.reply("Выберите кнопку:", reply_markup=inline_keyboard)

@dp.callback_query_handler(lambda query: query.data == 'button1')

async def process_callback_button1(callback_query: types.CallbackQuery):

await bot.answer_callback_query(callback_query.id)

await bot.send_message(callback_query.from_user.id, "Вы выбрали кнопку 1")

@dp.callback_query_handler(lambda query: query.data == 'button2')

async def process_callback_button2(callback_query: types.CallbackQuery):

await bot.answer_callback_query(callback_query.id)

await bot.send_message(callback_query.from_user.id, "Вы выбрали кнопку 2")

if __name__ == '__main__':

executor.start_polling(dp, skip_updates=True)

Документация aiogram - https://docs.aiogram.dev/en/latest/.

Перейдем к nocode решениям

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

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

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

Рассмотрим основные платформы для реализации nocode решений.

Botman - конструктор чат ботов и автоворонок

Начнем с первой платформой, которая мне больше зашла по интерфейсу и она в целом отражает всю суть создания nocode решений.

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

После этого мы видим следующую картину:

Те, кто уже имели какой-либо опыт создания ботов на других платформах возможно сразу поймут что здесь. Однако, у тех, кто только начинает вникать в тему телеграм ботов возникнет очевидный вопрос: - "А причем здесь mindmap?".

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

Итак, все начинается с окошка "начало скрипта бота". Здесь мы выбираем некий триггер, на который должен реагировать бот. Этим триггером в основном является слово.

Нажимаем по кнопке "Добавить триггер" и выбираем "Ключевое слово". Пусть оно будет банальным "привет".

-2

Помимо этого можно настроить различные параметры при триггере слова о том, соответствует ли оно на 100% слову или может начинается с него и так далее.

Но особое внимание у большинства интересующихся привяжется к функции триггера на подачу заявки в канал. Да, можно сделать так, чтобы бот сразу отписал новому подписчику и сразу же, к примеру перенаправлять своих подписчиков на второй канал. Сейчас большинство телеграм-каналов именно так и раскручиваются.

Так вот, продолжим. Изначально наше начало сразу привязано к "сообщению 1". И это окошко как раз и отвечает за то, какая реакция поступит от бота. Реакций может быть очень много, например в botman это:

-3

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

Добавим к примеру картинку котика в ответ.

-4

- И все?... Бот, который отправляет котика в ответ?...

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

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

Самое простое - ответить тем же блоком "сообщения", который мы рассмотрели выше. А можно и привязаться к так называемым действиям, которые можно связывать c API других сервисов! Например, к гугл таблицам:

-5

Процесс весьма прост и на самом сервисе есть пошаговые инструкции к этому процессу.

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

Можно также создать временную задержку, именную в ботмане как "умную задержку". С ней можно сделать так, чтобы бот отвечал на предыдущие за ним триггеры не сразу, а например, через 15 минут, секунд или даже дней. С этим можно придумывать неплохие маркетинговые фичи, к примеру, по удержанию клиентов. А также можно составить расписание отправки сообщений. Например, можно настроить, чтобы каждый вторник пользователю бота приходила определенная рассылка.

-6

Помимо всего этого можно создавать рандомные ответы в виде разных блоков или же создавать более сложные линии условий через различные блоки.

multy

Еще один сервис для создания тг ботов, имеет интересное решение по интерфейсу. Он представлен в мультяшно-космическом виде:

-7

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

-8

Настройка бота идет также через блок-схемы как и в ботмане:

-9

Здесь в целом поменьше функций, к примеру нельзя связать блоки через тот же API. Возможно, кому то зайдет такой красочный интерфейс.

В общих чертах создание ТГ-бота выглядит так. Решения через Питон позволяют реализовывать очень крутых и сложных ботов, в чем-то уникальных. А с помощью nocode решений можно быстро пилить ботов для бизнеса, без необходимости разбираться в коде.

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