КАК ЗАПУСТИТЬ БОТА TELEGRAM НА GOOGLE CLOUD

Как я создаю «Sembako Bot» с помощью Google Cloud

Поверьте мне, это не так сложно.

Отказ от ответственности: все, что я пишу в этом посте, представляет мое мнение и только мое мнение, а не мнение моих работодателей.

О «Сембако Бот»

Так что я на самом деле написал о «сембако» в README репозитория, но я могу кратко объяснить здесь.



«Сембако» — это индонезийская аббревиатура от «sembilan bahan pokok», что переводится как «девять основных товаров», хотя его также можно перевести как «продукты питания». Что это за девять товаров? Это может быть сырое пищевое сырье (например, мясо), фрукты и овощи или даже сжиженный нефтяной газ (LPG), который очень популярен в Индонезии для приготовления пищи.

Настоящая причина, по которой я делаю этого бота, заключается в том, что цены на сембако в Индонезии постоянно растут, особенно цены на пальмовое масло*. Итак, инфляция цен на пальмовое масло происходит с декабря 2021 года, но кризис фактически не ощущается до февраля 2022 года. Инфляция происходит из-за сочетания факторов, от перебоев с поставками из Малайзии, игры с поставками от дистрибьюторов ( на индонезийском)», и Российско-украинская война, которая нарушает поставки подсолнечного масла (справедливости ради, война не запускает инфляцию, она только ускоряет инфляцию). Основная предпосылка бота заключается в том, что пользователи могут внимательно следить за ценой, чтобы они могли принять решение о том, покупать ли сембако сегодня или придержать до завтра**.

* Самым популярным растительным маслом в Индонезии является пальмовое масло, несмотря на то, что существует много других видов растительного масла, таких как рапсовое, оливковое и т. д.

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

Почему Телеграм

Прежде чем я сделал бота, я должен определиться с платформами. Я думал о некоторых кандидатах, таких как LINE, WhatsApp, Discord и Telegram.

Что касается WhatsApp, то я особо об этом не думал, потому что знаю, что создать там бота довольно сложно. Насколько мне известно, вы должны стать владельцем бизнеса, чтобы создать бота.

Что касается LINE, я помню, что давным-давно сделал простого бота в чат-приложении LINE. Однако LINE доступен не на всех платформах (LINE для Linux поставляется только с подключаемым модулем). Кроме того, LINE — это не легкое приложение для чата (тяжелее, чем Telegram), из-за которого мне лень входить в систему даже на ноутбуке.

Для Discord я редко использую его. И потом, CMIIW, но боты, которых я видел в Discord, находятся на Discord-серверах (группах). Мой первоначальный дизайн бота — это бот для личного использования, а не для группового использования.

Что касается Telegram, я думаю, что основная причина, по которой я выбрал его, заключается в том, что я нашел учебник от канала YK Dojo о разработке чат-ботов Telegram. Когда я читаю дальше, я думаю, что SDK довольно прост в использовании. Поэтому я выбираю Telegram.

Как использовать бота

ПРИМЕЧАНИЕ. в настоящее время бот доступен только на индонезийском языке.

Чтобы использовать бота, вам нужно найти его с идентификатором @tele_sembako_bot. Появится Sembako Bot.

После того, как вы добавите его. Вам нужно будет ввести /start. Это даст вам список команд, которые вы можете использовать.

Я кратко объясню каждую команду здесь:

  1. /update: вы можете использовать эту команду, чтобы получать цены «сембако» без необходимости регистрироваться для ежедневного обновления. Подождав 5–10 секунд, вы получите цены (в индонезийских рупиях) вместе с акциями.
  2. /subscribe: если вы хотите получать ежедневное обновление цен, вы можете использовать эту команду.
  3. /unsubscribe: если вы хотите отказаться от ежедневного обновления, используйте эту команду.
  4. /help: если вы хотите увидеть список всех команд, используйте эту команду.
  5. /donate: если вы хотите внести финансовый вклад в этот проект, вы можете использовать эту команду. Для получения дополнительной информации см. нижний раздел ниже.

Если вы введете недопустимую команду, бот сообщит вам, что команда недействительна, и вам нужно проверить доступные команды с помощью /help.

Архитектура высокого уровня

Итак, вот архитектура высокого уровня для проекта Sembako Bot. Что касается объяснения этих компонентов внутри Google Cloud и базы данных, они будут объяснены позже.

Чтобы понять роль сервера Telegram выше, я сделал диаграмму последовательности ниже. Вот диаграмма последовательности при использовании команды /update:

На приведенной выше диаграмме последовательности показано, как на самом деле работает бот Telegram*. Когда пользователи отправляют сообщения чат-боту, сообщения сначала отправляются на сервер Telegram. Затем Telegram отправляет сообщение на URL-адрес веб-перехватчика, который мы установили (позже в части Terraform я объясню настройку веб-перехватчика). В этом случае сервер размещается в Cloud Run. Затем Cloud Run отправит запрос в соответствующий контейнер. Контейнер получит данные, а затем цены из внешних источников (Segari, Tokopedia и Shopee). После этого он отправит обратно ответное сообщение, используя chat_id send.

* Диаграмма верна, если вы настроили вебхук. Однако вы также можете создать чат-бота Telegram без веб-хука. Вы можете использовать механизм опроса, как показано в видео YK Dojo. Однако механизм опроса не подходит для бессерверного подхода (поскольку он может масштабироваться до нулевого контейнера, то есть выключения), поэтому вместо этого я выбрал веб-перехватчик.

Сервер

Объяснение каждого технического стека можно найти в каждом подразделе.

Язык

Я выбираю язык Python. Почему? Не потому, что я эксперт по языку Python. Я строю свою карьеру с 3 лет программирования на Java. Но для бота Telegram наиболее распространенный язык, который я нашел в учебниках по чат-ботам, использует Python для разработки, включая учебник с канала YK Dojo (учебник представлен Джейкобом из ClarityCoders).

Рамки

Я использую FastAPI из-за его простоты. В отличие от Django, вы можете запустить FastAPI буквально с одним файлом Python. Очень заманчиво использовать FastAPI для такого небольшого проекта.

Вторая причина, по которой я использую FastAPI, заключается в том, что это один из самых быстрых веб-фреймворков для Python (см. скриншот выше). Когда мы комбинируем раннер с Uvicorn, это так быстро, как вы можете получить в Python. Конечно, есть более быстрые языки, просто поскольку я решил использовать Python, FastAPI — лучший выбор для повышения производительности. Извини, Фласк.

Одна вещь, которую может быть трудно найти, — это выяснить полезную нагрузку с сервера Telegram. Просмотрев несколько сообщений, я нашел это сообщение от Kendrew C и сообщение в блоге от dicoffeean (на индонезийском языке), в которых рассказывается о структуре полезной нагрузки Telegram. Из этих двух статей я знаю, где структурированы chat_id и text.

Источник данных

Самое главное в этом чат-боте, конечно же, цены. Где взять цены?

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

Нас интересуют цены. В Segari конечную точку найти несложно. На скриншоте видно, что я просматриваю каждый запрос, пока не найду ответ в формате JSON с ценовыми данными. Как только я нахожу запрос, я копирую и вставляю запрос cURL в Postman и смотрю, могу ли я уменьшить отправляемые заголовки или параметры. Оказывается, есть некоторые заголовки, которые не нужно отправлять.

Для Tokopedia метод аналогичен. Однако в Tokopedia вам нужно отлаживать страницу сведений о продукте, в отличие от Segari, где вы отлаживаете страницу поиска. Почему? Потому что у Segari нет страницы с подробной информацией о продукте. Каждая деталь помещается на эту страницу поиска (подход PWA).

Кажется, я понял просьбу. Проблема в том, что он возвращает слишком много данных. Как уменьшить ответ?

После отладки в Postman я обнаружил, что на самом деле это запрос GraphQL! Вау, скрытое благословение! Так что мне нужно только изменить запрос GraphQL (уменьшив ответный запрос), и тогда все в порядке.

Самый сложный — это Shopee. Я практически не стал ставить Shopee в список прайс-провайдеров, потому что непонятно, какой именно сетевой вызов несет в чат-боте нужные мне данные.

Поэтому я сделал что-то «немного» другое. Я искал цену (например, 112800 согласно информации о продукте apge) на вкладке «Сеть», надеясь, что получу сетевой вызов. Оказывается, я нашел несколько результатов. Я решил использовать get_purchase_quantities_for_selected_model запрос, и смотрите, что я нашел! Цена и наличие есть.

Так что у нас это. Три провайдера, три разные конечные точки API и, следовательно, три источника данных.

База данных

Для базы данных я выбрал новое решение: CockroachDB. Но почему? Ну, причина в том, что у меня есть 5 ГБ в месяц бесплатного плана с CockroachDB.

Но у вас также есть «бесплатный план с Mongo Atlas?» Да исправить. Но вот в чем дело. В предыдущем проекте я использую TypeScript. У меня есть опыт запуска MongoDB с TypeScript до предыдущего проекта, поэтому его проще настроить. Но для Питона? Мой опыт работы с базой данных в Python связан с библиотекой peewee, поэтому я думаю, что лучше придерживаться ее. Проблема с использованием peewee заключается в том, что теперь у меня ограниченные возможности бесплатного плана базы данных, поэтому я выбрал CockroachDB. Я знаю, что CockroachDB — это NewSQL, но я выбрал его не по этой причине, хотя, справедливости ради, если проект станет вирусным, мне не нужно будет снова заботиться о шардинге.

Инфраструктура

Google Cloud Run

Цитировать Документация Google Cloud:

Cloud Run — это управляемая вычислительная платформа, позволяющая запускать контейнеры, которые можно вызывать с помощью запросов или событий.

Другими словами, Google Cloud Run — это бессерверное решение от Google, где мы можем запускать наши контейнеры в Google Cloud, а Google позаботится обо всем остальном (автоматическое масштабирование и т. д.).

Я использую Google Cloud Run для обслуживания запросов с сервера Telegram. Google Cloud Run — это бессерверная функция, предлагаемая Google, с одним отличием от AWS Lambda: она предназначена для запуска контейнеров, в отличие от AWS Lambda (и Google Cloud Function), которая предназначена для запуска одной «функции».

Мне нравится в Google Cloud Run то, что они уже настроили для нас HTTPS. Это важно для разработки чат-ботов, так как Telegram позволяет регистрировать веб-хук только HTTPS (они не принимают URL-адрес HTTP в качестве веб-хука).

Для настройки Google Cloud Run я использую Terraform. Я настраиваю только имя контейнера (которое загружаю в Google Container Registry), открытый порт и переменные среды.

Посмотреть конфигурацию можно здесь:



Облачный планировщик Google

Планировщик Google Cloud — это управляемая служба планировщика, предоставляемая Google, которая может периодически вызывать конечную точку HTTP.

Это легко настроить (особенно с Terraform), мне просто нужно установить расписание, которое я хочу, в нотации cron, а также часовой пояс. В данном случае я использую часовой пояс Джакарты (Asia/Jakarta).

Посмотреть конфигурацию можно здесь:



Развертывание с помощью Terraform

Я всегда предоставляю инфраструктуру с помощью Terraform. Для меня это не проблема. Без Terraform один неверный щелчок может привести к неправильной настройке, а использование Terraform гарантирует, что моя конфигурация будет хорошо задокументирована и может быть воспроизведена (при необходимости).

Что касается развертывания, я должен сделать как минимум два небольших изменения:

  1. Я всегда заменяю Cloud Run каждый раз, когда apply настраиваю конфигурацию. Заменить здесь означает, что я удаляю существующий ресурс Cloud Run, а затем создаю новый. Почему я это сделал? Потому что во время тестирования я обнаружил, что иногда Terraform выдает ошибку 409 при подаче заявки. Terraform попытался создать новую версию развертывания Cloud Run (с тем же именем), но оказалось, что это имя уже существует. Поэтому мой обходной путь — заменить ресурс, что привело к простою на 2–3 минуты. Я думаю, это нормально, так как Telegram повторит вызов API веб-перехватчика*.
  2. Я устанавливаю веб-хук после каждого развертывания. На самом деле вы можете увидеть конфигурацию Terraform здесь. Мне не нужно этого делать, но в связи с пунктом 1, если URL-адрес Cloud Run (по какой-то причине) изменен, мне нужно вручную установить веб-хук. Я подумал, что будет лучше, если веб-хук будет устанавливаться автоматически, если изменится URL-адрес Cloud Run.

* На самом деле я не знаю, как долго Telegram будет повторять попытку. Во время тестирования, когда у меня была ошибка, которая привела к внутренней ошибке сервера, Telegram все равно повторил попытку после развертывания исправления (через 5 минут после того, как ошибка была запущена в производство).

Заключение

Таким образом, архитектура высокого уровня проста. Нам просто нужно использовать Cloud Run и Cloud Scheduler. Что касается Telegram SDK, это тоже было довольно просто, хотя разобраться с вебхуком немного сложнее.

Что касается будущих улучшений, у меня есть две идеи:

  1. Я сравню Google Cloud с Amazon Web Service путем переноса используемых ресурсов. Я посмотрю, как эквивалентные ресурсы складываются друг против друга.
  2. Настройте панель инструментов с помощью Grafana и Prometheus (или InfluxDB, если это слишком сложно). Приборная панель может сравнивать цены за определенный период времени. Это более сложно и, безусловно, требует больше ресурсов (времени, денег и т. д.) для настройки.

Вот окончательный исходный код, если вы хотите прочитать весь код.



ПРИМЕЧАНИЕ. Если вы из Индонезии и хотите, чтобы этот бот работал, вы можете просмотреть руководство, введя команду /donate на боте. Бот расскажет вам обо всех доступных способах пожертвования. Каждое пожертвование помогает мне поддерживать этот проект, особенно оплата облачных сервисов.