Догоняем бессерверные технологии
Введение
Недавно Discord представил Взаимодействия и Команды с косой чертой, чтобы облегчить пользователям работу с ботами. Частично причина заключалась в защите конфиденциальности пользователей — боты теперь немного вынуждены отказываться от флагов для чтения сообщений на серверах Discord, что ранее вызывало озабоченность в связи с незаконной обработкой данных разработчиками ботов.
Это самые известные функции, но, помимо этого, в обновлении добавлена возможность взаимодействия с упомянутыми взаимодействиями через URL-адрес конечной точки взаимодействий.
Это позволяет нам перейти от традиционного приложения слушателя, размещенного на сервере, к бессерверному приложению *аплодисменты*, которое запускает лямбда-функцию на каждом Вызов взаимодействия.
Подключение AWS Lambda к Discord
Во время кодирования мы будем переключаться между «AWS», «Код» и «Портал разработчиков Discord».
АМС
Мы будем использовать AWS API Gateway и AWS Lambda для нашей задачи. Это базовый набор инструментов для бессерверной архитектуры на AWS. Функции будут написаны на Node.js.
- Создайте учетную запись и войдите на https://aws.amazon.com
- Перейдите к сервису API Lambda, используя навигацию на верхней панели.
- Выберите раздел «Функции» на боковой панели (если он еще не выбран)
- Нажмите «Создать функцию»
Если у вас хватило смелости щелкнуть по нему сразу с подключенной кредитной картой, вы, вероятно, уже использовали 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̶ ждет событий :)
Краткое содержание
Плюсы:
- Бюджетный
- Легко реализовать
- Очень хорошо масштабируется — нет необходимости в сегментировании (только с линейным увеличением стоимости!)
Недостатки:
- Заблокировано для AWS (вендор-блокировка) (это конкретное решение)
- Может потребоваться реализация CI/CD в большей степени, чем «серверные» варианты — в противном случае изменение ресурсов AWS может оказаться утомительным.
- Эта архитектура требует надлежащего ведения журналов и отладочных сообщений на стороне клиента и сервера, чтобы быть эффективной.
В этой статье вы узнали:
- Базовый бессерверный инструментарий на AWS
- Текущее состояние программирования Discord Bot
- Проблемы с AWS Lambda — разработка, развертывание, отладка
- Проверка полезной нагрузки с помощью
nacl
и отправка запросов с помощьюaxios
Дополнительные источники:
- Код с полным решением доступен в моем репозитории: https://github.com/jakjus/discord-aws-lambda-article
- Еще один хорошо сделанный туториал на эту тему, но с небольшими отличиями (т.е. использует Python; более сложный): https://oozio.medium.com/serverless-discord-bot-55f95f26f743
- Документация для разработчиков Discord https://discord.com/developers/docs/interactions/application-commands (см. также раздел Получение и ответ)
- Cosmos X — мой бот Discord Galactic RPG! https://cosmosx.fun/
Поднимитесь выше в моей следующей статье:
Как говорит ваша новоиспеченная функция, пора праздновать в баре!
(Теперь вступительная картинка статьи не кажется такой уж странной, верно?)