Для начала что такое Webhook, в контексте телеграм ботов есть два варианта взаимодействия с API:
- polling
- webhook
polling - Это когда наш бот, в каком-то вечном цикле опрашивает телеграм на наличие "обновлений", то есть если пользователь в боте сделал какое-то действие, что бы бот обработал его ему нужно понять что действие совершено, и что вообще произошло, в этом ему и помогает polling, но мы не будем об этом😁
webhook - Это тоже штука для того что бы бот понимал что изменилось, но в данном случае не бот опрашивает телеграм на наличие изменений, а телеграм "шлет" изменения для телеграм бота. Тут есть несколько важных моментов, для того что бы работал webhook у вашего бота должно быть доменное имя с настроенным ssl сертификатом, иначе не секюрно и телеграм откажется взаимодействовать с вашим ботом, и тут когда я начинал "играться" с webhook у меня возник вопрос, а как вообще это настроить для тестов, да и вообще как это настроить? ниже я попытаюсь это описать, а именно как развернуть это локально для разработки и самообучения. Для работы будет использоваться python, flask, ngrok, telebot
1 - Начнем пожалуй с самого кода (я надеюсь вы уже сделали самого бота в телеграм? нуу через BotFather? если нет, тут мануал), когда нам телеграм будет слать запросы мы должны их не только как-то принять, но и обработать, в этом нам поможет flask ну и естественно python, код базовой и довольно тестовой (то есть не для прода) версии ниже, сори что скрин, я не нашел как тут разместить код в удобочитаемом виде:
Я очень надеюсь что читатели уже кодили на python и мне не придется разбирать то, что происходит в каждой строке, но я все же вкратце опишу.
В самом верху вы видите 4 константы (по хорошему их бы вынести в отдельный какой-то конфиг):
API_TOKEN - Когда вы создадите бот в BotFather, вам будет выдан токен, вот его нужно добавить сюда
APP_HOST = '127.0.0.1' - Эта и следующая переменная для flask, он будет принимать запросы которые идут на порт и интерфейс указанный в этих переменных
APP_PORT = '8444'
WEB_HOOK_URL - Доменное имя, на него будет телеграм отправлять все запросы, где его взять так что бы не платить (все же это для самообучения) ? об этом чуть позже😁
Так же я подключил logger что бы удобней было контролировать то, что хочется видеть в в логах.
Блок:
@app.route( '/', methods=['POST'])
def webhook():
****
Помогает flask понять, какой тип запросов обрабатывать, и описывает то, что ему делать
если запрос который пришел был немного не таким как ожидалось)
видете в блоке json_string = flask.request.get_data().decode('utf-8') ? json_string это как раз
тот объект json который мы приняли от телеграм, он "скармливается" в telebot, и потом в хендлерах (как в данном случае start) будет доступен как аргумент функции (правда без пустых значений) в данном случае в виде message
в нашем хендлере start мы всем кто его выполнил в боте в ответ отправим тот json который нам отправил telegram 😁
а вот теперь самое интересное, что по доменному имени? и выход есть, ngrok, переходим на их сайт, создаем аккаунт, следуем всем инструкциям и скачиваем бинарный файл (ну или инсталлируем, как удобно, так как у меня мак, я скачал бинарный файл и просто разместил его в /usr/local/bin/ngrok, в итоге он стал доступен просто вызвав ngrok, не забудьте если делаете так же поставить исполняемый бит на файл chmod +x /usr/local/bin/ngrok, что бы у него было право на исполнение ) потом его нужно запустить, и тут все просто, пишем:
ngrok http <port> (у меня ngrok http 8444, этот тот порт который указан в переменной APP_PORT)
и вы увидите что-то на подобие этого:
Что это значит? ngrok сгенерит адрес который отображается в консоли:
Его вы копируете и вставляете в переменную WEB_HOOK_URL, так телеграм будет знать куда отправлять запросы, отправит их на сгенерированный адрес, ngrok в свою очередь перенаправит все что отправил телеграм во flask на указанный при запуске ngrok порт, и вуаля, все работает 😁
Обратите внимание на эту строку при запуске самого бота (вы же его запустили после того как засетили WEB_HOOK_URL? если нет, запускайте, не стесняйтесь😁 )
Она говорит о том что код который я написал лучше не юзать для прода, и он больше для общеобразовательных целей) я надеюсь я более менее правильно объяснил, если есть вопросы задавайте, я не являюсь разработчиком и это просто мое хобби, так что если я где-то накосячил поясните, поправлю 😁
ссылки для чтения:
https://dashboard.ngrok.com/login
https://flask.palletsprojects.com/en/2.0.x/
https://www.python.org/