Skip to content

Instantly share code, notes, and snippets.

@SpencerSharkey
Created September 28, 2020 04:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SpencerSharkey/d55aaecde778835ee869bdcea2b983b9 to your computer and use it in GitHub Desktop.
Save SpencerSharkey/d55aaecde778835ee869bdcea2b983b9 to your computer and use it in GitHub Desktop.
const TRIVIA_QUESTION_API =
'https://opentdb.com/api.php?amount=1&encode=url3986';
const TRIVIA_DB = new pylon.KVNamespace('trivia');
const TRIVIA_CMDS = new discord.command.CommandGroup();
const TRIVIA_LOCK_KEY = (
userId: discord.Snowflake,
channelId: discord.Snowflake
) => `lock:${userId}:${channelId}`;
const TRIVIA_KEY = (userId: discord.Snowflake, channelId: discord.Snowflake) =>
`${userId}:${channelId}`;
interface ITriviaQuestion {
category: string;
type: string;
difficulty: string;
question: string;
correct_answer: string;
incorrect_answers: Array<string>;
}
interface ITriviaResponse {
response_code: number;
results: Array<ITriviaQuestion>;
}
interface ITriviaRound {
messageId: discord.Snowflake;
user: discord.Snowflake;
correctAnswer: number;
options: Array<string>;
}
TRIVIA_CMDS.on(
{
name: 'trivia',
aliases: ['t']
},
(args) => ({
answer: args.textOptional()
}),
async (message, { answer }) => {
if (answer === null) {
try {
const lockKey = TRIVIA_LOCK_KEY(message.author.id, message.channelId);
await TRIVIA_DB.put(lockKey, true, {
ifNotExists: true,
ttl: 60000
});
const res = await fetch(TRIVIA_QUESTION_API);
if (!res.ok) {
await TRIVIA_DB.delete(lockKey);
return message.reply('Error connecting to Trivia API :(');
}
const triviaJson: ITriviaResponse = await res.json();
const question = triviaJson.results[0];
if (!question) {
await TRIVIA_DB.delete(lockKey);
return message.reply('Problem reading question from Trivia API :(');
}
const sortedAnswers = [
...question.incorrect_answers.map((a) => decodeURIComponent(a)),
decodeURIComponent(question.correct_answer)
].sort();
const correctAnswer = sortedAnswers.indexOf(
decodeURIComponent(question.correct_answer)
);
const embed = new discord.Embed();
embed.setTitle('Trivia Question');
embed.setThumbnail({
url: message.author.getAvatarUrl()
});
embed.setColor(0x4fc1ff);
embed.setDescription(`**Question:**
${decodeURIComponent(question.question)}
${sortedAnswers
.map((a, idx) => `**Option ${idx + 1}:** ${a}`)
.join('\n')}`);
embed.setFooter({
text: `${decodeURIComponent(
question.category
)} - ${decodeURIComponent(question.difficulty)}`
});
const questionMessage = await message.reply(embed);
const triviaRound: ITriviaRound = {
correctAnswer: correctAnswer,
options: sortedAnswers,
user: message.author.id,
messageId: questionMessage.id
};
await TRIVIA_DB.put(
TRIVIA_KEY(message.author.id, message.channelId),
triviaRound as any,
{
ttl: 60000
}
);
} catch (e) {
console.error(e);
return message.reply(
'You have to answer your last trivia question before starting a new one.'
);
}
} else {
const question = await TRIVIA_DB.get<ITriviaRound>(
TRIVIA_KEY(message.author.id, message.channelId)
);
if (!question) {
return await message.reply(
'No trivia question found! Start one with `!trivia`'
);
}
const channel = await message.getChannel();
const triviaMessage = await channel.getMessage(question.messageId);
if (triviaMessage) {
const embed = triviaMessage.embeds[0];
const correctAnswerString = decodeURIComponent(
question.options[question.correctAnswer]
);
let parsedAnswer = parseInt(answer);
let correct = false;
if (
isNaN(parsedAnswer) &&
correctAnswerString.toLowerCase() === answer.toLowerCase()
) {
correct = true;
} else if (parsedAnswer - 1 === question.correctAnswer) {
correct = true;
}
if (correct) {
embed.setColor(0x00ff00);
embed.setDescription(`${embed.description}
✅ **Correct Answer**: ${decodeURIComponent(
question.options[question.correctAnswer]
)}`);
} else {
embed.setColor(0xff0000);
embed.setDescription(`${embed.description}
❌ **Correct Answer**: ${decodeURIComponent(
question.options[question.correctAnswer]
)}`);
}
await triviaMessage.edit({
embed
});
}
await TRIVIA_DB.delete(TRIVIA_KEY(message.author.id, message.channelId));
await TRIVIA_DB.delete(
TRIVIA_LOCK_KEY(message.author.id, message.channelId)
);
}
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment