aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/discord-interactions/.env.example3
-rw-r--r--examples/discord-interactions/README.md17
-rw-r--r--examples/discord-interactions/bun_shim/index.js10
-rw-r--r--examples/discord-interactions/bun_shim/rest.js48
-rw-r--r--examples/discord-interactions/bun_shim/server.js78
-rw-r--r--examples/discord-interactions/commands/hello.js21
-rw-r--r--examples/discord-interactions/package.json8
-rw-r--r--examples/discord-interactions/polyfill.js2
-rw-r--r--examples/discord-interactions/run.js21
9 files changed, 208 insertions, 0 deletions
diff --git a/examples/discord-interactions/.env.example b/examples/discord-interactions/.env.example
new file mode 100644
index 000000000..a21515794
--- /dev/null
+++ b/examples/discord-interactions/.env.example
@@ -0,0 +1,3 @@
+DISCORD_APP_ID=
+DISCORD_BOT_TOKEN=
+DISCORD_PUBLIC_KEY= \ No newline at end of file
diff --git a/examples/discord-interactions/README.md b/examples/discord-interactions/README.md
new file mode 100644
index 000000000..2b62661fc
--- /dev/null
+++ b/examples/discord-interactions/README.md
@@ -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. \ No newline at end of file
diff --git a/examples/discord-interactions/bun_shim/index.js b/examples/discord-interactions/bun_shim/index.js
new file mode 100644
index 000000000..bcdcf5081
--- /dev/null
+++ b/examples/discord-interactions/bun_shim/index.js
@@ -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);
+ }
+} \ No newline at end of file
diff --git a/examples/discord-interactions/bun_shim/rest.js b/examples/discord-interactions/bun_shim/rest.js
new file mode 100644
index 000000000..d1c0b76ee
--- /dev/null
+++ b/examples/discord-interactions/bun_shim/rest.js
@@ -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()}`);
+ }
+} \ No newline at end of file
diff --git a/examples/discord-interactions/bun_shim/server.js b/examples/discord-interactions/bun_shim/server.js
new file mode 100644
index 000000000..d2caff328
--- /dev/null
+++ b/examples/discord-interactions/bun_shim/server.js
@@ -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);
+ }
+ });
+ },
+ });
+ }
+}; \ No newline at end of file
diff --git a/examples/discord-interactions/commands/hello.js b/examples/discord-interactions/commands/hello.js
new file mode 100644
index 000000000..61d92cf82
--- /dev/null
+++ b/examples/discord-interactions/commands/hello.js
@@ -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}!`;
+ }
+} \ No newline at end of file
diff --git a/examples/discord-interactions/package.json b/examples/discord-interactions/package.json
new file mode 100644
index 000000000..cef65c096
--- /dev/null
+++ b/examples/discord-interactions/package.json
@@ -0,0 +1,8 @@
+{
+ "version": "0.0.42",
+ "name": "@bun-examples/discord-interactions",
+
+ "dependencies": {
+ "slash-create": "^5.7.0"
+ }
+} \ No newline at end of file
diff --git a/examples/discord-interactions/polyfill.js b/examples/discord-interactions/polyfill.js
new file mode 100644
index 000000000..abe756dc9
--- /dev/null
+++ b/examples/discord-interactions/polyfill.js
@@ -0,0 +1,2 @@
+Error.captureStackTrace = () => {};
+Buffer.isBuffer = Buffer.isBuffer.bind(Buffer); \ No newline at end of file
diff --git a/examples/discord-interactions/run.js b/examples/discord-interactions/run.js
new file mode 100644
index 000000000..749a039d6
--- /dev/null
+++ b/examples/discord-interactions/run.js
@@ -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 \ No newline at end of file