Отне ми известно време, за да стартирам моя Discord Bot на Cloudflare Workers. Не исках да изтегля всички съществуващи рамки само за една проста, единствена команда, която искам на моя Discord сървър.

Излязох на мисия и се опитах да конфигурирам Discord Bot сам с наличната документация. Беше супер, супер, искам да кажа, наистина, супер трудно да се получи правилната информация от документацията за разработчици на Discord. Не знам как може да съществува такава богата екосистема от ботове с толкова много липсващи части в документите. Може също да съм само аз. Но хей, в крайна сметка успях да проработя и ако някой срещне същите проблеми: Прочетете нататък.

Както и да е, настроих Cloudflare Worker да отговаря на команди с наклонена черта или команди на приложение в Discord за извикване на външен API. За да направите това, трябва да създадете бот в Портал за разработчици на Discord и да конфигурирате персонализиран INTERACTIONS ENDPOINT URL

Под Сигурност и упълномощаване те описват какво е необходимо за проверка на персонализиран URL адрес на крайна точка, но липсва важна част, която ще обясня малко по-късно.

Накратко, те искат да потвърдят вашата крайна точка, като изпратят подпис, клеймо за време и тялото до вашата крайна точка, тя трябва да бъде потвърдена и да се върне с код на състояние 200 или код на състояние 401, ако не успее. За проверка те извикват две заявки и тестват дали една отговаря успешно и една като неуспешна. В техните примери за код те само споменават кодовете за състояние, но също така искат да получат полезния товар, който изпращат, върнат от вас. Това не беше очевидно за мен в документите, а също и в съобщението за грешка, което получих на страницата за разработчици на Discord:

Грешки при валидиране: interakcijи_endpoint_url: Посоченият URL адрес на крайна точка на взаимодействие не може да бъде проверен.

Едва след като проверих в JavaScript конзолата за разработчици, видях, че тялото е деформирано или липсва. О!

Освен това с Cloudflare Workers нямате достъп до Buffer от NodeJS, който те използват в своите примери, така че ние използваме друг буферен пакет, който работи в браузъри и Cloudflare Workers. Нека да стигнем до него.

Проверете и оторизирайте взаимодействията на Discord

Първо инсталирайте тези два пакета: buffer и tweetnacl:

npm i tweetnacl buffer

Сега във вашия Workers JavaScript импортирайте двете:

import nacl from 'tweetnacl'
const Buffer = require('buffer/').Buffer

Ето функцията handleRequest на Cloudflare Worker, моля, актуализирайте променливата PUBLIC_KEY:

async function handleRequest(request, env) {
  if (request.method === 'POST') {
    const req = await request.json()

    const headers = request.headers
    const PUBLIC_KEY = 'your-public_key-here'
    const signature = headers.get('X-Signature-Ed25519')
    const timestamp = headers.get('X-Signature-Timestamp')

    if (signature && timestamp) {
      const isVerified = nacl.sign.detached.verify(
        Buffer(timestamp + JSON.stringify(req)),
        Buffer(signature, 'hex'),
        Buffer(PUBLIC_KEY, 'hex'),
      )

      if (!isVerified) {
        return new Response(JSON.stringify(req), { status: 401 })
      } else {
        return new Response(JSON.stringify(req), { status: 200 })
      }
    }
  }
}

Сега, ако възнамерявате да валидирате вашето приложение Discord, то трябва да успее, тъй като отговорът ще изпрати правилния код на състоянието, а също и тялото обратно като низ към Discord.

Поправянето на цялото това нещо отне повече време, отколкото искам да призная. Може би най-накрая мога да започна да изграждам действителния бот следващата седмица и да публикувам актуализация.