Как стать автором
Обновить
26.67
Программный Продукт
Создаем решения для государства и бизнеса

Уведомления о деплое Gitlab через Telegram-бота при помощи Yandex Cloud Functions

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров8.1K

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

Данная статья и родилась вследствие того, что на текущем проекте в нашей команде разработки есть боль: когда на беке вливают МР в ветку develop, то стенд становится временно недоступен из-за деплоя. Основные участники, испытывающие эту боль — фронтенд разработчики и аналитики, которым чаще всего приходится взаимодействовать с бекендом. И во время недоступности стенда непонятно, деплой идёт или стенд стал временно недоступен из-за ошибки.

Нет, конечно, можно зайти в Gitlab, проверить, идёт ли сейчас деплой или посмотреть логи контейнера. Но для этого нужно быть в курсе, из-за деплоя каких конкретно микросервисов (естественно мы говорим о микросервисной архитектуре) стенд может быть временно недоступен. Ну и плох тот программист, который не хотел бы упростить жизнь себе и коллегам, автоматизировав при этом чаво-нибудь! :)

Как уже понятно из названия статьи, мы будем использовать цепочку из 3 звеньев: Gitlab Webhook + Yandex Cloud Functions + Telegram Bot. Аналогичные статьи-инструкции вы вполне вероятно видели в этих ваших интернетах, но подобной статьи с такой связкой лично я не нашёл (хотя прям в глубинах глубин гугла и яндекса я не ковырялся, отмечу справедливости ради).

Кратенькое ТЗ: нам нужно, чтобы Telegram-бот присылал уведомления каждый раз, когда на беке вливают МР и стартует пайплайн с деплоем в последней джобе, из-за чего временно становится недоступен дев стенд. Итак, давайте перейдём к делу.

Для начала нам нужно создать Telegram-бота. Это делается очень легко: в самой телеге переходим в праотца всех ботов @BotFather и создаём бота командой “/newbot”. После успешного создания бота, в ответ мы получим сообщение с его токеном. Он нам скоро понадобится, не теряем его.

На втором этапе нашей цепи переходим в Yandex Cloud под своей учётной записью, либо создаём новую, заполняем данные платёжного аккаунта, привязываем карту и переходим в раздел функций Яндекс. В месяц 1.000.000 вызовов бесплатно, если что:

Создаём новую Яндекс-функцию и переходим в редактор кода. Мой пример кода написан на Node.js, есть куча вариантов альтернативных решений, тут уже что вашей душе угодно, как грится :)

Непосредственно сам фрагмент кода:

module.exports.handler = async function (event, context) {

    var action = JSON.parse(event.body).object_attributes.action;

if (action === 'merge') {

require('https').get('https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/sendMessage?chat_id=<TELEGRAM_CHAT_ID>&text=%D0%9E%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D1%8F%D0%B5%D1%82%D1%81%D1%8F%20%D0%B1%D0%B5%D0%BA%D0%B5%D0%BD%D0%B4.%20%D0%92%20%D0%B1%D0%BB%D0%B8%D0%B6%D0%B0%D0%B9%D1%88%D0%B8%D0%B5%2010%20%D0%BC%D0%B8%D0%BD%D1%83%D1%82%20%D0%B2%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D1%8B%20%D0%BF%D0%B5%D1%80%D0%B5%D0%B1%D0%BE%D0%B8%20%D0%B2%20%D0%B5%D0%B3%D0%BE%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B5%20%D0%BD%D0%B0%20dev%20%D1%81%D1%82%D0%B5%D0%BD%D0%B4%D0%B5.');

}

    return {

        statusCode: 200,

        body: typeof event.body === 'string' ? JSON.parse(event.body).x : event.body,

    };

};

Вместо “<TELEGRAM_BOT_TOKEN>” в коде нужно вставить токен-бота, который мы получили после его создания в респонсе от @BotFather, а вместе “<TELEGRAM_CHAT_ID>” — айдишник чата, в который наш бот будет отправлять указанный текст. Значение параметра text в urlencoded.

С параметрами chat_id есть нюансы, с которыми мне пришлось столкнуться. Чтобы получить этот id, я зашёл в Telegram через браузерную веб-версию, выбрал нужный мне чат и из урла скопировал id. И начал тестировать, после чего несколько дней не понимал, почему бот не присылает уведомления, хотя я перепробовал самые разные вариации. В итоге пришёл к тому, что это не тот chat_id, а чтобы получить нужный айдишник, нужно:

1. Добавить бота в чат, в который нужно отправлять уведомления.

2. Сделать GET запрос по адресу: https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/getUpdates

3. Найти в респонсе рядом с именем нужного чата его идентификатор.

Возвращаемся к Yandex Cloud Function. В поле "Точка входа” вписываем значение “index.handler” для данного фрагмента кода выше. Остальные значения оставляем дефолтными. Затем переходим в раздел “Обзор” слева, и для поля “Публичная функция” меняем значение с false на true. Из поля “Ссылка для вызова” чуть выше копируем значение URL, оно нам понадобится на следующем шаге.

И теперь в Gitlab нам необходимо настроить webhook в модуле, уведомления которого мы хотим получать. Для этого нужно обладать правами мейнтейнера. Слева переходим в раздел "Settings” и выбираем пункт “Webhooks”. Снимаем дефолтную галочку с триггера “Push events” и вешаем галочку на триггер “Merge request events”. Дефолтную галочку “Enable SSL verification” внизу страницы оставляем в значении true. В URL прописываем ссылку на Yandex-функцию из поля “Ссылка для вызова”.

И вуаля! Теперь всё должно зафурычить :)

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

Первое, что я доработал — это второй webhook в модуле фронтенда. И в зависимости от параметра url из payload, бот теперь шлёт уведомления о деплое на бекенде либо фронтенде с разными текстами.

var url = JSON.parse(event.body).object_attributes.url;

Вторая доработка — это отправка одинаковых уведомлений в 2 разных Telegram-чата. На каждый чат я сделал реквест один за другим, но столкнулся с проблемой, что иногда во второй чат уведомление не приходило (в первый приходило всегда). Решил проблему путём добавления задержки в 2 секунды между реквестами.

setTimeout(() => {

// second request

}, 2000);

И последняя, третья фича — это добавление заголовка МР’а в уведомления для удобства аналитиков в отслеживании выполнения тасок. Получить заголовок из вебхука можно следующим образом:

var title = JSON.parse(event.body).object_attributes.title;

Итого, что сейчас реализовано: бот присылает разные уведомления о деплое на бекенде или фронтенде в 2 разных чата и сообщает заголовок МР’а.

Вот ссылка, которая 100% вам пригодится, если вы также будете ковыряться в этой теме и постоянно улучшать функциональность в своей Яндекс функции:

https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#merge-request-events

Заключение

Надеюсь, данная статья была для вас полезной и пригодится в решении аналогичной задачи.

Спасибо за внимание и хорошего дня ;)

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

Теги:
Хабы:
Всего голосов 2: ↑2 и ↓0+2
Комментарии4

Публикации

Информация

Сайт
ppr.ru
Дата регистрации
Дата основания
2002
Численность
501–1 000 человек
Местоположение
Россия

Истории