Планирование сообщений Slack с помощью AWS Lambda

1656653053 planirovanie soobshhenij slack s pomoshhyu aws lambda

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

Предположим, у вас есть небольшая программа Slack, которая посылает пять лучших историй из Hacker News на ваш канал Slack. В какой-то момент вы решили выключить сервер, на котором запускаете это приложение, но все равно хотите получать истории. Бессерверный режим AWS Lambda выглядит круто. Но как запустить функцию AWS Lambda?

yxY9HN0WQ-feWbL9t3GwVrMZwqwQn6pfIqYo
Все диаграммы создаются с помощью программы SimpleDiagrams 4

Если вы не знакомы, бессерверный способ – это метод развертывания и запуска программ в облачной инфраструктуре на основе оплаты за использование и без аренды или покупки серверов. Дополнительные сведения о бессерверном режиме и его работе с AWS см. в этом руководстве.

Функции AWS Lambda можно запускать с помощью различных служб AWS, таких как API Gateway для API и S3 для файлов. Чтобы получить полный список услуг, просмотрите документы здесь. Одним из доступных триггеров является событие AWS CloudWatch.

Подождите, разве CloudWatch не для журналов?

Ну это да. Но, кажется, кто-то из AWS является большим поклонником доктора Джекила и мистера Хайда, и в некоторых случаях под одним названием скрыто несколько различных служб (привет, Cognito).

Кроме обслуживания журналов, Amazon CloudWatch имеет события, обеспечивающие поток системных событий почти в реальном времени, описывающих изменения в ресурсах AWS. События могут также планировать автоматические действия с помощью выражений cron или rate. Бинго!

Поток программы

Как приложение будет работать с CloudWatch Events?

Вам нужно настроить событие CloudWatch с помощью синтаксиса cron или выражения скорости (т.е. 5 минут). Затем событие CloudWatch запускает функцию AWS Lambda через настроенные промежутки времени. В функции AWS Lambda вы получаете пять самых популярных статей из Hacker News API и публикуете их в Slack с помощью входящих веб-хуков.

Вы можете увидеть поток на рисунке ниже.

nRLfCXLIjaUsXISxyK-qQqFLbq6iJGLNySwJ
Поток бессерверных запланированных сообщений Slack

Звучит просто, не правда ли? Давайте посмотрим, как это работает на практике.

Отправка запланированных сообщений

Прежде чем мы начнем, чтобы следовать этому учебнику, необходимо иметь учетную запись AWS, а также установить AWS CLI и Node.js (v6+). Вы можете получить AWS CLI здесь.

Вам также нужно будет настроить Slack Incoming Webhook. Для этого выполните этот учебник. В конце руководства вы получите URL-адрес веб-хука. Сохраните этот URL, так как он вам вскоре понадобится. Иди, сделай это, я подожду здесь⏳

Ладно, время закончилось! Начнём с интересного.

Для начала создайте новую папку и запустите в ней новый проект Node.js (вы можете использовать npm init -y команда).

Поскольку вам нужно отправить несколько HTTP-запросов, установите модуль обещания минимального запроса от NPM в зависимости. Для этого выполните следующую команду:

npm install minimal-request-promise --save

Обещание минимального запроса – это небольшой модуль Node.js, который просто заворачивает родные модули HTTP и HTTPS в обещания JavaScript.

Теперь, когда зависимость готова, давайте посмотрим следующую фигуру со структурой проекта, которую мы будем использовать.

tth9sqtLCdMEiMc8Bh2u5PuiEiRom5N4N1eb
Структура папок вашего проекта

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

  • index.js — начальный файл для функции Lambda, которая вызывает другие два файла и отвечает на события CloudWatch.
  • src/get-top-hackernews-stories.js — файл, содержащий пять главных новостей с подробностями Hacker News.
  • src/send-slack-message.js — форматирующий и отправляющий файл Slack.

Начнём с исходного файла. Этот файл требует всего двух других файлов и вызывает getTopHackerNewsStories а потом sendSlackMessage функция. Когда обе функции готовы или если произошла ошибка, она реагирует на триггер (событие CloudWatch).

ваш index.js файл должен выглядеть как следующий список кодов.

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

'use strict'
const getTopHackerNewsStories = require('./src/get-top-hackernews-stories')
const sendSlackMessage = require('./src/send-slack-message')
function scheduledSlackMessage(event, context, callback) {  getTopHackerNewsStories()    .then(stories => sendSlackMessage(stories))    .then(() => callback(null))    .catch(callback)}
exports.handler = scheduledSlackMessage

Первая из двух функций, getTopHackerNewsStories, делает HTTP-запрос к Hacker News API (аутентификация не требуется). Поскольку API возвращает список идентификаторов истории, необходимо получить первые пять идентификаторов и отправить HTTP-запрос для каждого идентификатора, чтобы получить детали истории. Наконец вам нужно проанализировать тело ответа (поскольку обещание минимального запроса не делает этого под капотом) и вернуть результаты.

ваш get-top-hackernews-stories.js файл должен выглядеть как следующий список кодов.

'use strict'
const rp = require('minimal-request-promise')
function getTopNews() {  return rp.get(' {    'Content-Type': 'application/json'  })    .then(response => {      const storyIds = JSON.parse(response.body)
      return Promise.all(        storyIds.slice(0, 5)          .map(id => {            return rp.get(` {              'Content-Type': 'application/json'            })              .then(response => JSON.parse(response.body))          })      )    })}
module.exports = getTopNews

Когда вы получаете истории, sendSlackMessage функция форматирует сообщение и отправляет другой HTTP-запрос на URL входящего вебхука Slack, как показано в приведенном ниже списке кодов.

Вместо жесткого кодирования URL-адреса входящего вебхука мы передадим его как переменную среды AWS Lambda. Дополнительные сведения о переменных средах и других способах обмена секретами в бессерверных программах см. в этом руководстве.

'use strict'
const rp = require('minimal-request-promise')
function sendSlackMessage(news, url = process.env.SlackWebhookUrl) {  const body = JSON.stringify({    text: 'Following posts are trending on Hacker News:',    attachments: news.map(item => ({      'author_name': `${item.score} points by ${item.by}`,      title: item.title,      'title_link': item.url    }))  })
  return rp.post(url, {    headers: {      'Content-Type': 'application/json'    },    body: body  })}
module.exports = sendSlackMessage

Теперь, когда код готов, давайте развернем приложение и запланируем сообщение.

Развертывание, настройка и тестирование программы

Мы используем Claudia.js для развертывания нашей функции в AWS Lambda. Прежде чем мы продолжим, убедитесь, что вы следовали этому учебнику, чтобы установить Claudia и настроить учетные данные доступа к AWS.

Кроме того, вам нужно будет создать env.json файл в папке проекта, чтобы определить URL Slack Webhook. Этот файл должен иметь подобное содержимое в следующем списке кодов. Убедитесь, что вы заменили общий URL-адрес тем, который вы получили при настройке программы Slack.

{  "SlackWebhookUrl": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"}

Теперь, когда все готово, выполните такую ​​команду в терминале, чтобы развернуть свою программу:

claudia create --region eu-central-1 --handler index.handler --timeout 10 --set-env-from-json env.json

С помощью этой команды вы выполняете следующие действия:

  • Определите регион где будет развернута ваша функция Lambda. Полный список поддерживаемых регионов см. в документах.
  • Определите файл обработчика, который является относительным путем к вашему файлу точки входа, но с a .handler вместо .js расширение.
  • Набор тайм-аут, поскольку AWS Lambda по умолчанию составляет 3 секунды, но вам нужно выполнить несколько HTTP-запросов. Чтобы обеспечить безопасность, увеличьте время ожидания не менее 10 секунд.
  • Набор переменные среды из файла JSON, который вы подготовили.

Через несколько секунд вы получите ответ JSON, как в примере ниже. Вы тоже увидите claudia.json файл в папке вашего проекта.

{  "lambda": {    "role": "scheduled-slack-messages-executor",    "name": "scheduled-slack-messages",    "region": "eu-central-1"  }}

Это означает, что функция AWS Lambda готова.

Следующим шагом является создание события CloudWatch. Допустим, вы хотите получать уведомления ежедневно в 10 утра по центральноевропейскому времени, поскольку ваш cron работает во часовом поясе GMT. Ваша команда cron должна выглядеть следующим образом: cron(0 9 * * ? *).

Чтобы настроить событие каждый день в 10 утра, выполните следующую команду из вашего терминала:

aws events put-rule --name hackerNewsDigest --schedule-expression 'cron(0 9 * * ? *)'

Эта команда выведет правило ARN, которое вам нужно будет сберечь, поскольку оно вам понадобится в секунду.

Имена ресурсов Amazon (ARN) – это уникальные идентификаторы ресурсов AWS. Узнайте больше о ARN в документах здесь.

Теперь, когда ваше событие CloudWatch готово, вам нужно позволить ему запускать функцию Lambda. Для этого выполните следующую команду из вашего терминала:

aws lambda add-permission \  --statement-id 'hackernews-scheduled-messages' \  --action 'lambda:InvokeFunction' \  --principal 'events.amazonaws.com' \  --source-arn ruleArn \  --function-name functionName \  --region region

В этой команде:

  • ruleArn это ARN правила события CloudWatch, которое вы получили после выполнения предыдущей команды.
  • functionName это название вашей функции из вашего claudia.json файл.
  • region это регион от вашего claudia.json файл.

Ваша команда вернет ответ JSON. Найди Ресурс в ответ и скопируйте лямбда ARN. Это должно выглядеть следующим образом:

  • arn:aws:lambda:eu-central-1:123456789012:function:scheduled-slack-messages

Наконец, вам нужно будет установить триггер, выполнив такую ​​команду из вашего терминала:

aws events put-targets --rule hackerNewsDigest --targets '[{ "Id": "1", "Arn": "your Lambda ARN" }]'

И все, ваше запланированное событие Slack готово. На следующий день в 10:00 по центральноевропейскому времени вы получите сообщение, которое выглядит как ниже.

Если вы не можете ждать 10 утра и хотите увидеть результат раньше, запустите claudia test-lambda команду из вашего терминала. Убедитесь, что вы сначала перешли в папку проекта.

eqh0Xc8b2BzNL4H6nLBcOq8yGSwOaySx4fyX
Сообщение получено в Slack

Больше похожих статей по пути. Если вы хотите быть в курсе моих новых статей или у вас есть тема, о которой вы хотели бы прочитать, подпишитесь на меня и свяжитесь со мной в Twitter – twitter.com/slobodan_.

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

Все иллюстрации созданы с помощью программы SimpleDiagrams4.

Если вы хотите узнать больше о бессерверных программах в целом, посмотрите книгу «Бессерверные программы с Node и Claudia.js», которую я написал вместе с Александром Симовичем для Manning Publications.

Бессерверные программы с Node и Claudia.js
Первоначально модные слова: бессерверные вычисления. AWS Ламбда. Шлюз API. Node.js. Микросервисы. Облачные функции…www.manning.com

Книга научит вас создавать и отлаживать реальные бессерверные API (с БД, аутентификацией и тестами) с помощью Node и Claudia.js. Он также охватывает миграцию вашего существующего приложения, которое работает на серверах, в бессерверную программу, как создать чат-ботов для Facebook Messenger и SMS (с помощью Twilio), а также навыки Alexa.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *