<file_sep>const { SlashCommandBuilder } = require('@discordjs/builders');
const { MessageEmbed } = require('discord.js');
const max_dice = 10; // Set maximum number of Dice so as to avoid troll spam

module.exports = {
	data: new SlashCommandBuilder()
		.setName('roll')
		.setDescription('Roll a number of configurable dice!')
		.addIntegerOption(option =>
			option.setName('sides')
				.setDescription('Number of sides for the die.')
				.setRequired(true))
		.addIntegerOption(option =>
			option.setName('dice')
				.setDescription('Total number of dice to roll. Default: 1'))
		.addStringOption(option =>
			option.setName('verbosity')
				.setDescription('Show each individual roll (Verbose) or a simple sum (Simple). Default: Simple')
				.addChoice('Verbose', 'verbose')
				.addChoice('Simple', 'simple')),
	async execute(interaction) {

		// Get our options
		const sides = interaction.options.getInteger('sides');
		let dice = interaction.options.getInteger('dice');
		let verbosity = interaction.options.getString('verbosity');

		// Check if we have < 2 Sides to prevent trolling
		if (sides < 2) {
			return interaction.reply({content: 'Not enough sides to roll! You must have more than 1 side.', ephemeral: true});
		}

		// Set Dice to 1 if not chosen. Else, prevent trolling of max dice number.
		if (!dice) {
			dice = 1;
		}
		else if (dice < 1) {
			return interaction.reply({content: 'Cannot roll less than 1 die.', ephemeral:true});
		}
		else {
			dice = Math.min(dice, max_dice);
		}

		// Format a simple roll function
		if (dice === 1) {
			await interaction.deferReply();

			// Roll our die
			let result = RollDice(sides);

			// Format into a pretty embed
			const embed = new MessageEmbed()
				.setColor('#E61313')
				.setTitle(`:game_die: Roll Results (1d${sides.toString()}) :game_die:`)
				.addFields(
					{ name: 'Total', value: result.toString()},
				);

			// Send the embed to our reply.
			interaction.editReply({ embeds: [embed] });
		}
		else {
			await interaction.deferReply();

			// Create our results array and total
			const results_array = new Array();
			let results_total = 0;

			// Roll our dice.
			for (i = 0; i < dice; i++) {
				results_array[i] = RollDice(sides);
				results_total = results_total + results_array[i];
			}

			// Format into a pretty embed
			const embed = new MessageEmbed()
				.setColor('#E61313')
				.setTitle(`:game_die: Roll Results (${dice}d${sides.toString()}) :game_die:`)
				.addFields(
					{ name: 'Total', value: results_total.toString()},
				);
			// Expound if Verbose was requested.
			if (verbosity === 'Verbose' || verbosity === 'verbose') {
				let results_string = '';

				// Construct a string of results based on the length of the array
				for(j=0; j < results_array.length; j++) {
					results_string = results_string + results_array[j].toString() + ' ';
				 }
				 // Add our Rolls field to the existing embed.
				 embed.addFields(
						 { name: `Rolls`, value: results_string}
					 );
			}

			// Send the embed to our reply.
			interaction.editReply({ embeds: [embed] });
		}

		function RollDice(num_of_sides){
			let result = Math.random() * ((num_of_sides + 1) - 1) + 1;
			return Math.floor(result);
		}

	},
};
<file_sep># serious-bot
Discord Bot for learning JavaScript and bot programming
<file_sep>const { SlashCommandBuilder } = require('@discordjs/builders');
const { MessageEmbed } = require('discord.js');
const fetch = require('node-fetch');
const trim = (str, max) => ((str.length > max) ? `${str.slice(0, max - 3)}...` : str);

module.exports = {
	data: new SlashCommandBuilder()
		.setName('wiki')
		.setDescription('Search Wikipedia for a summary!')
		.addStringOption(option =>
			option.setName('input')
				.setDescription('What you want to search for.')
				.setRequired(true)),
	async execute(interaction) {
		await interaction.deferReply();

		const term = interaction.options.getString('input');
		console.log(`Attempting Search with option ${term}.`);

		// Turn into a URL search format so we don't have to do messy formatting ourselves.
		const query = new URLSearchParams(term);

		// Hit Wikipedia's API.
		const result = await fetch(`https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${query}&srlimit=1&srnamespace=0&format=json`).then(response => response.json());

		// On the off-chance nothing is found, say so.
		if (!result) {
			return interaction.editReply(`No results found for **${term}**.`);
		}

		// If something is found, get the main page and the thumbnail.
		const pageTitle = result.query.search[0].title;
		const pageid = result.query.search[0].pageid;
		const resultingPage = await fetch(`https://en.wikipedia.org/w/api.php?action=query&titles=${pageTitle}&prop=extracts&exintro=&explaintext=&format=json`).then(response => response.json());
		const resultingPageImages = await fetch(`https://en.wikipedia.org/w/api.php?action=query&titles=${pageTitle}&prop=pageimages&piprop=thumbnail|original&format=json`).then(response => response.json());

		// Check if a thumbnail exists, and if so, assign it for the embed.
		let pageThumbnail = '';
		if (resultingPageImages.query.pages[pageid].thumbnail) {
			pageThumbnail = resultingPageImages.query.pages[pageid].thumbnail.source;
		}
		else {
			pageThumbnail = 'https://en.wikipedia.org/static/images/project-logos/enwiki.png';
		}

		// Format into an embed

		const embed = new MessageEmbed()
			.setColor('#C0D6E4')
			.setTitle(resultingPage.query.pages[pageid].title)
			.setURL(`https://en.wikipedia.org/?curid=${resultingPage.query.pages[pageid].pageid}`)
			.setAuthor('Wikipedia', 'https://en.wikipedia.org/static/images/project-logos/enwiki.png', 'https://en.wikipedia.org')
			.setThumbnail(`${pageThumbnail}`)
			.addFields(
				{ name: 'Summary', value: trim(resultingPage.query.pages[pageid].extract, 600) },
			)
			.setFooter('This summary is from the first entry from Wikipedia based on your search terms.');

		interaction.editReply({ embeds: [embed] });
	},
};
