Skip to content

Commit

Permalink
discord interactions template
Browse files Browse the repository at this point in the history
  • Loading branch information
evanwashere authored and Jarred-Sumner committed Jul 5, 2022
1 parent a577e35 commit 4a927e0
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 0 deletions.
3 changes: 3 additions & 0 deletions examples/discord-interactions/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
DISCORD_APP_ID=
DISCORD_BOT_TOKEN=
DISCORD_PUBLIC_KEY=
17 changes: 17 additions & 0 deletions examples/discord-interactions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# /create with Bun runtime

A [slash-create](https://npm.im/slash-create) template, using [Bun runtime](https://bun.sh).

## Getting Started
### Cloning the repo
```sh
bun create discord-interactions interactions-bot
```

After that, make sure to install dependencies using bun or any other npm compatible package manager:
```sh
bun install
```

### Development
To run this locally, rename `.env.example` to `.env` and fill in the variables, then you can run `bun run.js` to start a local dev environment and use something like ngrok/cloudflare to tunnel it to a URL.
10 changes: 10 additions & 0 deletions examples/discord-interactions/bun_shim/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Creator } from 'slash-create';
import { FetchRequestHandler } from './rest.js';
export { default as BunServer } from './server.js';

export class BunSlashCreator extends Creator {
constructor(...args) {
super(...args);
this.requestHandler = new FetchRequestHandler(this);
}
}
48 changes: 48 additions & 0 deletions examples/discord-interactions/bun_shim/rest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { RequestHandler } from 'slash-create';
import { MultipartData } from 'slash-create/lib/util/multipartData.js';

export class FetchRequestHandler extends RequestHandler {
toString() {
return '[RequestHandler]';
}

async request(method, url, auth = true, body, file) {
const creator = this._creator;

const headers = {
'user-agent': this.userAgent,
'x-ratelimit-precision': 'millisecond',
};

if (auth) {
headers.authorization = creator.options.token;
if (!headers.authorization) throw new Error('No token was set in the SlashCreator.');
}

if (body) {
if (method !== 'GET' && method !== 'DELETE') {
body = JSON.stringify(body);
headers['content-type'] = 'application/json';
}
}

if (file) {
if (Array.isArray(file)) {}
else if (file.file) file = [file];
else throw new Error('Invalid file object.');

const form = new MultipartData();
headers['content-type'] = `multipart/form-data; boundary=${form.boundary}`;

for (const f of file) form.attach(f.name, f.file, f.name);
if (body) form.attach('payload_json', JSON.stringify(body));

body = Buffer.concat(form.finish());
}

const res = await fetch('https://discord.com' + this.baseURL + url, { body, method, headers });

if (res.ok) return res.json();
throw new Error(`${method} got ${res.status} - ${await res.text()}`);
}
}
78 changes: 78 additions & 0 deletions examples/discord-interactions/bun_shim/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Server } from 'slash-create';
import { MultipartData } from 'slash-create/lib/util/multipartData.js';

export default class BunServer extends Server {
#server = null;
#handler = null;
isWebserver = true;

constructor() {
super({ alreadyListening: true });
}

stop() {
if (this.#server) this.#server.close();
else throw new Error('BunServer not started');
}

createEndpoint(path, handler) {
this.#handler = handler;
}

listen(port) {
const getHandler = () => this.#handler;

this.#server = Bun.serve({
port,

async fetch(req) {
const handler = getHandler();
if (!handler) return new Response('Server has no handler.', { status: 503 });
if (req.method !== 'POST') return new Response('Server only supports POST requests.', { status: 405 });

const reqHeaders = Object.fromEntries(req.headers.entries());

const reqBody = await req.json();

return await new Promise(async (ok, err) => {
try {
await handler({
request: req,
body: reqBody,
response: null,
headers: reqHeaders,
}, async response => {
let body = response.body;
const headers = new Headers();

if (response.headers) {
for (const key in response.headers) {
headers.set(key, response.headers[key]);
}
}

if ('string' !== typeof body) {
body = JSON.stringify(body);
headers.set('content-type', 'application/json');
}

if (response.files) {
const form = new MultipartData();
headers.set('content-type', `multipart/form-data; boundary=${form.boundary}`);

form.attach('payload_json', body);
for (const file of response.files) form.attach(file.name, file.file, file.name);

body = Buffer.concat(form.finish());
}

ok(new Response(body, { headers, status: response.status }));
});
} catch (error) {
err(error);
}
});
},
});
}
};
21 changes: 21 additions & 0 deletions examples/discord-interactions/commands/hello.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const { SlashCommand, CommandOptionType } = require('slash-create');

module.exports = class HelloCommand extends SlashCommand {
constructor(creator) {
super(creator, {
name: 'hello',
description: 'Says hello to you.',
options: [{
type: CommandOptionType.STRING,
name: 'food',
description: 'What food do you like?'
}]
});

this.filePath = __filename;
}

async run(ctx) {
return ctx.options.food ? `You like ${ctx.options.food}? Nice!` : `Hello, ${ctx.user.username}!`;
}
}
8 changes: 8 additions & 0 deletions examples/discord-interactions/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"version": "0.0.42",
"name": "@bun-examples/discord-interactions",

"dependencies": {
"slash-create": "^5.7.0"
}
}
2 changes: 2 additions & 0 deletions examples/discord-interactions/polyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Error.captureStackTrace = () => {};
Buffer.isBuffer = Buffer.isBuffer.bind(Buffer);
21 changes: 21 additions & 0 deletions examples/discord-interactions/run.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// polyfill v8 and node (TODO: fix in bun)
import './polyfill.js';

import path from 'node:path';
import { BunServer, BunSlashCreator } from './bun_shim/index.js';

const client = new BunSlashCreator({
token: process.env.DISCORD_BOT_TOKEN,
publicKey: process.env.DISCORD_PUBLIC_KEY,
applicationID: process.env.DISCORD_APP_ID,
});

// client.on('debug', console.log);
client.on('error', console.error);

client.withServer(new BunServer());
client.registerCommandsIn(path.join(__dirname, 'commands')).syncCommands();

await client.server.listen(1337);

// client.server.stop(); // stop server

0 comments on commit 4a927e0

Please sign in to comment.