0
0
Fork 0

Add code to make the stuff work

This commit is contained in:
Oliver-Akins 2021-07-18 01:18:18 -06:00
parent a18b73fe52
commit 3d9feabe88
15 changed files with 517 additions and 0 deletions

View file

@ -0,0 +1,29 @@
import { Request, ResponseToolkit } from "@hapi/hapi";
import { config, db } from "@/main";
import axios from "axios";
export default {
method: `GET`, path: `/discord/auth/callback`,
async handler(request: Request, h: ResponseToolkit) {
console.log(`Authentication finishing!`)
let code = request.query.code;
let data = new URLSearchParams();
data.set(`client_id`, config.discord.client_id);
data.set(`client_secret`, config.discord.secret);
data.set(`grant_type`, `authorization_code`);
data.set(`code`, code);
data.set(`redirect_uri`, config.discord.auth_redirect);
let r = await axios.post(`https://discord.com/api/v8/oauth2/token`, data, {
headers: {
'Content-Type': `application/x-www-form-urlencoded`
}
});
db.webhook.token = r.data.webhook.token;
db.webhook.id = r.data.webhook.id;
return r.data;
},
}

View file

@ -0,0 +1,11 @@
import { Request, ResponseToolkit } from "@hapi/hapi";
import { config } from "@/main";
export default {
method: `GET`, path: `/discord/auth`,
async handler(request: Request, h: ResponseToolkit) {
return h.redirect(
`https://discord.com/api/oauth2/authorize?client_id=${config.discord.client_id}&redirect_uri=${encodeURIComponent(config.discord.auth_redirect)}&response_type=code&scope=webhook.incoming`
);
},
}

View file

@ -0,0 +1,75 @@
import { selectQuote } from "@/utils/components/dropdowns/select_quote";
import { deleteVote } from "@/utils/components/buttons/delete_vote";
import { countVotes } from "@/utils/components/buttons/count_votes";
import { showUserVote } from "@/utils/components/buttons/my_vote";
import { Request, ResponseToolkit } from "@hapi/hapi";
import { config } from "@/main";
import boom from "@hapi/boom";
import nacl from "tweetnacl";
import { viewDB } from "@/utils/components/buttons/view_db";
async function handleButton(data: any): Promise<object> {
switch (data.data.custom_id) {
case "deleteVote":
return await deleteVote(data);
case "showCount":
return await countVotes(data);
case "viewDB":
return await viewDB(data);
case "showMyVote":
return await showUserVote(data);
};
return {
type: 4,
data: {
content: `Unknown button, how did you trigger this response? 0\_o`,
flags: 1 << 6,
}
};
};
export default {
method: `POST`, path: `/discord/webhook`,
async handler(request: Request, h: ResponseToolkit) {
let sig = request.headers[`x-signature-ed25519`];
let timestamp = request.headers[`x-signature-timestamp`];
let body: any = request.payload;
// Verify the body against Discord's stuff
let verified = nacl.sign.detached.verify(
Buffer.from(timestamp + JSON.stringify(body)),
Buffer.from(sig, `hex`),
Buffer.from(config.discord.public_key, `hex`)
);
if (!verified) {
return boom.unauthorized(`invalid request signature`);
};
switch (body.type) {
case 1:
return { type: 1 };
case 3:
// Parse the data properly
if (body.data.component_type === 3) {
return await selectQuote(body)
} else if (body.data.component_type === 2) {
return await handleButton(body)
};
return {
type: 4,
data: {
content: `Unknown component type.`,
flags: 1 << 6,
},
};
default:
return boom.badRequest()
};
},
};

View file

@ -0,0 +1,122 @@
import { Request, ResponseToolkit } from "@hapi/hapi";
import { DISCORD_API_URI } from "@/constants";
import { getQuote } from "@/utils/quotes";
import { config, db } from "@/main";
import fs from "fs/promises";
import axios from "axios";
export default {
method: `GET`, path: `/bracket/finish`,
async handler(request: Request, h: ResponseToolkit) {
if (!db.bracket.msg) {
var quotes = await getQuote(config.discord.quote_max);
} else {
// Delete the old message from Discord while processing the new one
let wh = db.webhook;
await axios.delete(`${DISCORD_API_URI}/webhooks/${wh.id}/${wh.token}/messages/${db.bracket.msg}`);
// Save the previous bracket to the history file
let pastBrackets = JSON.parse(
await fs.readFile(config.server.bracket_history, `utf-8`)
);
pastBrackets.push({
quotes: db.bracket.quotes,
votes: db.bracket.votes,
});
await fs.writeFile(config.server.bracket_history, JSON.stringify(pastBrackets));
// Calculate the winners from the previous bracket
let r = await request.server.inject(`/bracket/winners`);
var quotes: string[] = JSON.parse(r.payload).winners;
var winner_count = quotes.length;
// Get any new quotes for the bracket
quotes.push(...(await getQuote(config.discord.quote_max - quotes.length)));
}
// Setup the database for the new bracket
db.bracket.quotes = quotes;
db.bracket.votes = {};
db.bracket.users = {};
db.bracket.msg = "";
let message = {
content: `New Quote Bracket!`,
embeds: [
{
description: `Note: If **more than ${Math.floor(config.discord.quote_max / 2)}** of the quotes tie, they will all be eliminated, otherwise, the ones that tie will move on to the next bracket.`,
fields: quotes.map((quote, i) => { return {
name: `${i < winner_count ? '👑 ' : ''}Quote: ${i + 1}`,
value: quote,
}}),
}
],
components: [
{
type: 1,
components: [
{
type: 3,
custom_id: `quote`,
placeholder: `Choose Your Favourite Quote`,
options:quotes.map((_, i) => {
return {
label: `Quote ${i + 1}`,
value: i,
emoji: i < winner_count ? {
name: `👑`
} : null
}
}),
}
]
},
{
type: 1,
components: [
{
type: 2,
style: 1,
label: `What Did I Vote For?`,
custom_id: `showMyVote`
},
{
type: 2,
style: 4,
label: `Remove Vote`,
custom_id: `deleteVote`
}
]
}
]
};
if (config.discord.dev_buttons) {
message.components.push({
type: 1,
components: [
{
type: 2,
style: 1,
label: `See Count`,
custom_id: `showCount`,
},
{
type: 2,
style: 1,
label: `See Database Object`,
custom_id: `viewDB`,
}
]
});
};
let url = `${DISCORD_API_URI}/webhooks/${db.webhook.id}/${db.webhook.token}`;
let r = await axios.post(url, message, { params: { wait: true } });
db.bracket.msg = r.data.id;
return { status: r.status }
},
}

View file

@ -0,0 +1,26 @@
import { config, db } from "@/main"
export default {
method: `GET`, path: `/bracket/winners`,
async handler() {
let winners: string[] = [];
let highest = -1;
// Find the winners of the quote
for (var i in db.bracket.quotes) {
if (db.bracket.votes[i] > highest) {
winners = [ db.bracket.quotes[i] ];
highest = db.bracket.votes[i];
} else if (db.bracket.votes[i] === highest) {
winners.push(db.bracket.quotes[i]);
};
};
// Ensure that the all elimination limit didn't get hit
if (winners.length > Math.floor(config.discord.quote_max / 2)) {
return { winners: [] };
};
return { winners };
},
}