Всем привет! Наверняка вы видели в различных ботах реферальную ссылку типа https://t.me/<юзернейм_бота>?start=<число>. Обычно в качестве числа указывается Telegram ID реферера. В этой статье я расскажу как обрабатывать такие ссылки в своем боте.
Для разработки ботов я использую Python библиотеку pytelegrambotapi.
Процесс создания бота через @BotFather опущу, приступлю сразу к коду. Есть файл config.py с переменной TOKEN, в которой хранится токен бота. В файле bot.py будем «химичить». Напишем обработчик команды /start и выведем все, что хранится в объекте сообщения.
import telebot import config bot = telebot.TeleBot(config.TOKEN) @bot.message_handler(commands=["start"]) def start_command_handler(msg): print(msg) if __name__ == '__main__': bot.polling(none_stop=True)
Нас интересует строчка 'text': '/start'. Попробуем теперь перейти по ссылке вида https://t.me/<юзернейм_бота>?start=test и изменим 10-ю строчку на print(msg.text)
В консоли вывелось/start test. Делаем вывод, что в msg.text хранится необходимая нам информация из реферальной ссылки, которую необходимо обработать.
Приступим к обработке. Учитываем, что не всегда пользователь нажимает /start по реферальной ссылке, поэтому текста после /start может и не быть. Отличительным символом служит пробел (вспоминаем /start test). Значит будем проверять наличие ID реферера по нему.
@bot.message_handler(commands=["start"]) def start_command_handler(msg): user_id = msg.from_user.id referrer = None if " " in msg.text: referrer_candidate = msg.text.split()[1] # Идем далее
Если пользователь перейдет по ссылке https://t.me/<юзернейм_бота>?start=test test2, То test2 не попадет в msg.text, потому что там имеется пробел, который говорит, что test2 не является частью ссылки. Именно поэтому в msg.text находится только один символ пробела. А значит если он имеется, то и есть некоторая информация из реферальной ссылки. Поэтому в первой ветке мы создаем список (msg.text.split()), и берем его второй элемент (всем ведь известно, что нумерация списка идет с нуля, да?).
Хорошо, на этом этапе мы имеем текст из ссылки. Мы подразумеваем, что там число, но от пользователя можно поджидать чего угодно. Вдруг кому-то захочется «сломать» бота, указав в ссылке вместо ID реферера какой-то текст. Для этого проверим данные.
@bot.message_handler(commands=["start"]) def start_command_handler(msg): user_id = msg.from_user.id referrer = None # Проверяем наличие хоть какой-то дополнительной информации из ссылки if " " in msg.text: referrer_candidate = msg.text.split()[1] # Пробуем преобразовать строку в число try: referrer_candidate = int(referrer_candidate) # Идем далее except ValueError: pass
Здесь, используя try... except мы преобразуем при помощи int() информацию в число. Если в переменной referer хранится не число, то int() вызовет ошибку ValueError
Теперь в referer записано число. Но тут появляется загвоздка: функция int() может перевести строку «-101» в число -101. То есть на данном этапе в referer может храниться отрицательное число. Почему это не важно, расскажу чуть позднее.
Пользователь может вставить в ссылку свой TG ID. Реферальная система подразумевает под собой некий бонус за переход, поэтому таким образом можно выдать самому себе бонус. Предусмотрим это. ID пользователя получаем, используя user_id = msg.from_user.id
@bot.message_handler(commands=["start"]) def start_command_handler(msg): user_id = msg.from_user.id referrer = None # Проверяем наличие хоть какой-то дополнительной информации из ссылки if " " in msg.text: referrer_candidate = msg.text.split()[1] # Пробуем преобразовать строку в число try: referrer_candidate = int(referrer_candidate) # Проверяем на несоответствие TG ID пользователя TG ID реферера if user_id != referrer_candidate: # Идем дальше pass except ValueError: pass
Допустим, что имеется функция get_all_users(), которая возвращает список всех пользователей бота. Делаем это для того, чтобы не назначить в качестве реферера пользователя, которого не существует.
@bot.message_handler(commands=["start"]) def start_command_handler(msg): user_id = msg.from_user.id referrer = None # Проверяем наличие хоть какой-то дополнительной информации из ссылки if " " in msg.text: referrer_candidate = msg.text.split()[1] # Пробуем преобразовать строку в число try: referrer_candidate = int(referrer_candidate) # Проверяем на несоответствие TG ID пользователя TG ID реферера # Также проверяем, есть ли такой реферер в базе данных if user_id != referrer_candidate and referrer_candidate in get_all_users(): referer = referrer_candidate except ValueError: pass
Что необходимо делать в случае, если у пользователя и так уже есть реферер? Не будем ведь при каждом использовании реферальной ссылки выдавать бонус за приведенного реферала, это нас попросту разорит. Поэтому необходимо написать проверку. Напишем функцию has_referrer(), которая вернет True при наличии у пользователя реферера и False при его отсутствии. Логично ее написать в начале для оптимизации.
@bot.message_handler(commands=["start"]) def start_command_handler(msg): user_id = msg.from_user.id # Проверяем наличие закрепленного реферера за пользователем if not has_referrer(): referrer = None # Проверяем наличие хоть какой-то дополнительной информации из ссылки if " " in msg.text: referrer_candidate = msg.text.split()[1] # Пробуем преобразовать строку в число try: referrer_candidate = int(referrer_candidate) # Проверяем на несоответствие TG ID пользователя TG ID реферера # Также проверяем, есть ли такой реферер в базе данных if user_id != referrer_candidate and referrer_candidate in get_all_users(): referer = referrer_candidate except ValueError: pass
Надеюсь, что статья будет для вас полезна!
ссылка на оригинал статьи https://habr.com/ru/post/561112/
Добавить комментарий