Привет, Хабр! В одной из прошлых своих статей я уже писал про API для работы с SMS-сообщениями от компании МТТ (входит в экосистему МТС). На этом можно было бы и остановиться, если бы не одно «но». Не так давно вышла в свет платформа МТС Exolve за авторством всё той же компании МТТ. Методы для работы с SMS у MTT Telecom API и MTC Exolve очень похожи, за исключением одного: чтобы «покрутить в руках» MTC Exolve, не нужно заключать договор.

Если прошлые статьи могли заинтересовать только специалистов компаний, оплативших доступ к услугам от МТТ, то в этот раз проверить работу платформы бесплатно сможет практически каждый.

Чтобы не повторяться в кейсах, сегодня мы  «поймаем двух зайцев»: посмотрим, как работает GitHub Actions и научимся отправлять SMS с помощью МТС Exolve.

План следующий:

  1. Подготовить всё для отправки SMS через Exolve.

  2. Настроить репозиторий и окружение в GitHub.

  3. Написать свой action, который будет отправлять SMS на разные номера.

  4. Написать 2 workflow:

    а. для отправки SMS тимлиду при pull request в ветку main.

    б. для отправки SMS DevOps, если будет ошибка сборки.

Начнём, как обычно, с дисклеймера. Я не разработчик и не DevOps (хотя мемы ниже утверждают обратное)

Всё, что будет представлено в статье, не стоит рассматривать как хорошие практики и примеры для незамедлительной реализации в проде. Относитесь к этому как к демонстрации концепта just for fun.

Предположим, что мы хотим следующий процесс:

  • разработчик направляет pull request в ветку main проекта на GitHub;

  • GitHub запускает процесс main.yml — этот процесс вызывает наш самописный action, который шлёт SMS тимлиду;

  • если тимлид одобрил pull request то идём дальше, если нет, то коммит в рамках этого кейса нам не интересен и дальше мы не идем;

  • GitHub запускает процесс build.yml — этот процесс пытается собрать наше .NET приложение testapp;

  • если при сборке были ошибки, то вызываем наш action и он отправляет SMS DevOps, а если ошибок не было, то процесс успешно завершен.

Для тех, кто знаком с нотацией BPMN, схема может быть нагляднее:

Сегодня мы не будем идти от простого к сложному. Вначале выполним все подготовительные работы, а после напишем функции отправки SMS.

Создаем приложение в MTC Exolve

Для начала нажмите кнопку «Попробовать бесплатно» на сайте платформы.

Для регистрации потребуется действующая электронная почта.

После подтверждения адреса, нужно подтвердить телефон, без этого полноценно попробовать платформу не получится.

После подтверждения телефона вам доступен тестовый доступ и 300 рублей на балансе.

Вы можете выбрать один виртуальный номер для тестирования платформы и создать одно приложение.

К сожалению пополнить тестовый баланс нельзя, чтобы закинуть деньжат, потребуется подтвердить личность (по сути заключить договор).

Но для нашей статьи тестового пакета хватит за глаза. Лично я пока потратил меньше 30 рублей.

Чтобы получить ключ API, необходимо создать приложение.

После создания приложения мы можем получить ключ API.

Остаётся только подтвердить тестовый номер и привязать его к приложению. За номер будет списываться абонентская плата из тестового баланса, так что лучше не затягивайте с экспериментами.

Теперь мы готовы переходить к следующему этапу.

Настраиваем репозиторий в GitLab

Вы можете клонировать мой репозиторий из GitHub или создать свой.

Предположим, что у вас есть пустой репозиторий (ну илис Readme.md). 

Давайте для начала создадим окружение и зададим переменные.

Перейдите в раздел  Settings - > Environments и создайте новое окружение Habr.

Можете оставить настройки по умолчанию, наше главная задача — создать переменные.

Создайте одну «секретку»  EXOLVE_TOKEN — запишите в неё ключ API.

Затем создайте три переменные:

  • DEVOPS_PHONE — телефон DevOps для скрипта build.yml;

  • LEAD_PHONE — телефон тимлида для скрипта main.yml;

  • SERVICE_PHONE — телефон сервиса от MTC Exolve.

В тестовом режиме SMS можно слать только самому себе

На всякий случай напомню, что секретки в отличие от переменных нельзя увидеть, то есть значение будет скрыто как в скриптах, так и в самом интерфейсе GitHub.

Должно выглядеть примерно так (само собой с вашими номерам телефона).

Создаем приложение .NET

Мы создадим самое простое приложение с одной командой вывода текста в консоль.

Создайте в репозитории папку testapp

Перейдите в эту папку в консоли

Введите команду

dotnet new console --framework net6.0 --use-program-main

Замените код в файле Program.cs на следующий:

namespace HelloWorld
{
   class Program
   {
       static void Main(string[] args)
       {
           Console.WriteLine("Hello, Habr!");
       }
   }
}

Вот и всё. Если вдруг вам захочется проверить обработку ошибки в процессе build.yml, можете просто допустить опечатку в Console.WriteLine и отправить коммит в репозиторий.

Пишем свой action

GitHub позволяет написать свой action на JS без заморочек с Docker. Наверняка можно было сделать элегантнее, но мы разместим action в том же репозитории, что и приложение. Это решение я отчасти позаимствовал тут.

Создайте в корне репозитория файл action.yml со следующим содержимым:

name: 'Fancy name of the action'
description: 'Short description'
author: 'name I want to become famous with'
inputs: # если нужны какие-то внешние параметры
 exolve-token:
   description: 'This is a token to access github'
   required: true
 receiver_phone:
   description: 'Target for message TeamLead or DevOps'
   required: true
 service_phone:
   description: 'Phone of MTC Exolve'
   required: true
 text:
   description: 'Text of SMS'
   required: true
runs:
 using: 'node12' # необходимая версия ноды – важно
 main: 'actions/exolve-sms.js' # итоговый файл со всем кодом
branding: # как будет выглядеть иконка экшена в маркетплейсе
 icon: 'terminal'
 color: 'blue'

Давайте разберем по порядку.

Первые три строки, думаю, очевидны.

В блоке input мы задаем параметры, которые будем далее передавать в наши процессы и в скрипт.

Первые три переменные совпадают по смыслу с теми, что мы делали при настройке окружения, text — это текст SMS.

В блоке runs мы запускаем логику action, которая лежит в ещё не созданном файле exolve-sms.js.

Блок branding отвечает за оформление, я просто скопипастил его из примера, в нашем случае мы не будем отправлять action в маркетплейс.

Пришло время написать логику action.

Создайте папку actions, а в ней файл exolve-sms.js со следующим содержимым:

const core = require('@actions/core');
var axios = require('axios');

const EXOLVE_TOKEN = core.getInput('exolve-token')
const RECEIVER_PHONE = core.getInput('receiver_phone')
const SERVICE_PHONE = core.getInput('service_phone')
const TEXT = core.getInput('text')

console.log('Hello, I am an action!')

var data = JSON.stringify({
 "number": SERVICE_PHONE,
 "destination": RECEIVER_PHONE,
 "text": TEXT
});

var config = {
 method: 'post',
 url: 'https://api.exolve.ru/messaging/v1/SendSMS',
 headers: {
   'Authorization': `Bearer ${EXOLVE_TOKEN}`,
   'Content-Type': 'application/json'
 },
 data : data
};


axios(config)
.then(function (response) {
 console.log(JSON.stringify(response.data));
})
.catch(function (error) {
 console.log(error);
});

Давайте разберем код. На самом деле большую часть кода я сгенерировал в Postman. Мы просто берём параметры из окружения и отправляем запрос к API MTC Exolve.

Но объясню подробнее.

const core = require('@actions/core');
var axios = require('axios');

Подключаем библиотеки:

@actions/core — для получения переменных и секретки из GitHub

axios — для запроса к API

Кладем в константы параметры из окружения:

const EXOLVE_TOKEN = core.getInput('exolve-token')

const RECEIVER_PHONE = core.getInput('receiver_phone')

const SERVICE_PHONE = core.getInput('service_phone')

const TEXT = core.getInput('text')

Обратите внимание, что значения в скобках совпадают с теми, что были в секции input файла action.yml. Значения параметров мы зададим позже в процессах main.yml и build.yml

Далее идёт отладочный вывод в консоль.

В переменную data мы сохраняем данные для запроса.

var data = JSON.stringify({
 "number": SERVICE_PHONE,
 "destination": RECEIVER_PHONE,
 "text": TEXT
});

Почитать подробнее про параметры запроса и URL точки подключения можно в документации.

Остальной кусок кода — это автогенерация запроса в Postman.

Нам нужно скачать зависимости для скрипта. Делаем это так:

Перейдите в папку actions

И выполните

npm init

можно оставить всё по умолчанию.

Затем добавьте библиотеки

npm install @actions/core

npm install axios

Я не стал заморачиваться и решил сделать как в инструкции.

Поэтому просто залейте всю папку actions вместе с node_modules в репозиторий GitHub.

Создаем процесс (workflow) main.yml

Создайте папку

/.github/workflows

А в ней создайте файл main.yml со следующим кодом:

name: "need to check pull request"
on:
 pull_request:
   types:
     - opened
   branches:
     - 'main'
jobs:
 test:
   runs-on: ubuntu-latest
   environment: habr
   steps:
     # 1 шаг необходим, чтобы использовать экшен из соседней папки
     - name: Check out repository
       uses: actions/checkout@v3
     - name: Start message
       uses: ./
       with:
         exolve-token: ${{secrets.EXOLVE_TOKEN }}
         receiver_phone:  ${{vars.DEVOPS_PHONE}}
         service_phone :  ${{vars.SERVICE_PHONE}}
         text: "Check pull request"

Давайте разберёмся по частям.

on:
 pull_request:
   types:
     - opened
   branches:
     - 'main'

Этот блок говорит, что надо использовать процесс только когда открыт pull request в ветку main.

jobs:
 test:
   runs-on: ubuntu-latest
   environment: habr

Это название работы и окружения, из которого мы берём переменные, а также система на которой запустится процесс.

 steps:
     # 1 шаг необходим, чтобы использовать экшен из соседней папки
     - name: Check out repository
       uses: actions/checkout@v3
     - name: Start message
       uses: ./
       with:
         exolve-token: ${{secrets.EXOLVE_TOKEN }}
         receiver_phone:  ${{vars.DEVOPS_PHONE}}
         service_phone :  ${{vars.SERVICE_PHONE}}
         text: "Check pull request"

Это шаги, которые выполняет процесс.

     - name: Check out repository
       uses: actions/checkout@v3

Позволяет процессу получить доступ к репозиторию.

     - name: Start message
       uses: ./
       with:
         exolve-token: ${{secrets.EXOLVE_TOKEN }}
         receiver_phone:  ${{vars.DEVOPS_PHONE}}
         service_phone :  ${{vars.SERVICE_PHONE}}
         text: "Check pull request"

Вызываем action.yml в корне репозитория.

При этом передаются поля  exolve-token, receiver_phone, service_phone, text, которые в итоге попадут в exolve-sms.js.

Обратите внимание, что секретные данные окружения вытаскиваются из secrets, а переменные из vars.

Если все пойдёт по плану, то тимлид получит сообщение с текстом Check pull request.

Создаём процесс build.yml

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

Тогда нам надо по аналогии с прошлым разделом в папке /.github/workflows создать файл build.yml со следующим кодом:

name: dotnet package

on:
 push:
  branches:
     - 'main'

jobs:
 build:

   runs-on: ubuntu-latest
   environment: habr
   steps:
     - uses: actions/checkout@v3
     - name: Setup .NET Core SDK
       uses: actions/setup-dotnet@v3
       with:
         dotnet-version: '6.0.x'
     - name: Install dependencies
       working-directory: ./testapp
       run: dotnet restore
     - name: Build
       working-directory: ./testapp
       run: dotnet build --configuration Release --no-restore
     - name: Build Alerts
       if: ${{ failure() }}
       uses: ./
       with:
         exolve-token: ${{ secrets.EXOLVE_TOKEN }}
         receiver_phone:  ${{vars.DEVOPS_PHONE}}
         service_phone :  ${{vars.SERVICE_PHONE}}
         text: "Check pipeline"

Тут многое аналогично прошлому разделу. Рассмотрим только новое для нас.

Процесс стартует при push в ветку main.

on:
 push:
   branches:
     - 'main'

Мы используем .Net версии 6.0.

     - name: Setup .NET Core SDK
       uses: actions/setup-dotnet@v3
       with:
         dotnet-version: '6.0.x'

Устанавливаем зависимости.

     - name: Install dependencies
       working-directory: ./testapp
       run: dotnet restore

Переход в папку с .NET приложением надо делать каждый раз.

Запускаем сборку приложения, если всё пройдёт штатно, процесс закончится.

     - name: Build
       working-directory: ./testapp
       run: dotnet build --configuration Release --no-restore

Если будут ошибки сборки, то сработает веткаif: ${{ failure() }}.

И в этой секции вызовется наш кастомный action, по аналогии с main.

     - name: Build Alerts
       if: ${{ failure() }}
       uses: ./
       with:
         exolve-token: ${{ secrets.EXOLVE_TOKEN }}
         receiver_phone:  ${{vars.DEVOPS_PHONE}}
         service_phone :  ${{vars.SERVICE_PHONE}}
         text: "Check pipeline"

В таком случае DevOps получит сообщение с текстом Check pipeline.

Ну вот и всё. Ещё раз напомню, что готовый код можно скачать с GitHub.

Понятно, что в XXI веке сложно представить, что надо кого-то уведомлять с помощью SMS, ведь есть куча мессенджеров, почта, но зато теперь вы вооружены и сможете экстренно достучаться даже до самых «винтажных» коллег.

Спасибо за уделенное статье время! Если у вас есть вопросы – добро пожаловать в комментарии. Если вы хотите поделиться своими историями про SMS – встречаемся там же)

Также вы можете почитать и другие статьи о МТС Exolve:

Комментарии (2)


  1. fireapple
    01.06.2023 14:59
    +1

    Очень необычный кейс)) с телегой бы такое провернуть


    1. vitaly_il1
      01.06.2023 14:59
      +3

      Про телеграм или слак статью не напишешь - это будет workflow из 10 строчек, использующее одну из готовых акций https://github.com/marketplace?type=actions&query=telegram+