0
0
Fork 0

Add functional code

This commit is contained in:
Tyler-A 2020-04-20 15:48:01 -06:00
parent 23bc6c10f5
commit f34b4f2cb3
5 changed files with 251 additions and 0 deletions

74
src/api.ts Normal file
View file

@ -0,0 +1,74 @@
const axios = require("axios").default;
import {
QUOTE_URL,
DISCORD_WEBHOOK,
DISCORD_API_BASE,
DISCORD_CHANNEL_ID,
DISCORD_OAUTH_TOKEN,
DISCORD_WEBHOOK_USERNAME
} from "./config";
import { LOAD_USED_QUOTES } from "./database";
export const GET_QUOTE = async (count = 1): Promise<string> => {
return axios.get(
QUOTE_URL
).then((response: any) => {
let used_quotes = LOAD_USED_QUOTES();
let quotes = response.data.split("\n");
let quote = quotes[Math.floor(Math.random() * quotes.length)];
while (used_quotes.includes(quote)) {
quote = quotes[Math.floor(Math.random() * quotes.length)];
};
used_quotes.push(quote);
return quote
})
.catch((err: any) => {throw err});
}
export const GET_MESSAGE = async (id: string): Promise<msg_meta> => {
return axios.get(
`${DISCORD_API_BASE}/channels/${DISCORD_CHANNEL_ID}/messages/${id}`,
{
headers: {
Authorization: `Bot ${DISCORD_OAUTH_TOKEN}`
}
}
)
.then((response:any) => {
response = response.data;
if (response.reactions) {
return {
reactions: response.reactions,
quote_a: response.embeds[0].fields[0],
quote_b: response.embeds[0].fields[1]
}
} else {
return {
reactions: [],
quote_a: response.embeds[0].fields[0],
quote_b: response.embeds[0].fields[1]
}
}
}).catch((err:any) => {throw err});
};
export const WEBHOOK_PUSH = async (embed: any): Promise<string> => {
return await axios.post(
`${DISCORD_WEBHOOK}?wait=true`,
{
username: DISCORD_WEBHOOK_USERNAME,
embeds: [embed]
}
)
.then((response: any) => {
return response.data.id;
}).catch((err:any) => {throw err});
};

30
src/config.template.ts Normal file
View file

@ -0,0 +1,30 @@
// A bot OAuth token that has access to the channels we are looking in.
export const DISCORD_OAUTH_TOKEN: string = ``;
// The Discord channel ID that the bot will be posting in
export const DISCORD_CHANNEL_ID: string = ``;
// The Discord webhook that we will be posting into
export const DISCORD_WEBHOOK: string = ``;
// The name of the webhook in Discord, if left undefined it will use the
// default name from within Discord
export const DISCORD_WEBHOOK_USERNAME: string|undefined = undefined;
// The file names for the database operations
export const DB_NAME: string = `used_quotes.json`
export const MSG_ID_FILE: string = `msg_id`
// The twitch.center URL for the quote list
export const QUOTE_URL: string = ``;
// The base API endpoint for Discord
export const DISCORD_API_BASE: string = `https://discordapp.com/api/v6`
// The details for the Discord emoji
export const EMOJI_A_ID: string = `701289852146286633`;
export const EMOJI_B_ID: string = `701289851923988540`;
export const EMOJI_A_NAME: string = `star`;
export const EMOJI_B_NAME: string = `like`;

21
src/database.ts Normal file
View file

@ -0,0 +1,21 @@
import { MSG_ID_FILE, DB_NAME } from "./config";
import * as fs from "fs";
export const LOAD_MSG_ID = (): string => {
return fs.readFileSync(`./${MSG_ID_FILE}`, `utf8`)
};
export const WRITE_MSG_ID = (new_id: string) => {
return fs.writeFileSync(`./${MSG_ID_FILE}`, new_id)
};
export const LOAD_USED_QUOTES = (): string[] => {
return JSON.parse(fs.readFileSync(`./${DB_NAME}`, `utf`));
};
export const WRITE_USED_QUOTES = (data: string[]) => {
fs.writeFileSync(`${DB_NAME}`, JSON.stringify(data));
}

100
src/main.ts Normal file
View file

@ -0,0 +1,100 @@
import { LOAD_MSG_ID, WRITE_MSG_ID } from "./database";
import { GET_MESSAGE, GET_QUOTE, WEBHOOK_PUSH } from "./api";
import { EMOJI_A_ID, EMOJI_B_ID, EMOJI_B_NAME, EMOJI_A_NAME } from "./config";
const MAIN = async () => {
// Load message ID from file
let msg_id: string = LOAD_MSG_ID();
// Get message data
let msg: msg_meta = await GET_MESSAGE(msg_id);
// Compare values of reaction counts
let emoji_a: reaction|undefined = msg.reactions.find(
(reaction: reaction) => {return reaction.emoji.id === EMOJI_A_ID}
);
let emoji_b: reaction|undefined = msg.reactions.find(
(reaction: reaction) => {return reaction.emoji.id === EMOJI_B_ID}
);
// Both quotes have had a reaction
let winning_emoji: reaction|"TIE"|"NO_DATA";
if (emoji_a !== undefined && emoji_b !== undefined) {
if (emoji_a!.count === emoji_b!.count) {
winning_emoji = "TIE";
}
else if (emoji_a!.count > emoji_b!.count) {
winning_emoji = emoji_a!;
}
else if (emoji_a!.count < emoji_b!.count) {
winning_emoji = emoji_b!;
};
}
// Only emoji_a has had a reaction
else if (emoji_a !== undefined && emoji_b === undefined) { winning_emoji = emoji_a!; }
// Only emoji_b has had a reaction
else if (emoji_a === undefined && emoji_b !== undefined) { winning_emoji = emoji_b!; }
// Neither emoji has had a reaction
else { winning_emoji = "NO_DATA"; }
winning_emoji = winning_emoji!;
var new_quote_a: string, new_quote_b: string;
// Get new quotes
switch (winning_emoji) {
// Discard both previous quotes
case "TIE":
case "NO_DATA":
new_quote_a = await GET_QUOTE();
new_quote_b = await GET_QUOTE();
break;
// Only get one new quote
default:
winning_emoji = winning_emoji as reaction;
let split_str: string = " - **"
if (winning_emoji.emoji.id === EMOJI_A_ID) {
new_quote_a = msg.quote_a.value.split(split_str, 2)[1].slice(0, -2);
} else {
new_quote_a = msg.quote_b.value.split(split_str, 2)[1].slice(0, -2);
};
new_quote_b = await GET_QUOTE();
break;
};
// Construct new embed
let embed: any = {
title: `Quote Bracketeering`,
description: `Vote for your favourite quote by reacting to this message with the proper emoji!\n\n\n**Note:** If both quotes end in the same number of votes they will __**BOTH**__ be eliminated.`,
color: 43520,
fields: [
{
name: `Quote A:`,
value: `<:${EMOJI_A_NAME}:${EMOJI_A_ID}> - **${new_quote_a}**`,
inline: false
},
{
name: `Quote B:`,
value: `<:${EMOJI_B_NAME}:${EMOJI_B_ID}> - **${new_quote_b}**`,
inline: false
}
]
}
// Post to webhook and store new message ID
let new_msg_id = await WEBHOOK_PUSH(embed);
WRITE_MSG_ID(new_msg_id);
};
MAIN();

26
src/types.d.ts vendored Normal file
View file

@ -0,0 +1,26 @@
type snowflake = number;
interface emoji {
name: string;
id: string;
}
interface reaction {
emoji: emoji;
count: number;
me: boolean;
}
interface embed_field {
name: string;
value: string;
inline: boolean;
}
interface msg_meta {
reactions: reaction[];
quote_a: embed_field;
quote_b: embed_field;
}