Догоняем бессерверные технологии

Введение

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

Это самые известные функции, но, помимо этого, в обновлении добавлена ​​возможность взаимодействия с упомянутыми взаимодействиями через URL-адрес конечной точки взаимодействий.

Это позволяет нам перейти от традиционного приложения слушателя, размещенного на сервере, к бессерверному приложению *аплодисменты*, которое запускает лямбда-функцию на каждом Вызов взаимодействия.

Подключение AWS Lambda к Discord

Во время кодирования мы будем переключаться между «AWS», «Код» и «Портал разработчиков Discord».

АМС

Мы будем использовать AWS API Gateway и AWS Lambda для нашей задачи. Это базовый набор инструментов для бессерверной архитектуры на AWS. Функции будут написаны на Node.js.

  1. Создайте учетную запись и войдите на https://aws.amazon.com
  2. Перейдите к сервису API Lambda, используя навигацию на верхней панели.
  3. Выберите раздел «Функции» на боковой панели (если он еще не выбран)
  4. Нажмите «Создать функцию»

Если у вас хватило смелости щелкнуть по нему сразу с подключенной кредитной картой, вы, вероятно, уже использовали AWS или AWS Lambda.

Если вы колебались, пришло время вас успокоить: уровень бесплатного пользования AWS Lambda включает один миллион бесплатных запросов в месяц и 400 000 ГБ-секунд вычислительного времени в месяц. Гораздо больше, чем вам понадобится для этого урока и, возможно, когда-либо (хотя я желаю вам превысить лимит!).

5. Выберите имя функции, выберите Node.js 14.x и нажмите «Создать функцию».

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

Большой! У нас есть лямбда с шаблонным кодом. Теперь добавьте триггер API — нам нужен какой-то URI для передачи на Discord Portal, верно?

Включите CORS, чтобы разрешить происхождение хоста Discord. Когда-нибудь в будущем вы, возможно, захотите изменить открытость конечной точки API и доменов, разрешенных CORS, чтобы вас не спамили ботами (хотя это не характерно для ресурсов AWS).

Результат:

Перейдите к конечной точке API, щелкнув ее URL-адрес: вы должны увидеть «Привет от Lambda!»

Код

Создайте каталог проекта serverless_discord/. Внутри создайте подкаталоги lambda_bot/ и index.js внутри. Используйте следующий код:

В приведенном выше коде мы следуем структуре, которую вы уже можете видеть в шаблонном коде AWS Lambda (функция exports.handler).

Далее мы выполняем требования конечной точки (проверка полезной нагрузки и ответ на пинг), установленные Discord в документации. Проверка производится с пакетом tweetnacl, которого у нас пока нет. Давайте установим его!

Лучше всего, если ваша node --version близка к версии среды выполнения Lambda (мы выбрали 14.x ) — в идеале, если она такая же. Если это слишком далеко друг от друга — вместе с npm — упакованные модули могут не работать в Lambda.

npm i tweetnacl

Хороший. Теперь давайте заархивируем все это (с node_modules!) и поместим обратно в нашу лямбду. Находясь внутри вашего каталога, введите:

zip -r ../lambda_bot.zip *

АМС

Загрузите zip в панель инструментов Lambda — раздел «Код».

или через интерфейс командной строки, если у вас установлен и настроен интерфейс командной строки AWS:

aws lambda update-function-code \
    --function-name discord \
    --zip-file fileb://../lambda_bot.zip

Все выглядит великолепно. Быстрое создание приложений в Discord за 3, 2, 1, вперед!

Портал разработчиков Discord

Перейдите на Портал разработчиков Discord, выберите Новое приложение и выберите имя. Скопируйте ранее созданную конечную точку API в поле URL-адрес конечной точки взаимодействия в конфигурации бота ниже.

и нажмите Сохранить!

Сохранение выполняет проверку их требований на стороне Discord — они отправляют набор запросов POST на вашу конечную точку.

Прокрутите страницу вверх, чтобы увидеть уведомление, и — вот оно! Большая зеленая полоса успеха — ваш бот жив! Ты сделал это!

Хм? Что? У тебя какая-то ошибка? Эм, что за сообщение об ошибке?

Как я могу исправить конечную точку, когда все, что я знаю, это то, что «что-то» не так? В лучшем случае мы можем предположить, что одно из двух их требований не выполняется.

АМС

Чтобы отладить его со стороны AWS, вы можете создать несколько тестовых фрагментов и запустить их для своего кода. К сожалению, найти точный пример вызова в Discord, чтобы поиздеваться над этим, непросто.

Вы также можете быстро отладить его, запустив код на своем компьютере (просто удалите код в index.js из функции обработчика), но тогда вам потребуется перенаправление внешнего домена на ваш локальный IP-адрес, что имеет свои риски.

Давайте добавим логи консоли, чтобы иметь представление, приходит ли запрос и правильно ли мы его интерпретируем.

Добавить регистрацию в самых первых строках index.js

const nacl = require('tweetnacl');
exports.handler = async (event) => {
  console.log(event)
  // Checking signature (requirement 1.)
  ...

и нажмите «Развернуть».

На портале разработчика Discord «Сохранить» настройки приложения Discord (напоминаем — он повторно запустит POST-запрос Discord к нашей лямбде). Зарегистрировав событие (надеюсь), проверьте его в CloudWatch.

Я нашел это сообщение об ошибке:

(само событие было зарегистрировано на одно поле выше, что может быть полезно)

Ошибка указывает на строку 15 в index.js , в которой указано:

Buffer.from(PUBLIC_KEY, 'hex')

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

const PUBLIC_KEY = process.env.PUBLIC_KEY;

Получите открытый ключ вашего приложения на Портале разработчиков Discord и вставьте в AWS Lambda: Конфигурация → Переменные среды → Изменить… → Добавить… (НЕ используйте кавычки для переменных env)

Key: PUBLIC_KEY, Value: 55ff1c234...

Запустите «Сохранить изменения» прямо сейчас!

Регистрация и создание Slash-команд

В конце index.js добавим обработчик команды, которую мы скоро зарегистрируем.

Мне нужна команда косой черты /foo, которая отвечает «bar» (хорошо, не слишком умопомрачительно).

Скопируйте и вставьте обновленный код в редактор кода AWS Lambda или заархивируйте его и загрузите, как в прошлый раз. Нажмите «Развернуть».

Регистрация команды /foo

Создайте второй подкаталог в serverless_discord/ с именем register_commands/ и перейдите в него.

➜  serverless_discord mkdir register_commands && cd register_commands

Создайте новый файл register.js с:

Чтобы добавить недостающие модули, запустите:

npm i axios dotenv

Но почему у нас сейчас два разных пакета (папки)?

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

Создайте файл .env и измените значения на свои:

ДляGUILD_ID перейдите в Приложение Discord, создайте гильдию Discord (в просторечии Discord Server). В настройках пользователя → Дополнительно → Режим разработчика включен. Вернитесь на главный экран разногласий, щелкните правой кнопкой мыши свою гильдию и выберите Копировать ID.

Затем перейдите на Портал разработчиков Discord, выберите свое приложение → Бот → Добавить бота → Сбросить токен → Копировать — это ваш BOT_TOKEN.

Найдите APP_ID в разделе «Общая информация».

Перейдите в раздел OAuth2 → Генератор URL. Выберите прицелы: bot, application.commands. Права бота: Use Slash Commands.

Скопируйте URL-адрес, сгенерированный ниже, и перейдите по нему — выберите Гильдию, которую вы только что создали.

Вы правы, мы ограничиваем область действия только одной гильдией (вашей). Слэш-команды НЕ будут отображаться в других гильдиях, в которые вы пригласите бота. При создании Slash-команд с Guild Scope изменения применяются немедленно — поэтому они всегда используются в процессе разработки, пока бот не будет полностью готов. Создание или изменение глобальных команд выполняется для каждой гильдии в течение 0–60 минут.

Изменение области действия на Global позже займет у вас около 5 минут с официальной документацией.

Хватит говорить, давайте развернём команду!

➜  register_commands node register.js
➜  register_commands

Отсутствие ошибок означает успех! Быстро перейдите в чат гильдии Discord, начните вводить /foo и нажмите Enter.

Поздравляем! 🏆

Ваш бессерверный бот теперь u̶p̶ ̶a̶n̶d̶ ̶r̶u̶n̶n̶i̶n̶g̶ ждет событий :)

Краткое содержание

Плюсы:

  1. Бюджетный
  2. Легко реализовать
  3. Очень хорошо масштабируется — нет необходимости в сегментировании (только с линейным увеличением стоимости!)

Недостатки:

  1. Заблокировано для AWS (вендор-блокировка) (это конкретное решение)
  2. Может потребоваться реализация CI/CD в большей степени, чем «серверные» варианты — в противном случае изменение ресурсов AWS может оказаться утомительным.
  3. Эта архитектура требует надлежащего ведения журналов и отладочных сообщений на стороне клиента и сервера, чтобы быть эффективной.

В этой статье вы узнали:

  1. Базовый бессерверный инструментарий на AWS
  2. Текущее состояние программирования Discord Bot
  3. Проблемы с AWS Lambda — разработка, развертывание, отладка
  4. Проверка полезной нагрузки с помощью nacl и отправка запросов с помощью axios

Дополнительные источники:

Поднимитесь выше в моей следующей статье:



Как говорит ваша новоиспеченная функция, пора праздновать в баре!

(Теперь вступительная картинка статьи не кажется такой уж странной, верно?)