Skip to main content

Starting our bot

The Router class attached to our App instance is the main entry point for our bot. It is responsible for handling all incoming interactions and dispatching them to the appropriate handlers. We will be using the Router class to be an entry point for our bot.

Our goal is to transform whatever request type we receive from our implementation of a web server to a TRequest object. This object will be passed to the Router class to be handled and will fulfill a Promise that we will return to our web server.

// src/server.mjs
import { serve } from 'https://deno.land/std@0.155.0/http/server.ts';
import { app } from './main.mjs';

// The handler function will be called every time a request is made to our server
const handler = async (req) => {
// Ignore any requests that aren't POST
if (req.method !== 'POST') {
return new Response('Method not allowed', { status: 405 });
}

// Loop over headers and transform them to a record
const reqHeaders = {};
for (const [key, value] of req.headers) {
reqHeaders[key] = value;
}

// Create a TRequest object
const tReq = {
body: await req.json(),
headers: reqHeaders,
_request: req,
};

// Handle the request using Disploy's router
const payload = await app.router.entry(tReq);
const { status, headers, body } = payload.serialized;

// Create a Response object to return to Discord
return new Response(JSON.stringify(body), {
// Set the HTTP status code
status,
// Set the HTTP headers
headers: (() => {
// Create an object to hold the headers
const headersObj = {
'content-type': 'application/json',
};
// Loop over the headers passed in as an argument
for (const [key, value] of Object.entries(headers)) {
// If the value is a string, add it to the headers object
if (typeof value === 'string') {
headersObj[key] = value;
}
// If the value is an array, join the array into a string with commas between each element
if (Array.isArray(value)) {
headersObj[key] = value.join(',');
}
}
// Return the headers object
return headersObj;
})(),
});
};

// Create a server
serve(handler);

We can now run our bot by running the following command:

deno run --allow-read --allow-env --allow-net src/server.mjs
Using deno.json tasks
{
{
"importMap": "import_map.json",
"tasks": {
"start": "deno run --allow-read --allow-env --allow-net src/server.mjs",
"deploy": "deno run --allow-read --allow-env src/deploy.mjs"
}
}
}

You can now run your bot by running the following command:

deno task start

Or to deploy commands:

deno task deploy

Exposing our bot to the internet

Now that we have our bot running, we need to expose it to the internet. We will be using ngrok to do this. You can download it from here.

Once you have downloaded ngrok, you can run the following command to expose your bot to the internet:

ngrok http 8000

Once ngrok is running, you should do the following:

  1. Visit https://discord.com/developers/applications/your_bot_id/information
  2. Set INTERACTIONS ENDPOINT URL to https://xxxx-xx-xxx-xxx-xx.ngrok.io/interactions

Setting the interactions endpoint URL