Сегодня, мы будем писать Telegram Bot с заявкой. Например: Пользователи заполняют анкеты и после эти данные отправляются Администратору.
Для этого мы будем использовать библиотеку pyTelegramBotAPI (telebot).
pyTelegramBotAPI - это легкая и хорошая библиотека для написания Telegram Bot!
Установка библиотеки
Для установки на Windows самой библиотеки telebot нам понадобиться открыть cmd или терминал и написать:
pip install pyTelegramBotAPI
Для установки на macOS нужно написать:
pip3 install pyTelegramBotAPI
Начало кода
Для начало необходимо получить наш токен бота. Для этого нужно перейти в @BotFather и создать бота. После вы получите токен и его нужно вставить его в переменную TOKEN которую мы сейчас создадим, вставить нужно вместо YOUR_TOKEN .
И так, импортируем сначала саму библиотеку:
import telebot
TOKEN = 'YOUR_TOKEN'
ADMIN_ID = 'YOUR_ID'
В переменной TOKEN мы будем хранить наш токен полученный от BotFather
В переменной ADMIN_ID нам нужно вставить наш айди от аккаунта телеграм. Ваш ID можно узнать через бота @getmyid_bot
Теперь давайте напишем приветствие бота:
import telebot
TOKEN = 'YOUR_TOKEN'
ADMIN_ID = 'YOUR_ID'
bot = telebot.TeleBot(TOKEN)
name = None
username = None
user1_mess = None
user2_mess = None
user3_mess = None
@bot.message_handler(commands=['start'])
def start_message(message):
global name, username
name = message.from_user.first_name
username = message.from_user.username
bot.send_message(message.chat.id, "Привет! Это бот для заявок. Чтобы подать заявку, заполните анкеты")
bot.polling()
У нас есть 4 переменных. Переменные name и username делаем глобальными и в них нужно хранить username пользователя от телеграмма и имя. Теперь давайте проверим, работает ли наш бот. Для этого сначала нужно в конце кода написать:
bot.polling()
Как мы видим, бот работает!
Теперь давайте приступим к анкетам:
import telebot
TOKEN = 'YOUR_TOKEN'
ADMIN_ID = 'YOUR_ID'
bot = telebot.TeleBot(TOKEN)
name = None
username = None
user1_mess = None
user2_mess = None
user3_mess = None
@bot.message_handler(commands=['start'])
def start_message(message):
global name, username
name = message.from_user.first_name
username = message.from_user.username
bot.send_message(message.chat.id, "Привет! Это бот для заявок. Чтобы подать заявку, заполните анкеты")
form1(message)
И да, в функции start_message в конце не забываем написать form1(message)
благодаря которому после приветствия перекидывает нас на следующую функцию, которую мы сейчас и создадим.
Давайте напишем первый вопрос:
def form1(message):
bot.send_message(message.chat.id, "1. Как вас зовут?")
bot.register_next_step_handler(message, form2)
Благодаря коду bot.register_next_step_handler(message, form2)
бот ждет, пока пользователь не отправит сообщение, и после его отправки переходит к следующей функции form2, сейчас мы его и создадим
Делаем вторую функцию:
def form2(message):
global user1_mess
user1_mess = message.text
bot.send_message(message.chat.id, "2. Сколько вам лет?")
bot.register_next_step_handler(message, form3)
Делаем переременную user1_mess глобальным и меняем его значение на message.text. В нем будет храниться текст пользователя. Эта переменная хранит текст введенный в предыдущей фукции.
Также делаем и с третьей функцией:
def form3(message):
global user2_mess
user2_mess = message.text
bot.send_message(message.chat.id, "3. Укажите номер телефона:")
bot.register_next_step_handler(message, result)
Вы наверное заметили, что в коде bot.register_next_step_handler(message, result)
на этот раз указывает на функцию result. Давайте его создадим
Делаем функцию result:
def result(message):
global user3_mess
user3_mess = message.text
bot.send_message(message.chat.id, "Спасибо за заявку! Скоро наш менеджер свяжется с вами. Всего доброго!")
admin_app(ADMIN_ID)
Здесь просто пишем сообщение и код admin_app(ADMIN_ID)
который перекидывает к функции admin_app.
Напомню, что Переменные user3_mess, user2_mess и user1_mess хранят тексты введенные в предыдущей функции.
И так, создаем функцию для отправки введенных данных пользователя Администратору/Менеджеру
Делаем функцию admin_app для отправки данных Админу:
def admin_app(ADMIN_ID):
ankets = f'''Новая заявка от {name}!
Имя: {user1_mess}
Возраст: {user2_mess}
Номер телефона: {user3_mess}
Telegram:
Name: {name}
Username: @{username}'''
bot.send_message(ADMIN_ID, ankets)
Создаем переменную ankets где будут заполненные анкеты пользователя и отправляем Админу. Вы помните, что мы создавали переменную ADMIN_ID? Так вот, на этот аккаунт с таким айди будут отправляться заявки пользователей.
Не забываем в конце кода написать:
bot.polling()
Полный код:
import telebot
TOKEN = 'YOUR_TOKEN'
ADMIN_ID = 'YOUR_ID'
bot = telebot.TeleBot(TOKEN)
name = None
username = None
user1_mess = None
user2_mess = None
user3_mess = None
@bot.message_handler(commands=['start'])
def start_message(message):
global name, username
name = message.from_user.first_name
username = message.from_user.username
bot.send_message(message.chat.id, "Привет! Это бот для заявок. Чтобы подать заявку, заполните анкеты")
form1(message)
def form1(message):
bot.send_message(message.chat.id, "1. Как вас зовут?")
bot.register_next_step_handler(message, form2)
def form2(message):
global user1_mess
user1_mess = message.text
bot.send_message(message.chat.id, "2. Сколько вам лет?")
bot.register_next_step_handler(message, form3)
def form3(message):
global user2_mess
user2_mess = message.text
bot.send_message(message.chat.id, "3. Укажите номер телефона:")
bot.register_next_step_handler(message, result)
def result(message):
global user3_mess
user3_mess = message.text
bot.send_message(message.chat.id, "Спасибо за заявку! Скоро наш менеджер свяжется с вами. Всего доброго!")
admin_app(ADMIN_ID)
def admin_app(ADMIN_ID):
ankets = f'''Новая заявка от {name}!
Имя: {user1_mess}
Возраст: {user2_mess}
Номер телефона: {user3_mess}
Telegram:
Name: {name}
Username: @{username}'''
bot.send_message(ADMIN_ID, ankets)
bot.polling()
Запускаем и проверяем:
Ура! Все работает прекрасно!
Также вы можете в переменной ADMIN_ID указать айди вашей группы, куда нужно отправлять уведомления о новых заявок (не забудьте добавить бота в группу).
Комментарии (12)
rSedoy
08.08.2023 01:36+1А вы хотя бы понимаете проблему такого использования глобальных переменных в подобных конкурентных средах?
theurus
08.08.2023 01:36А как юзеру отменить режим ожидания ввода сообщения :) пока он возраст не напишет его не отпустит?
fedorov0av
08.08.2023 01:36+1мммм... для таких целей есть FSM. Советую ознакомиться. Можно обойтись без глобальных переменных.
iantoshkai
08.08.2023 01:36telebot в 2023 -__-
использование global -____-
нейминг на уровне(user3_mess, user2_mess, ...)
советую почитать за aiogram, fsmtwistfire92
08.08.2023 01:36Конкретно для задачи описанной в статье telebot подходит более чем. И FSM от aiogram тут тоже не нужен. Слишком простой сценарий, реализация которого легко ложится на плечи
register_next_step_handler
, просто автор не все возможности этой функции знает. Вот если бы появились Inline кнопки, было бы чуть сложнее, но тоже решаемо.
Автор - новичок, и прыгать сразу в aiogram с FSM только потому что aiogram достаточно попсовый - не самая удачная идея.
crushilov
08.08.2023 01:36Это конечно все круто, что можно кинуть боту сообщение и он тебе ответит другим сообщением, но хотелось бы уже что-то поинтереснее про на эту тему, чем просто краткий User Guide.
twistfire92
08.08.2023 01:36Я правильно понимаю, что на одновременной работе нескольких пользователей это все не тестировалось? Попробуйте использовать несколько аккаунтов, попросите друзей.
Шаги следующие:Первый начнет заполнять анкету, доходит до вопроса с номером телефона и ждет
Второй заполняет анкету полностью
Первый вводит номер телефона
Какой результат получит первый пользователь?
Собранную информацию на каждом шаге лучше пробрасывать в
register_next_step_handler
дополнительными параметрами, а не хранить в глобальных переменных
MaxSoft
08.08.2023 01:36А что будет, если 2 и более пользователя одновременно начнут писать в этого бота? Мне кажется, что будет Race Condition на глобальные переменные и всё сломается. Или я ошибаюсь?
lex08275
08.08.2023 01:36А в чем смысл глобальных переменных?
2 человека одновременно заполняют форму, админу придет солянка из двух анкет?
Почему бы не генерить объект и передавать его по цепочке?
nameisBegemot
08.08.2023 01:36А как в этом коде обстоит дело с асинхронным выполнением? Не будет ли блокировать после первого же подключения юзера?
rusik2293
user3_mess - беспорядок юзера 3?