Slash commands for most fun commands (#45)
* Move few fun commands to interactions * Move poll command to slash * Move even more fun commands into interactions api * Move the rest of fun commands to interactions * Pull request review fixes
This commit is contained in:
parent
0bdb4514bc
commit
3c1642f05f
|
@ -1,5 +1,7 @@
|
||||||
import {NamedCommand, RestCommand} from "onion-lasers";
|
import {NamedCommand, RestCommand} from "onion-lasers";
|
||||||
import {random} from "../../lib";
|
import {random} from "../../lib";
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
|
|
||||||
const responses = [
|
const responses = [
|
||||||
"Most likely,",
|
"Most likely,",
|
||||||
|
@ -23,7 +25,14 @@ const responses = [
|
||||||
"Outlook not so good,",
|
"Outlook not so good,",
|
||||||
"Very doubtful,"
|
"Very doubtful,"
|
||||||
];
|
];
|
||||||
|
export const header = new SlashCommandBuilder()
|
||||||
|
.setDescription("Answers your question in an 8-ball manner.")
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option.setName("question").setDescription("Question to ask the 8-ball.").setRequired(true)
|
||||||
|
);
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
interaction.reply(`${random(responses)} ${interaction.user.tag}`);
|
||||||
|
}
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Answers your question in an 8-ball manner.",
|
description: "Answers your question in an 8-ball manner.",
|
||||||
usage: "<question>",
|
usage: "<question>",
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import {User} from "discord.js";
|
import {User} from "discord.js";
|
||||||
import {Command, NamedCommand} from "onion-lasers";
|
import {Command, NamedCommand} from "onion-lasers";
|
||||||
import {random, parseVars} from "../../lib";
|
import {random, parseVars} from "../../lib";
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
const cookies = [
|
const cookies = [
|
||||||
`has given %target% a chocolate chip cookie!`,
|
`has given %target% a chocolate chip cookie!`,
|
||||||
`has given %target% a soft homemade oatmeal cookie!`,
|
`has given %target% a soft homemade oatmeal cookie!`,
|
||||||
|
@ -25,6 +26,20 @@ const cookies = [
|
||||||
`bakes %target% fresh cookies, it smells amazing.`
|
`bakes %target% fresh cookies, it smells amazing.`
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const header = new SlashCommandBuilder()
|
||||||
|
.setDescription("Gives specified user a cookie.")
|
||||||
|
.addUserOption((option) =>
|
||||||
|
option.setName("user").setDescription("User you want to give a cookie to.").setRequired(true)
|
||||||
|
);
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
const {options} = interaction;
|
||||||
|
|
||||||
|
return interaction.reply(
|
||||||
|
`:cookie: ${interaction.user.tag} ${parseVars(random(cookies), {
|
||||||
|
target: options.getUser("user", true).tag.toString()
|
||||||
|
})}`
|
||||||
|
);
|
||||||
|
}
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Gives specified user a cookie.",
|
description: "Gives specified user a cookie.",
|
||||||
usage: "['all'/@user]",
|
usage: "['all'/@user]",
|
||||||
|
|
|
@ -1,7 +1,24 @@
|
||||||
import {NamedCommand, RestCommand} from "onion-lasers";
|
import {NamedCommand, RestCommand} from "onion-lasers";
|
||||||
import figlet from "figlet";
|
import figlet from "figlet";
|
||||||
import {Util} from "discord.js";
|
import {Util} from "discord.js";
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
|
|
||||||
|
export const header = new SlashCommandBuilder()
|
||||||
|
.setDescription("Generates a figlet of your input.")
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option.setName("text").setDescription("Text used to create the figlet.").setRequired(true)
|
||||||
|
);
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
const {options} = interaction;
|
||||||
|
return interaction.reply(
|
||||||
|
`\`\`\`\n${Util.cleanCodeBlockContent(
|
||||||
|
figlet.textSync(options.getString("text", true), {
|
||||||
|
horizontalLayout: "full"
|
||||||
|
})
|
||||||
|
)}\n\`\`\``
|
||||||
|
);
|
||||||
|
}
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Generates a figlet of your input.",
|
description: "Generates a figlet of your input.",
|
||||||
run: "You have to provide input for me to create a figlet!",
|
run: "You have to provide input for me to create a figlet!",
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
import {NamedCommand} from "onion-lasers";
|
import {NamedCommand} from "onion-lasers";
|
||||||
|
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
|
|
||||||
|
export const header = new SlashCommandBuilder().setDescription("Insult TravBot >:D");
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
interaction.reply(
|
||||||
|
`<@${interaction.user.id}> What the fuck did you just fucking say about me, you little bitch? I'll have you know I graduated top of my class in the Navy Seals, and I've been involved in numerous secret raids on Al-Quaeda, and I have over 300 confirmed kills. I am trained in gorilla warfare and I'm the top sniper in the entire US armed forces. You are nothing to me but just another target. I will wipe you the fuck out with precision the likes of which has never been seen before on this Earth, mark my fucking words. You think you can get away with saying that shit to me over the Internet? Think again, fucker. As we speak I am contacting my secret network of spies across the USA and your IP is being traced right now so you better prepare for the storm, maggot. The storm that wipes out the pathetic little thing you call your life. You're fucking dead, kid. I can be anywhere, anytime, and I can kill you in over seven hundred ways, and that's just with my bare hands. Not only am I extensively trained in unarmed combat, but I have access to the entire arsenal of the United States Marine Corps and I will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit. If only you could have known what unholy retribution your little "clever" comment was about to bring down upon you, maybe you would have held your fucking tongue. But you couldn't, you didn't, and now you're paying the price, you goddamn idiot. I will shit fury all over you and you will drown in it. You're fucking dead, kiddo.`
|
||||||
|
);
|
||||||
|
}
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Insult TravBot! >:D",
|
description: "Insult TravBot! >:D",
|
||||||
async run({send, channel, author}) {
|
async run({send, channel, author}) {
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
import {NamedCommand, CHANNEL_TYPE} from "onion-lasers";
|
import {NamedCommand, CHANNEL_TYPE} from "onion-lasers";
|
||||||
|
|
||||||
|
export const header = new SlashCommandBuilder().setDescription("Chooses someone to love.");
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
const member = interaction.guild!.members.cache.random();
|
||||||
|
if (!member) return interaction.reply("For some reason, an error occurred fetching a member.");
|
||||||
|
return interaction.reply(`I love ${member.nickname ?? member.user.username}!`);
|
||||||
|
}
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Chooses someone to love.",
|
description: "Chooses someone to love.",
|
||||||
channelType: CHANNEL_TYPE.GUILD,
|
channelType: CHANNEL_TYPE.GUILD,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {Command, NamedCommand, confirm, poll} from "onion-lasers";
|
import {Command, NamedCommand, confirm, poll} from "onion-lasers";
|
||||||
import {pluralise} from "../../../lib";
|
import {pluralise, parseDuration} from "../../../lib";
|
||||||
import {Storage} from "../../../structures";
|
import {Storage} from "../../../structures";
|
||||||
import {isAuthorized, getMoneyEmbed} from "./eco-utils";
|
import {isAuthorized, getMoneyEmbed} from "./eco-utils";
|
||||||
import {User} from "discord.js";
|
import {User} from "discord.js";
|
||||||
|
@ -167,30 +167,3 @@ export const BetCommand = new NamedCommand({
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a duration string into milliseconds
|
|
||||||
* Examples:
|
|
||||||
* - 3d -> 3 days -> 259200000ms
|
|
||||||
* - 2h -> 2 hours -> 7200000ms
|
|
||||||
* - 7m -> 7 minutes -> 420000ms
|
|
||||||
* - 3s -> 3 seconds -> 3000ms
|
|
||||||
*/
|
|
||||||
function parseDuration(duration: string): number {
|
|
||||||
// extract last char as unit
|
|
||||||
const unit = duration[duration.length - 1].toLowerCase();
|
|
||||||
// get the rest as value
|
|
||||||
let value: number = +duration.substring(0, duration.length - 1);
|
|
||||||
|
|
||||||
if (!["d", "h", "m", "s"].includes(unit) || isNaN(value)) return 0;
|
|
||||||
|
|
||||||
if (unit === "d") value *= 86400000;
|
|
||||||
// 1000ms * 60s * 60m * 24h
|
|
||||||
else if (unit === "h") value *= 3600000;
|
|
||||||
// 1000ms * 60s * 60m
|
|
||||||
else if (unit === "m") value *= 60000;
|
|
||||||
// 1000ms * 60s
|
|
||||||
else if (unit === "s") value *= 1000; // 1000ms
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
import {NamedCommand} from "onion-lasers";
|
import {NamedCommand} from "onion-lasers";
|
||||||
import {random} from "../../lib";
|
import {random} from "../../lib";
|
||||||
|
|
||||||
|
@ -58,7 +60,10 @@ const responses = [
|
||||||
"cat",
|
"cat",
|
||||||
"large man"
|
"large man"
|
||||||
];
|
];
|
||||||
|
export const header = new SlashCommandBuilder().setDescription("Sends random ok message.");
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
interaction.reply(`ok ${random(responses)}`);
|
||||||
|
}
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Sends random ok message.",
|
description: "Sends random ok message.",
|
||||||
async run({send}) {
|
async run({send}) {
|
||||||
|
|
|
@ -1,6 +1,25 @@
|
||||||
import {NamedCommand, RestCommand} from "onion-lasers";
|
import {NamedCommand, RestCommand} from "onion-lasers";
|
||||||
import {random} from "../../lib";
|
import {random} from "../../lib";
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
|
|
||||||
|
export const header = new SlashCommandBuilder()
|
||||||
|
.setDescription("OwO-ifies the input.")
|
||||||
|
.addStringOption((option) => option.setName("text").setDescription("Text to owoify").setRequired(true));
|
||||||
|
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
const {options} = interaction;
|
||||||
|
const faces = ["owo", "UwU", ">w<", "^w^"];
|
||||||
|
const owoified = options
|
||||||
|
.getString("text", true)
|
||||||
|
.replace(/[rl]/g, "w")
|
||||||
|
.replace(/[RL]/g, "W")
|
||||||
|
.replace(/ove/g, "uv")
|
||||||
|
.replace(/n/g, "ny")
|
||||||
|
.replace(/N/g, "NY")
|
||||||
|
.replace(/\!/g, ` ${random(faces)} `);
|
||||||
|
interaction.reply(owoified);
|
||||||
|
}
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "OwO-ifies the input.",
|
description: "OwO-ifies the input.",
|
||||||
run: "You need to specify some text to owoify.",
|
run: "You need to specify some text to owoify.",
|
||||||
|
|
|
@ -1,6 +1,23 @@
|
||||||
import {MessageAttachment, User} from "discord.js";
|
import {MessageAttachment, User} from "discord.js";
|
||||||
import {NamedCommand, Command, RestCommand, getUserByNickname} from "onion-lasers";
|
import {NamedCommand, Command, RestCommand, getUserByNickname} from "onion-lasers";
|
||||||
import petPetGif from "pet-pet-gif";
|
import petPetGif from "pet-pet-gif";
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
|
|
||||||
|
//Ravioli ravioli...
|
||||||
|
//number from 1 to 9
|
||||||
|
export const header = new SlashCommandBuilder()
|
||||||
|
.setDescription("Generates a pat GIF of the avatar of the mentioned user.")
|
||||||
|
.addUserOption((option) => option.setName("user").setDescription("User you want a pat gif of.").setRequired(true));
|
||||||
|
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
await interaction.reply("Generating pat gif...");
|
||||||
|
const {options} = interaction;
|
||||||
|
const pfp = options.getUser("user", true).displayAvatarURL({format: "png"});
|
||||||
|
const gif = await petPetGif(pfp);
|
||||||
|
const file = new MessageAttachment(gif, "pat.gif");
|
||||||
|
await interaction.editReply({content: "Here you go!", files: [file]});
|
||||||
|
}
|
||||||
|
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Generates a pat GIF of the provided attachment image OR the avatar of the mentioned user.",
|
description: "Generates a pat GIF of the provided attachment image OR the avatar of the mentioned user.",
|
||||||
|
|
|
@ -1,6 +1,23 @@
|
||||||
import {MessageEmbed, Message, User} from "discord.js";
|
import {MessageEmbed, Message, User, MessageActionRow, MessageButton} from "discord.js";
|
||||||
import {NamedCommand, RestCommand, poll, CHANNEL_TYPE, SendFunction, Command} from "onion-lasers";
|
import {NamedCommand, RestCommand, poll, CHANNEL_TYPE, SendFunction, Command} from "onion-lasers";
|
||||||
import {pluralise} from "../../lib";
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
|
import {pluralise, parseDuration} from "../../lib";
|
||||||
|
|
||||||
|
export const header = new SlashCommandBuilder()
|
||||||
|
.setDescription("Create a poll.")
|
||||||
|
.addStringOption((option) => option.setName("question").setDescription("Question for the poll").setRequired(true))
|
||||||
|
.addIntegerOption((option) =>
|
||||||
|
option.setName("duration").setDescription("Duration of the poll in seconds.").setRequired(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
const {options} = interaction;
|
||||||
|
const question = options.getString("question", true);
|
||||||
|
var duration = options.getInteger("duration", false);
|
||||||
|
duration = parseDuration(duration + "s"); //override the duration variable with miliseconds one
|
||||||
|
execSlashPoll(interaction, question, duration || 60000);
|
||||||
|
}
|
||||||
|
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Create a poll.",
|
description: "Create a poll.",
|
||||||
|
@ -27,6 +44,63 @@ export default new NamedCommand({
|
||||||
const AGREE = "✅";
|
const AGREE = "✅";
|
||||||
const DISAGREE = "⛔";
|
const DISAGREE = "⛔";
|
||||||
|
|
||||||
|
async function execSlashPoll(interaction: CommandInteraction, question: string, duration = 60000) {
|
||||||
|
const responseButtons = new MessageActionRow().addComponents(
|
||||||
|
new MessageButton().setCustomId("agree").setLabel(AGREE).setStyle("SUCCESS"),
|
||||||
|
new MessageButton().setCustomId("disagree").setLabel(DISAGREE).setStyle("DANGER")
|
||||||
|
);
|
||||||
|
|
||||||
|
const icon =
|
||||||
|
interaction.user.avatarURL({
|
||||||
|
dynamic: true,
|
||||||
|
size: 2048
|
||||||
|
}) || interaction.user.defaultAvatarURL;
|
||||||
|
const embed = new MessageEmbed()
|
||||||
|
.setAuthor(`Poll created by ${interaction.user.username}`, icon)
|
||||||
|
.setColor(0xffffff)
|
||||||
|
.setFooter("Click the buttons to vote.")
|
||||||
|
.setDescription(question)
|
||||||
|
.addField(`${AGREE} -`, `${pluralise(0, "", "people have voted")}\n`)
|
||||||
|
.addField(`${DISAGREE} -`, `${pluralise(0, "", "people have voted")}\n`);
|
||||||
|
const msg = await interaction.reply({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [responseButtons]
|
||||||
|
});
|
||||||
|
var idsArray: string[] = [];
|
||||||
|
const collector = interaction.channel?.createMessageComponentCollector({time: duration});
|
||||||
|
collector?.on("collect", async (i) => {
|
||||||
|
if (i.customId === "agree") {
|
||||||
|
if (idsArray.includes(i.user.id)) {
|
||||||
|
i.reply({content: "You have already voted!", ephemeral: true});
|
||||||
|
} else {
|
||||||
|
idsArray.push(i.user.id);
|
||||||
|
var agree = +1;
|
||||||
|
embed.fields[0].value = `${pluralise(agree, "", "people who agree", "person who agrees")}\n`;
|
||||||
|
interaction.editReply({embeds: [embed]});
|
||||||
|
i.reply({content: "You picked ✅!", ephemeral: true});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i.customId === "disagree") {
|
||||||
|
if (idsArray.includes(i.user.id)) {
|
||||||
|
i.reply({content: "You have already voted!", ephemeral: true});
|
||||||
|
} else {
|
||||||
|
idsArray.push(i.user.id);
|
||||||
|
var disagree = +1;
|
||||||
|
embed.fields[1].value = `${pluralise(disagree, "", "people who disagree", "person who disagrees")}\n`;
|
||||||
|
interaction.editReply({embeds: [embed]});
|
||||||
|
i.reply({content: "You picked ⛔!", ephemeral: true});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//This solution looks messy but works really well and stops from stuff like vote fraud happening.
|
||||||
|
//I'm not sure if it's the best solution but if you have a better idea then please let me know.
|
||||||
|
|
||||||
|
collector?.on("end", async (collected) => {
|
||||||
|
embed.setTitle(`The results of ${interaction.user.username}'s poll:`);
|
||||||
|
interaction.editReply({embeds: [embed]});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function execPoll(send: SendFunction, message: Message, user: User, question: string, duration = 60000) {
|
async function execPoll(send: SendFunction, message: Message, user: User, question: string, duration = 60000) {
|
||||||
const icon =
|
const icon =
|
||||||
user.avatarURL({
|
user.avatarURL({
|
||||||
|
|
|
@ -1,6 +1,34 @@
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
import {Command, NamedCommand} from "onion-lasers";
|
import {Command, NamedCommand} from "onion-lasers";
|
||||||
import {Random} from "../../lib";
|
import {Random} from "../../lib";
|
||||||
|
//Ravioli ravioli...
|
||||||
|
//number from 1 to 9
|
||||||
|
export const header = new SlashCommandBuilder()
|
||||||
|
.setDescription("Ravioli ravioli...")
|
||||||
|
.addIntegerOption((option) => option.setName("number").setDescription("Number from 1 to 9").setRequired(false));
|
||||||
|
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
const {options} = interaction;
|
||||||
|
try {
|
||||||
|
//get the number from the options if it fails fallback to the randomizer
|
||||||
|
var response = options.getInteger("number", true);
|
||||||
|
} catch (e) {
|
||||||
|
var response = Random.int(1, 10);
|
||||||
|
}
|
||||||
|
console.log(response);
|
||||||
|
|
||||||
|
interaction.reply({
|
||||||
|
embeds: [
|
||||||
|
{
|
||||||
|
title: "Ravioli ravioli...",
|
||||||
|
image: {
|
||||||
|
url: `https://raw.githubusercontent.com/keanuplayz/TravBot/master/assets/ravi${response}.png`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Ravioli ravioli...",
|
description: "Ravioli ravioli...",
|
||||||
usage: "[number from 1 to 9]",
|
usage: "[number from 1 to 9]",
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
import {NamedCommand, RestCommand} from "onion-lasers";
|
import {NamedCommand, RestCommand} from "onion-lasers";
|
||||||
|
|
||||||
const letters: {[letter: string]: string[]} = {
|
const letters: {[letter: string]: string[]} = {
|
||||||
a: "aáàảãạâấầẩẫậăắằẳẵặ".split(""),
|
a: "aáàảãạâấầẩẫậăắằẳẵặ".split(""),
|
||||||
e: "eéèẻẽẹêếềểễệ".split(""),
|
e: "eéèẻẽẹêếềểễệ".split(""),
|
||||||
|
@ -29,8 +30,22 @@ function transform(str: string) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
let phrase = "I have no currently set phrase!";
|
export const header = new SlashCommandBuilder()
|
||||||
|
.setDescription("Transforms your text into vietnamese.")
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option.setName("text").setDescription("The text you want to transform").setRequired(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
const {options} = interaction;
|
||||||
|
const response = options.getString("text", true);
|
||||||
|
|
||||||
|
interaction.reply(transform(response));
|
||||||
|
// You might notice the remove message code is missing here. It's because reactions collectors are
|
||||||
|
//not a thing in interactions. The best alternative would be buttons
|
||||||
|
}
|
||||||
|
|
||||||
|
let phrase = "I have no currently set phrase!";
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Transforms your text into vietnamese.",
|
description: "Transforms your text into vietnamese.",
|
||||||
usage: "([text])",
|
usage: "([text])",
|
||||||
|
|
|
@ -1,7 +1,38 @@
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
import {NamedCommand, RestCommand} from "onion-lasers";
|
import {NamedCommand, RestCommand} from "onion-lasers";
|
||||||
import {MessageEmbed} from "discord.js";
|
import {MessageEmbed, CommandInteraction} from "discord.js";
|
||||||
import urban from "relevant-urban";
|
import urban from "relevant-urban";
|
||||||
|
|
||||||
|
export const header = new SlashCommandBuilder()
|
||||||
|
.setDescription("Gives you a definition of the inputted word.")
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option.setName("word").setDescription("The word you're looking for").setRequired(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
const {options} = interaction;
|
||||||
|
await interaction.reply("Working on it....");
|
||||||
|
const response = options.getString("word", true);
|
||||||
|
// [Bug Fix]: Use encodeURIComponent() when emojis are used: "TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters"
|
||||||
|
urban(encodeURIComponent(response))
|
||||||
|
.then(async (res) => {
|
||||||
|
const embed = new MessageEmbed()
|
||||||
|
.setColor(0x1d2439)
|
||||||
|
.setTitle(res.word)
|
||||||
|
.setURL(res.urbanURL)
|
||||||
|
.setDescription(`**Definition:**\n*${res.definition}*\n\n**Example:**\n*${res.example}*`)
|
||||||
|
// [Bug Fix] When an embed field is empty (if the author field is missing, like the top entry for "british"): "RangeError [EMBED_FIELD_VALUE]: MessageEmbed field values may not be empty."
|
||||||
|
.addField("Author", res.author || "N/A", true)
|
||||||
|
.addField("Rating", `**\`Upvotes: ${res.thumbsUp} | Downvotes: ${res.thumbsDown}\`**`);
|
||||||
|
if (res.tags && res.tags.length > 0 && res.tags.join(" ").length < 1024)
|
||||||
|
embed.addField("Tags", res.tags.join(", "), true);
|
||||||
|
interaction.editReply("Here you go!");
|
||||||
|
await interaction.editReply({embeds: [embed]});
|
||||||
|
})
|
||||||
|
.catch(async () => {
|
||||||
|
await interaction.editReply("Sorry, that word was not found.");
|
||||||
|
});
|
||||||
|
}
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Gives you a definition of the inputted word.",
|
description: "Gives you a definition of the inputted word.",
|
||||||
run: "Please input a word.",
|
run: "Please input a word.",
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {CommandInteraction} from "discord.js";
|
||||||
import {NamedCommand, RestCommand} from "onion-lasers";
|
import {NamedCommand, RestCommand} from "onion-lasers";
|
||||||
|
|
||||||
const vaporwave = (() => {
|
const vaporwave = (() => {
|
||||||
const map = new Map<string, string>();
|
const map = new Map<string, string>();
|
||||||
const vaporwave =
|
const vaporwave =
|
||||||
|
@ -21,6 +22,17 @@ function getVaporwaveText(text: string): string {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const header = new SlashCommandBuilder()
|
||||||
|
.setDescription("Transforms your text into vaporwave.")
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option.setName("text").setDescription("The text you want to vaporwave.").setRequired(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
const {options} = interaction;
|
||||||
|
const response = options.getString("text", true);
|
||||||
|
await interaction.reply(getVaporwaveText(response));
|
||||||
|
}
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Transforms your text into vaporwave.",
|
description: "Transforms your text into vaporwave.",
|
||||||
run: "You need to enter some text!",
|
run: "You need to enter some text!",
|
||||||
|
|
|
@ -1,7 +1,47 @@
|
||||||
import {NamedCommand, RestCommand} from "onion-lasers";
|
import {NamedCommand, RestCommand} from "onion-lasers";
|
||||||
import {MessageEmbed} from "discord.js";
|
import {SlashCommandBuilder} from "@discordjs/builders";
|
||||||
|
import {MessageEmbed, CommandInteraction} from "discord.js";
|
||||||
import {find} from "weather-js";
|
import {find} from "weather-js";
|
||||||
|
|
||||||
|
export const header = new SlashCommandBuilder()
|
||||||
|
.setDescription("Shows weather info of specified location.")
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option.setName("location").setDescription("The location you're looking for").setRequired(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
export async function handler(interaction: CommandInteraction) {
|
||||||
|
const {options} = interaction;
|
||||||
|
await interaction.reply("Working on it....");
|
||||||
|
const response = options.getString("location", true);
|
||||||
|
|
||||||
|
find(
|
||||||
|
{
|
||||||
|
search: response,
|
||||||
|
degreeType: "C"
|
||||||
|
},
|
||||||
|
async function (error, result) {
|
||||||
|
if (error) return await interaction.editReply(error.toString());
|
||||||
|
if (result.length === 0) return await interaction.editReply("No city found by that name.");
|
||||||
|
var current = result[0].current;
|
||||||
|
var location = result[0].location;
|
||||||
|
const embed = new MessageEmbed()
|
||||||
|
.setDescription(`**${current.skytext}**`)
|
||||||
|
.setAuthor(`Weather for ${current.observationpoint}`)
|
||||||
|
.setThumbnail(current.imageUrl)
|
||||||
|
.setColor(0x00ae86)
|
||||||
|
.addField("Timezone", `UTC${location.timezone}`, true)
|
||||||
|
.addField("Degree Type", "C", true)
|
||||||
|
.addField("Temperature", `${current.temperature} Degrees`, true)
|
||||||
|
.addField("Feels like", `${current.feelslike} Degrees`, true)
|
||||||
|
.addField("Winds", current.winddisplay, true)
|
||||||
|
.addField("Humidity", `${current.humidity}%`, true);
|
||||||
|
interaction.editReply("Here you go!"); // remove the working on message
|
||||||
|
return await interaction.editReply({
|
||||||
|
embeds: [embed]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Shows weather info of specified location.",
|
description: "Shows weather info of specified location.",
|
||||||
run: "You need to provide a city.",
|
run: "You need to provide a city.",
|
||||||
|
|
26
src/lib.ts
26
src/lib.ts
|
@ -269,3 +269,29 @@ export function split<T>(array: T[], lengthOfEachSection: number): T[][] {
|
||||||
export function requireAllCasesHandledFor(variable: never): never {
|
export function requireAllCasesHandledFor(variable: never): never {
|
||||||
throw new Error(`This function should never be called but got the value: ${variable}`);
|
throw new Error(`This function should never be called but got the value: ${variable}`);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Parses a duration string into milliseconds
|
||||||
|
* Examples:
|
||||||
|
* - 3d -> 3 days -> 259200000ms
|
||||||
|
* - 2h -> 2 hours -> 7200000ms
|
||||||
|
* - 7m -> 7 minutes -> 420000ms
|
||||||
|
* - 3s -> 3 seconds -> 3000ms
|
||||||
|
*/
|
||||||
|
export function parseDuration(duration: string): number {
|
||||||
|
// extract last char as unit
|
||||||
|
const unit = duration[duration.length - 1].toLowerCase();
|
||||||
|
// get the rest as value
|
||||||
|
let value: number = +duration.substring(0, duration.length - 1);
|
||||||
|
|
||||||
|
if (!["d", "h", "m", "s"].includes(unit) || isNaN(value)) return 0;
|
||||||
|
|
||||||
|
if (unit === "d") value *= 86400000;
|
||||||
|
// 1000ms * 60s * 60m * 24h
|
||||||
|
else if (unit === "h") value *= 3600000;
|
||||||
|
// 1000ms * 60s * 60m
|
||||||
|
else if (unit === "m") value *= 60000;
|
||||||
|
// 1000ms * 60s
|
||||||
|
else if (unit === "s") value *= 1000; // 1000ms
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue