Compare commits

...

28 Commits
main ... pe

Author SHA1 Message Date
361fdecbb7 MVP 3.4.0-pe
All checks were successful
NodBot PE Dockerization / build (push) Successful in 59s
2024-09-26 14:48:18 -04:00
db53a01e48 Merge branch 'v3.4.0' into pe 2024-09-26 14:43:29 -04:00
450ae24930 ignore env
All checks were successful
NodBot PE Dockerization / build (push) Successful in 19s
2024-09-26 14:37:05 -04:00
6175a30974 Add PR tag # 2024-09-26 14:28:11 -04:00
8d5f75e471 Add nested commands 2024-09-26 14:25:22 -04:00
e4fbcca6c4 MVP for nested commands
All checks were successful
NodBot Production Dockerization / build (pull_request) Successful in 53s
2024-09-26 14:20:56 -04:00
2cbfc7f354 WIP DNU 2024-09-26 09:55:49 -04:00
ed315d0cb1 Versioning -- v3.4.0 2024-09-26 09:43:05 -04:00
f1459e9d91 Fix startup message
All checks were successful
NodBot PE Dockerization / build (push) Successful in 1m16s
2024-09-22 19:46:44 -04:00
57f729de24 Update to use new TenorJSv2
All checks were successful
NodBot PE Dockerization / build (push) Successful in 1m28s
2024-09-22 19:19:16 -04:00
623070690a Maybe?
All checks were successful
NodBot PE Dockerization / build (push) Successful in 17s
2024-09-22 19:05:46 -04:00
7a60fbde8b idk anymore
Some checks failed
NodBot PE Dockerization / build (push) Failing after 0s
2024-09-22 19:02:36 -04:00
5e57d6e2d9 Fix runs on
Some checks failed
NodBot PE Dockerization / build (push) Failing after 1s
2024-09-22 18:48:35 -04:00
a00fecde1f derp fix
Some checks failed
NodBot PE Dockerization / build (push) Failing after 3s
2024-09-22 18:47:59 -04:00
e0805c0241 Update CI/CD for testing 2024-09-22 18:24:51 -04:00
3be90aef30 Update node version in docker
Some checks failed
NodBot Production Dockerization / build (push) Failing after 0s
2024-09-22 12:20:13 -04:00
4d0fec19d5 Fix gif embed
Some checks are pending
NodBot Production Dockerization / build (push) Waiting to run
2024-09-22 12:18:04 -04:00
21ef9012ac Updates, fix pastas
Some checks are pending
NodBot Production Dockerization / build (push) Waiting to run
2024-09-22 12:17:09 -04:00
9d24745e46 Wrong verbiage
All checks were successful
NodBot Production Dockerization / build (push) Successful in 1m24s
2023-08-04 21:19:11 -04:00
6f7f3df001 Base-level functioning 2023-08-04 21:17:44 -04:00
050d927908 Update to use Node.js 18 LTS 2023-08-04 20:59:33 -04:00
fcbe25687f Adjust gitignore 2023-08-04 20:41:04 -04:00
26e94e71b2 Update pe from main 2023-08-04 20:31:34 -04:00
Skylar Grant
b1ffd2d22b Typo 2022-12-21 19:04:52 -05:00
Skylar Grant
06f9758bc2 Ignore self messages 2022-12-21 19:01:45 -05:00
Skylar Grant
c46d183608 CI for NodBot PE 2022-12-16 21:21:27 -05:00
Skylar Grant
ae95349b9b Can't delete message in DMs 2022-12-16 21:20:46 -05:00
Skylar Grant
d15ccf6a5b fucking shit up 2022-12-16 15:50:48 -05:00
30 changed files with 161 additions and 979 deletions

1
.gitignore vendored
View File

@ -4,7 +4,6 @@ package-lock.json
.VSCodeCounter/ .VSCodeCounter/
.env* .env*
*.env *.env
# Custom folders # Custom folders
# gifs/* # gifs/*
# pastas/* # pastas/*

View File

@ -1,3 +1,7 @@
## v3.4.x
#### v3.4.0 (#25)
* Added nested commands, enclose a command in brackets, braces, or parenthesis inside a longer message: `You really don't get it do you? [that's the joke.gif] You're so dense` would return the results for just `that's the joke.gif`
## v3.3.x ## v3.3.x
#### v3.3.3 (#20) #### v3.3.3 (#20)
* Fixed content-list slash commands `/gifs`, `/pastas`, `/joints`, `/requests` (#19) * Fixed content-list slash commands `/gifs`, `/pastas`, `/joints`, `/requests` (#19)

View File

@ -8,6 +8,7 @@ module.exports = {
this.args = message.content.slice(0,this.finalPeriod).toLowerCase(); // Grab everything leading up to the final period this.args = message.content.slice(0,this.finalPeriod).toLowerCase(); // Grab everything leading up to the final period
this.command = message.content.slice(this.finalPeriod + 1).toLowerCase(); // Grab everything after the final period this.command = message.content.slice(this.finalPeriod + 1).toLowerCase(); // Grab everything after the final period
this.author = message.author.username; this.author = message.author.username;
this.message = message;
return this; return this;
} }
@ -16,14 +17,110 @@ module.exports = {
if (this.args.startsWith('http')) return false; if (this.args.startsWith('http')) return false;
if (this.args.startsWith('www')) return false; if (this.args.startsWith('www')) return false;
const indices = {
curlyBrace: {
start: -1,
end: -1
},
bracket: {
start: -1,
end: -1
},
parenthesis: {
start: -1,
end: -1
}
}
// Check for and extract the part of the message that's
// wrapped in any type of brackets or quotes eg. ([{``''""}])
const curlyBraceStart = this.message.content.match(/[\{]/g);
const curlyBraceEnd = this.message.content.match(/[\}]/g);
if (curlyBraceStart && curlyBraceEnd) {
indices.curlyBrace.start = this.message.content.indexOf(curlyBraceStart[0]) + 1;
indices.curlyBrace.end = this.message.content.lastIndexOf(curlyBraceEnd[0]);
}
const bracketStart = this.message.content.match(/[\[]/g);
const bracketEnd = this.message.content.match(/[\]]/g);
if (bracketStart && bracketEnd) {
indices.bracket.start = this.message.content.indexOf(bracketStart[0]) + 1;
indices.bracket.end = this.message.content.lastIndexOf(bracketEnd[0]);
}
const parenthesisStart = this.message.content.match(/[\(]/g);
const parenthesisEnd = this.message.content.match(/[\)]/g);
if (parenthesisStart && parenthesisEnd) {
indices.parenthesis.start = this.message.content.indexOf(parenthesisStart[0]) + 1;
indices.parenthesis.end = this.message.content.lastIndexOf(parenthesisEnd[0]);
}
let nestedText = new String();
if (indices.curlyBrace.start >= 0 && indices.curlyBrace.end > 0) {
nestedText = this.message.content.slice(indices.curlyBrace.start, indices.curlyBrace.end);
}
if (indices.bracket.start >= 0 && indices.bracket.end > 0) {
nestedText = this.message.content.slice(indices.bracket.start, indices.bracket.end);
}
if (indices.parenthesis.start >= 0 && indices.parenthesis.end > 0) {
nestedText = this.message.content.slice(indices.parenthesis.start, indices.parenthesis.end);
}
console.log(nestedText);
if (nestedText !== "") {
this.nestedCommand = {
finalPeriod: nestedText.lastIndexOf('.'),
isCommand: nestedText.lastIndexOf('.') >= 0 ? true : false,
args: nestedText.slice(0, nestedText.lastIndexOf('.')).toLowerCase(),
command: nestedText.slice(nestedText.lastIndexOf('.') + 1).toLowerCase()
}
for (const [key, value] of dotCommands) {
if (key === this.nestedCommand.command) {
this.isValid = true;
this.args = this.nestedCommand.args;
this.command = key;
this.isCommand = this.nestedCommand.isCommand;
this.finalPeriod = this.nestedCommand.finalPeriod;
return this;
} else if (value.alias) {
if (typeof value.alias === 'string' && value.alias === this.nestedCommand.command) {
this.command = key
this.args = this.nestedCommand.args;
this.isValid = true;
this.isCommand = this.nestedCommand.isCommand;
this.finalPeriod = this.nestedCommand.finalPeriod;
return this;
} else if (typeof value.alias === 'object' && value.alias.includes(this.nestedCommand.command)) {
this.command = key
this.args = this.nestedCommand.args;
this.isValid = true;
this.isCommand = this.nestedCommand.isCommand;
this.finalPeriod = this.nestedCommand.finalPeriod;
return this;
}
}
}
}
for (const [key, value] of dotCommands) { for (const [key, value] of dotCommands) {
if (key === this.command) { if (key === this.command) {
this.isValid = true; this.isValid = true;
return this; return this;
} else if (value.alias && value.alias.includes(this.command)) { } else if (value.alias) {
if (typeof value.alias === 'string' && value.alias === this.command) {
this.command = key; this.command = key;
this.isValid = true; this.isValid = true;
return this; return this;
} else if (typeof value.alias === 'object' && value.alias.includes(this.command)) {
this.command = key;
this.isValid = true;
return this;
}
} }
} }
return this; return this;

View File

@ -1,4 +1,4 @@
FROM node:18 FROM node:20
RUN mkdir -p /usr/src/app RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app WORKDIR /usr/src/app

View File

@ -1,27 +0,0 @@
// dotenv for handling environment variables
const dotenv = require('dotenv');
dotenv.config();
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const clientId = process.env.clientId;
const { guildId } = require('../config.json');
const token = process.env.TOKEN;
const rest = new REST({ version: '9' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: '' },
);
console.log('Successfully reloaded application (/) commands.');
process.exit();
} catch (error) {
console.error(error);
}
})();

View File

@ -1,40 +0,0 @@
// dotenv for handling environment variables
const dotenv = require('dotenv');
dotenv.config();
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const { guildId } = require('./config.json');
const clientId = process.env.clientId;
const token = process.env.TOKEN;
const fs = require('fs');
const commands = [];
const commandFiles = fs.readdirSync('./slash-commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./slash-commands/${file}`);
if (command.data != undefined) {
commands.push(command.data.toJSON());
}
}
console.log(commands);
const rest = new REST({ version: '9' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
);
console.log('Successfully reloaded application (/) commands.');
process.exit();
} catch (error) {
console.error(error);
}
})();

View File

@ -1,39 +0,0 @@
// dotenv for handling environment variables
const dotenv = require('dotenv');
dotenv.config();
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const clientId = process.env.clientId;
const token = process.env.TOKEN;
const fs = require('fs');
const commands = [];
const commandFiles = fs.readdirSync('./slash-commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./slash-commands/${file}`);
if (command.data != undefined) {
commands.push(command.data.toJSON());
}
}
console.log(commands);
const rest = new REST({ version: '9' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationCommands(clientId),
{ body: commands },
);
console.log('Successfully reloaded application (/) commands.');
process.exit();
} catch (error) {
console.error(error);
}
})();

View File

@ -1,7 +1,9 @@
const fn = require('../functions'); const fn = require('../functions');
const axios = require('axios'); const axios = require('axios');
const dotenv = require('dotenv').config(); const dotenv = require('dotenv').config();
const Tenor = require('tenorjs-v2');
const tenor = new Tenor(process.env.TENOR_API_KEY);
// TODO: Tenor has changed API versions, switch from TenorJS (unmaintained) to axios for // TODO: Tenor has changed API versions, switch from TenorJS (unmaintained) to axios for
// general API usage. See: https://github.com/Jinzulen/TenorJS/issues/12 // general API usage. See: https://github.com/Jinzulen/TenorJS/issues/12
// see also: https://developers.google.com/tenor/guides/migrate-from-v1 // see also: https://developers.google.com/tenor/guides/migrate-from-v1
@ -16,32 +18,17 @@ module.exports = {
const client = message.client; const client = message.client;
if (!client.gifs.has(commandData.args.toLowerCase())) { if (!client.gifs.has(commandData.args.toLowerCase())) {
if (process.env.isDev) console.log('https://tenor.googleapis.com/v2/search?' + `&q=${commandData.args}` + `&key=${process.env.tenorAPIKey}` + '&limit=1&contentfilter=off'); if (process.env.isDev) console.log('https://tenor.googleapis.com/v2/search?' + `&q=${commandData.args}` + `&key=${process.env.tenorAPIKey}` + '&limit=1&contentfilter=off');
const q = await axios.get( tenor.search(commandData.args, "1").then(res => {
'https://tenor.googleapis.com/v2/search?' + if (res[0] == undefined) {
`&q=${commandData.args}` +
`&key=${process.env.tenorAPIKey}` +
'&limit=1' +
`&contentfilter=off`
).then(res => {
if (process.env.isDev) console.log(res.data.results);
if (res.data.results[0] == undefined) {
message.reply('Sorry I was unable to find a GIF of ' + commandData.args); message.reply('Sorry I was unable to find a GIF of ' + commandData.args);
return; return;
}; };
commandData.embed_url = res.data.results[0].url; commandData.embed_url = res[0].mediaUrl;
// message.reply(fn.embeds.gif(commandData));
// message.channel.send(`> ${commandData.author} - ${commandData.args}.gif`);
// message.channel.send(commandData.embed_url);
message.reply(commandData.embed_url); message.reply(commandData.embed_url);
}).catch(err => console.error(err)); }).catch(err => console.error(err));
// tenor.Search.Query(commandData.args, "1").then(res => {
// if (res[0] == undefined) {
// message.reply('Sorry I was unable to find a GIF of ' + commandData.args);
// return;
// };
// commandData.embed_url = res[0].media[0].gif.url;
// // message.reply(fn.embeds.gif(commandData));
// // message.channel.send(`> ${commandData.author} - ${commandData.args}.gif`);
// // message.channel.send(commandData.embed_url);
// message.reply(commandData.embed_url);
// }).catch(err => console.error(err));
} else { } else {
// message.reply(commandData.args + ' requested by ' + message.author.username + '\n' + client.gifs.get(commandData.args).embed_url); // message.reply(commandData.args + ' requested by ' + message.author.username + '\n' + client.gifs.get(commandData.args).embed_url);
const gifData = client.gifs.get(commandData.args.toLowerCase()); const gifData = client.gifs.get(commandData.args.toLowerCase());

View File

@ -12,8 +12,9 @@ module.exports = {
content: "Sorry, I couldn't find that pasta." content: "Sorry, I couldn't find that pasta."
}; };
} else { } else {
pastaData = client.pastas.get(commandData.args); commandData.content = client.pastas.get(commandData.args).content;
} }
message.reply(fn.embeds.pasta(commandData, pastaData)); const messagePayload = fn.embeds.pasta(commandData);
message.reply(messagePayload);
} }
} }

View File

@ -7,6 +7,7 @@ module.exports = {
execute(message, commandData) { execute(message, commandData) {
const request = commandData.args; const request = commandData.args;
commandData.content = `Your request has been submitted!\nRequest: ${request}`; commandData.content = `Your request has been submitted!\nRequest: ${request}`;
commandData.requestUrl = message.url;
message.reply(fn.embeds.text(commandData)); message.reply(fn.embeds.text(commandData));
commandData.content = `A new request has been submitted by ${message.author.tag}:\n${commandData.args}`; commandData.content = `A new request has been submitted by ${message.author.tag}:\n${commandData.args}`;
message.client.users.fetch(process.env.ownerID).then(user => { message.client.users.fetch(process.env.ownerID).then(user => {

View File

@ -2,12 +2,13 @@
// dotenv for handling environment variables // dotenv for handling environment variables
const dotenv = require('dotenv').config(); const dotenv = require('dotenv').config();
// Assignment of environment variables for database access // Assignment of environment variables for database access
const dbHost = process.env.dbHost; const dbHost = process.env.DB_HOST;
const dbUser = process.env.dbUser; const dbUser = process.env.DB_USER;
const dbName = process.env.dbName; const dbName = process.env.DB_NAME;
const dbPass = process.env.dbPass; const dbPass = process.env.DB_PASS;
const dbPort = process.env.dbPort; const dbPort = process.env.DB_PORT;
const isDev = process.env.isDev; const isDev = process.env.IS_DEV;
const ownerId = process.env.ownerId; const ownerId = process.env.ownerId;
// filesystem // filesystem
@ -26,7 +27,6 @@ const axios = require('axios');
// Various imports from other files // Various imports from other files
const config = require('./config.json'); const config = require('./config.json');
const strings = require('./strings.json'); const strings = require('./strings.json');
const slashCommandFiles = fs.readdirSync('./slash-commands/').filter(file => file.endsWith('.js'));
const dotCommandFiles = fs.readdirSync('./dot-commands/').filter(file => file.endsWith('.js')); const dotCommandFiles = fs.readdirSync('./dot-commands/').filter(file => file.endsWith('.js'));
const customEmbeds = require('./CustomModules/Embeds.js'); const customEmbeds = require('./CustomModules/Embeds.js');
@ -249,26 +249,16 @@ const functions = {
], ephemeral: true }; ], ephemeral: true };
}, },
gif(commandData) { gif(commandData) {
return { embeds: [new Discord.MessageEmbed() return commandData.embed_url;
.setAuthor({name: `${commandData.args}.${commandData.command}`})
.setImage(commandData.embed_url)
.setTimestamp()
.setFooter({text: commandData.author})]};
}, },
pasta(commandData, pastaData) { pasta(commandData) {
return { embeds: [ new Discord.MessageEmbed() return commandData.content;
.setAuthor({name: `${commandData.args}.${commandData.command}`})
.setDescription(pastaData.content)
.setThumbnail("https://assets.vfsh.dev/shednod.png")
.setTimestamp()
.setFooter({text: commandData.author})]};
}, },
pastas(commandData, indexedPastas) { pastas(commandData, indexedPastas) {
const pastasEmbed = new Discord.MessageEmbed() const pastasEmbed = new Discord.MessageEmbed()
.setAuthor({name: commandData.command}) .setAuthor({name: commandData.command})
.setTimestamp() .setTimestamp()
.setFooter({text: `Page: ${indexedPastas.pagesString}`}) .setFooter({text: commandData.author});
.setDescription(indexedPastas.pastasString);
const pastasPageAR = customEmbeds.pastasPageAR(indexedPastas.state); const pastasPageAR = customEmbeds.pastasPageAR(indexedPastas.state);
return { embeds: [pastasEmbed], components: [pastasPageAR], ephemeral: true }; return { embeds: [pastasEmbed], components: [pastasPageAR], ephemeral: true };
@ -277,8 +267,7 @@ const functions = {
const gifsEmbed = new Discord.MessageEmbed() const gifsEmbed = new Discord.MessageEmbed()
.setAuthor({name: commandData.command}) .setAuthor({name: commandData.command})
.setTimestamp() .setTimestamp()
.setFooter({text: `Page: ${indexedGifs.pagesString}`}) .setFooter({text: commandData.author});
.setDescription(indexedGifs.gifsString);
const gifsPageAR = customEmbeds.gifsPageAR(indexedGifs.state); const gifsPageAR = customEmbeds.gifsPageAR(indexedGifs.state);
return { embeds: [gifsEmbed], components: [gifsPageAR], ephemeral: true }; return { embeds: [gifsEmbed], components: [gifsPageAR], ephemeral: true };
@ -304,15 +293,16 @@ const functions = {
const requestsEmbed = new Discord.MessageEmbed() const requestsEmbed = new Discord.MessageEmbed()
.setAuthor({name: commandData.command}) .setAuthor({name: commandData.command})
.setTimestamp() .setTimestamp()
.setFooter({text: `Page: ${indexedRequests.pagesString}`}) .setFooter({text: commandData.author});
.setDescription(indexedRequests.requestsString);
const requestsPageAR = customEmbeds.requestsPageAR(indexedRequests.state); const requestsPageAR = customEmbeds.requestsPageAR(indexedRequests.state);
return { embeds: [requestsEmbed], components: [requestsPageAR], ephemeral: true }; return { embeds: [requestsEmbed], components: [requestsPageAR], ephemeral: true };
}, },
strain(strainInfo, interaction) { strain(commandData, message) {
const strainEmbed = new Discord.MessageEmbed() const strainEmbed = new Discord.MessageEmbed()
.setTimestamp(); .setTimestamp()
.setFooter({text: commandData.author});
const { strainInfo } = commandData;
strainEmbed.addFields([ strainEmbed.addFields([
{ {
name: 'Strain Name', name: 'Strain Name',
@ -336,7 +326,7 @@ const functions = {
}, },
{ {
name: 'Rating', name: 'Rating',
value: `⭐️${strainInfo.rating}`, value: `${strainInfo.rating}s`,
inline: true, inline: true,
}, },
{ {
@ -346,7 +336,7 @@ const functions = {
}, },
]); ]);
interaction.reply({ embeds: [ strainEmbed ]}); message.reply({ embeds: [ strainEmbed ]});
}, },
dalle(prompt, imageUrl, size) { dalle(prompt, imageUrl, size) {
const dalleEmbed = new Discord.MessageEmbed() const dalleEmbed = new Discord.MessageEmbed()
@ -439,7 +429,7 @@ const functions = {
}, },
upload: { upload: {
request(commandData, client) { request(commandData, client) {
const query = `INSERT INTO requests (author, request, status) VALUES (${db.escape(commandData.author)},${db.escape(commandData.args)},'Active')`; const query = `INSERT INTO requests (author, request, status, url) VALUES (${db.escape(commandData.author)},${db.escape(commandData.args)},'Active',${db.escape(commandData.url)})`;
db.query(query, (err, rows, fields) => { db.query(query, (err, rows, fields) => {
if (err) throw err; if (err) throw err;
functions.download.requests(client); functions.download.requests(client);
@ -562,11 +552,12 @@ const functions = {
functions.collections.joints(rows, client); functions.collections.joints(rows, client);
}); });
}, },
async strain(strainName, interaction) { async strain(commandData, message) {
const { strainName } = commandData;
const query = `SELECT id, strain, type, effects, description, flavor, rating FROM strains WHERE strain = ${db.escape(strainName)}`; const query = `SELECT id, strain, type, effects, description, flavor, rating FROM strains WHERE strain = ${db.escape(strainName)}`;
await db.query(query, (err, rows, fields) => { await db.query(query, (err, rows, fields) => {
if (rows != undefined) { if (rows != undefined) {
const strainInfo = { commandData.strainInfo = {
id: `${rows[0].id}`, id: `${rows[0].id}`,
strain: `${rows[0].strain}`, strain: `${rows[0].strain}`,
type: `${rows[0].type}`, type: `${rows[0].type}`,
@ -575,7 +566,7 @@ const functions = {
flavor: `${rows[0].flavor}`, flavor: `${rows[0].flavor}`,
rating: `${rows[0].rating}`, rating: `${rows[0].rating}`,
}; };
functions.embeds.strain(strainInfo, interaction); functions.embeds.strain(commandData, message);
} }
}); });
}, },
@ -598,7 +589,12 @@ const functions = {
strain: { strain: {
lookup(strainName, client) { lookup(strainName, client) {
const strainSearcher = new FuzzySearch(client.strains.map(e => e.name)); const strainSearcher = new FuzzySearch(client.strains.map(e => e.name));
return strainSearcher.search(strainName).slice(0,25); const name = strainSearcher.search(strainName)[0];
if (name != undefined) {
return name;
} else {
return false;
}
}, },
submit(strainName) { submit(strainName) {
const query = `` const query = ``

195
main.js
View File

@ -4,18 +4,11 @@
const dotenv = require('dotenv'); const dotenv = require('dotenv');
dotenv.config(); dotenv.config();
const token = process.env.TOKEN; const token = process.env.TOKEN;
const statusChannelId = process.env.statusChannelId; const statusChannelId = process.env.STATUS_CHANNEL_ID;
// Discord.JS // Discord.JS
const { Client, Intents } = require('discord.js'); const { Client } = require('discord.js-selfbot-v13');
const client = new Client({ const client = new Client({
intents: [
'GUILDS',
'GUILD_MESSAGES',
'GUILD_MESSAGE_REACTIONS',
'DIRECT_MESSAGES',
'DIRECT_MESSAGE_REACTIONS',
],
partials: [ partials: [
'CHANNEL', 'CHANNEL',
'MESSAGE', 'MESSAGE',
@ -28,13 +21,9 @@ const fn = require('./functions.js');
const config = require('./config.json'); const config = require('./config.json');
const strings = require('./strings.json'); const strings = require('./strings.json');
const { GifData, CommandData } = require('./CustomModules/NodBot.js'); const { GifData, CommandData } = require('./CustomModules/NodBot.js');
const ButtonHandlers = require('./CustomModules/ButtonHandlers.js'); const isDev = process.env.IS_DEV;
const InteractionStorage = require('./CustomModules/InteractionStorage.js');
const isDev = process.env.isDev;
client.once('ready', async () => { client.once('ready', async () => {
fn.collections.interactionStorage(client);
fn.collections.slashCommands(client);
fn.collections.dotCommands(client); fn.collections.dotCommands(client);
fn.collections.setvalidCommands(client); fn.collections.setvalidCommands(client);
fn.collections.roaches(client); fn.collections.roaches(client);
@ -49,189 +38,15 @@ client.once('ready', async () => {
await fn.avWx.datis.getAllICAOs(); await fn.avWx.datis.getAllICAOs();
// console.log(JSON.stringify(icaoArray)); // console.log(JSON.stringify(icaoArray));
client.channels.fetch(statusChannelId).then(channel => { client.channels.fetch(statusChannelId).then(channel => {
channel.send(`${new Date().toISOString()} -- <@${process.env.ownerId}>\nStartup Sequence Complete`); channel.send(`${new Date().toISOString()} -- <@${process.env.OWNER_ID}>\nStartup Sequence Complete`);
}); });
}); });
// slash-commands
client.on('interactionCreate', async interaction => {
if (interaction.isCommand()) {
if (isDev) {
console.log('Interaction ID: ' + interaction.id);
}
const { commandName } = interaction;
if (!client.iStorage.has(interaction.id)) {
new InteractionStorage(interaction.id, interaction);
}
if (client.slashCommands.has(commandName)) {
client.slashCommands.get(commandName).execute(interaction);
} else {
interaction.reply('Sorry, I don\'t have access to that command.');
console.error('Slash command attempted to run but not found: ' + commandName);
}
}
if (interaction.isButton()) {
if (isDev) console.log('Origin Interaction ID: ' + interaction.message.interaction.id);
if (isDev) console.log('Button ID: ' + interaction.component.customId);
// Get some meta info from strings
const index = strings.temp.gifIndex;
const limit = strings.temp.gifLimit;
let newIndex;
const buttonId = interaction.component.customId;
switch (buttonId) {
case 'prevGif':
newIndex = index - 1;
strings.temp.gifIndex = newIndex;
// If we're leaving the last GIF, enable the Next GIF button
if (index == limit) {
// Re-Send Previous GIF button
const prevButton = new MessageButton().setCustomId('prevGif').setLabel('Previous GIF').setStyle('SECONDARY');
// Re-Send Confirm GIF Button
const confirmButton = new MessageButton().setCustomId('confirmGif').setLabel('Confirm').setStyle('PRIMARY');
// Enable Next GIF Button
const nextButton = new MessageButton().setCustomId('nextGif').setLabel('Next GIF').setStyle('SECONDARY');
// Re-Send Cancel Button
const cancelButton = new MessageButton().setCustomId('cancelGif').setLabel('Cancel').setStyle('DANGER');
// Put all the above into an ActionRow to be sent as a component of the reply
const row = new MessageActionRow().addComponents(prevButton, confirmButton, nextButton, cancelButton);
interaction.update({ content: strings.temp.gifs[newIndex].embed_url, components: [row] });
break;
}
// If we're going into the first GIF, disable the Previous GIF button
if (newIndex == 0) {
// Disable Previous GIF button
const prevButton = new MessageButton().setCustomId('prevGif').setLabel('Previous GIF').setStyle('SECONDARY').setDisabled();
// Re-Send Confirm GIF Button
const confirmButton = new MessageButton().setCustomId('confirmGif').setLabel('Confirm').setStyle('PRIMARY');
// Re-Send Next GIF Button
const nextButton = new MessageButton().setCustomId('nextGif').setLabel('Next GIF').setStyle('SECONDARY');
// Re-Send Cancel Button
const cancelButton = new MessageButton().setCustomId('cancelGif').setLabel('Canceled').setStyle('DANGER');
// Put all the above into an ActionRow to be sent as a component of the reply
const row = new MessageActionRow().addComponents(prevButton, confirmButton, nextButton, cancelButton);
interaction.update({ content: strings.temp.gifs[newIndex].embed_url, components: [row] });
break;
}
interaction.update(strings.temp.gifs[newIndex].embed_url);
break;
case 'confirmGif':
// const gifData = {
// name: strings.temp.gifName,
// url: strings.temp.gifs[strings.temp.gifIndex].embed_url,
// };
const gifData = new GifData().setInfo(strings.temp.gifName, strings.temp.gifs[strings.temp.gifIndex].embed_url);
fn.upload.gif(gifData, client);
interaction.update({ content: `I've saved the GIF as ${gifData.name}.gif`, components: [] });
fn.download.gifs(interaction.client);
break;
case 'nextGif':
newIndex = index + 1;
strings.temp.gifIndex = newIndex;
// If we're leaving the first GIF, enable the Previous GIF button
if (index == 0) {
// Enable Previous GIF button
const prevButton = new MessageButton().setCustomId('prevGif').setLabel('Previous GIF').setStyle('SECONDARY').setDisabled(false);
// Re-Send Confirm GIF Button
const confirmButton = new MessageButton().setCustomId('confirmGif').setLabel('Confirm').setStyle('PRIMARY');
// Re-Send Next GIF Button
const nextButton = new MessageButton().setCustomId('nextGif').setLabel('Next GIF').setStyle('SECONDARY');
// Re-Send Cancel Button
const cancelButton = new MessageButton().setCustomId('cancelGif').setLabel('Cancel').setStyle('DANGER');
// Put all the above into an ActionRow to be sent as a component of the reply
const row = new MessageActionRow().addComponents(prevButton, confirmButton, nextButton, cancelButton);
interaction.update({ content: strings.temp.gifs[newIndex].embed_url, components: [row] });
break;
}
// If we're going into the last GIF, disable the Next GIF button
if (newIndex == strings.temp.gifLimit) {
// Re-Send Previous GIF button
const prevButton = new MessageButton().setCustomId('prevGif').setLabel('Previous GIF').setStyle('SECONDARY');
// Re-Send Confirm GIF Button
const confirmButton = new MessageButton().setCustomId('confirmGif').setLabel('Confirm').setStyle('PRIMARY');
// Disable Next GIF Button
const nextButton = new MessageButton().setCustomId('nextGif').setLabel('Next GIF').setStyle('SECONDARY').setDisabled();
// Re-Send Cancel Button
const cancelButton = new MessageButton().setCustomId('cancelGif').setLabel('Canceled').setStyle('DANGER');
// Put all the above into an ActionRow to be sent as a component of the reply
const row = new MessageActionRow().addComponents(prevButton, confirmButton, nextButton, cancelButton);
interaction.update({ content: strings.temp.gifs[newIndex].embed_url, components: [row] });
break;
}
interaction.update(strings.temp.gifs[newIndex].embed_url);
break;
case 'cancelGif':
// Previous GIF button
const prevButton = new MessageButton().setCustomId('prevGif').setLabel('Previous GIF').setStyle('SECONDARY').setDisabled();
// Confirm GIF Button
const confirmButton = new MessageButton().setCustomId('confirmGif').setLabel('Confirm').setStyle('PRIMARY').setDisabled();
// Next GIF Button
const nextButton = new MessageButton().setCustomId('nextGif').setLabel('Next GIF').setStyle('SECONDARY').setDisabled();
// Cancel Button
const cancelButton = new MessageButton().setCustomId('cancelGif').setLabel('Canceled').setStyle('DANGER');
// Put all the above into an ActionRow to be sent as a component of the reply
const row = new MessageActionRow().addComponents(prevButton, confirmButton, nextButton, cancelButton);
interaction.component.setDisabled(true);
interaction.update({ content: 'Canceled.', components: [row] });
break;
default:
ButtonHandlers.baseEvent(interaction);
break;
}
}
// Handle autocomplete requests
if (interaction.isAutocomplete()) {
switch (interaction.commandName) {
case 'strain':
const searchString = interaction.options.getFocused();
const choices = fn.weed.strain.lookup(searchString, interaction.client);
await interaction.respond(
choices.map(choice => ({ name: choice, value: choice }))
);
break;
case "edit":
//TODO
switch (interaction.options.getSubcommand()) {
case 'gif':
const gifQuery = interaction.options.getFocused();
const gifChoices = fn.search.gifs(gifQuery, interaction.client);
await interaction.respond(
gifChoices.map(choice => ({ name: choice, value: choice }))
);
break;
case 'pasta':
const pastaQuery = interaction.options.getFocused();
const pastaChoices = fn.search.pastas(pastaQuery, interaction.client);
await interaction.respond(
pastaChoices.map(choice => ({ name: choice, value: choice }))
);
break;
default:
break;
}
break;
default:
break;
}
}
});
// dot-commands // dot-commands
client.on('messageCreate', message => { client.on('messageCreate', message => {
// Some basic checking to prevent running unnecessary code // Some basic checking to prevent running unnecessary code
if (message.author.bot) return; if (message.author.bot) return;
if (message.author.id == client.user.id) return;
// Automatic Responses, will respond if any message contains the keyword(s), excluding self-messages // Automatic Responses, will respond if any message contains the keyword(s), excluding self-messages
const lowerContent = message.content.toLowerCase(); const lowerContent = message.content.toLowerCase();

View File

@ -1,22 +1,23 @@
{ {
"name": "nodbot", "name": "nodbot",
"version": "3.3.3", "version": "3.4.0",
"description": "Nods and Nod Accessories, now with ChatGPT!", "description": "Nods and Nod Accessories",
"main": "main.js", "main": "main.js",
"dependencies": { "dependencies": {
"@discordjs/builders": "^0.16.0", "@discordjs/builders": "^1.9.0",
"@discordjs/rest": "^0.1.0-canary.0", "@discordjs/rest": "^0.1.0-canary.0",
"axios": "^0.21.4", "axios": "^0.21.4",
"discord-api-types": "^0.22.0", "discord-api-types": "^0.22.0",
"discord.js": "^13.15.1", "discord.js": "^13.15.1",
"discord.js-selfbot-v13": "^3.4.0",
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"fuzzy-search": "^3.2.1", "fuzzy-search": "^3.2.1",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"openai": "^4.12.0", "tenorjs": "1.0.10",
"tenorjs": "^1.0.10" "tenorjs-v2": "^1.0.2"
}, },
"engines": { "engines": {
"node": "18.x" "node": "^20.x"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^7.32.0" "eslint": "^7.32.0"

View File

@ -1,16 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('closereq')
.setDescription('Close a request by ID, retrieved from /requests')
.addStringOption(option =>
option.setName('requestid')
.setDescription('The ID of the request you\'d like to close.')
.setRequired(true)),
async execute(interaction) {
const requestId = interaction.options.getString('requestid');
fn.closeRequest(requestId, interaction);
},
};

View File

@ -1,110 +0,0 @@
const tenor = require('tenorjs').client({
'Key': process.env.tenorAPIKey, // https://tenor.com/developer/keyregistration
'Filter': 'off', // "off", "low", "medium", "high", not case sensitive
'Locale': 'en_US',
'MediaFilter': 'minimal',
'DateFormat': 'D/MM/YYYY - H:mm:ss A',
});
const { SlashCommandBuilder } = require('@discordjs/builders');
const { MessageActionRow, MessageButton } = require('discord.js');
const { GifData, PastaData } = require('../CustomModules/NodBot');
const fn = require('../functions.js');
const strings = require('../strings.json');
const { emoji } = strings;
module.exports = {
data: new SlashCommandBuilder()
.setName('edit')
.setDescription('Edit content in Nodbot\'s database.')
// GIF
.addSubcommand(subcommand =>
subcommand
.setName('gif')
.setDescription('Edit a GIF URL')
.addStringOption(option =>
option
.setName('name')
.setDescription('The name of the GIF to edit')
.setRequired(true)
.setAutocomplete(true)
)
.addStringOption(option =>
option
.setName('url')
.setDescription('The new URL')
.setRequired(true)
)
)
// Pasta
.addSubcommand(subcommand =>
subcommand
.setName('pasta')
.setDescription('Edit a copypasta\'s content')
.addStringOption(option =>
option
.setName('name')
.setDescription('The name of the copypasta')
.setRequired(true)
.setAutocomplete(true)
)
.addStringOption(option =>
option
.setName('content')
.setDescription('The new content of the copypasta')
.setRequired(true)
)
),
async execute(interaction) {
await interaction.deferReply({ ephemeral: true });
try {
// Code Here...
const subcommand = interaction.options.getSubcommand();
switch (subcommand) {
// GIF
case "gif":
//TODO
await this.editGif(interaction, interaction.options.getString('name'), interaction.options.getString('url'));
break;
// Joint
case "joint":
//TODO
break;
// MD
case "md":
//TODO
break;
// Pasta
case "pasta":
//TODO
await this.editPasta(interaction, interaction.options.getString('name'), interaction.options.getString('content'));
break;
// Strain
case "strain":
//TODO
break;
break;
// Default
default:
break;
}
} catch (err) {
const errorId = fn.generateErrorId();
console.error(`${errorId}: err`);
await interaction.editReply(`Sorry, an error has occured. Error ID: ${errorId}`);
}
},
async editGif(interaction, name, url) {
const gifData = new GifData().setInfo(name, url);
await fn.upload.gif(gifData, interaction.client);
await fn.download.gifs(interaction.client);
await interaction.editReply(`I've updated ${gifData.name}.gif`);
},
async editPasta(interaction, name, content) {
const pastaData = new PastaData().setInfo(name, content);
await fn.upload.pasta(pastaData, interaction.client);
await fn.download.gifs(interaction.client);
await interaction.editReply(`I've updated ${name}.pasta`);
}
};

View File

@ -1,30 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const { config } = require('dotenv');
const fn = require('../functions.js');
const indexer = require('../CustomModules/Indexer.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('gifs')
.setDescription('Get a list of currently saved GIFs.'),
execute(interaction) {
if (!interaction.client.gifs) {
interaction.reply('For some reason I don\'t have access to the collection of gifs. Sorry about that!');
return;
}
let iStorage = interaction.client.iStorage.get(interaction.id);
let indexedGifs = indexer(interaction.client.gifs, 0);
indexedGifs.gifsString = new String();
iStorage.page = 0;
for (const gif of indexedGifs.thisPage) {
indexedGifs.gifsString += `[${gif.name}.gif](${gif.url})\n`;
}
const commandData = {
command: "/gifs",
author: interaction.member.displayName
};
interaction.reply(fn.embeds.gifs(commandData, indexedGifs));
}
};

View File

@ -1,11 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('help')
.setDescription('Send the help page.'),
async execute(interaction) {
await interaction.reply(fn.embeds.help(interaction));
}
};

View File

@ -1,11 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('jenny')
.setDescription('Jenny?'),
async execute(interaction) {
interaction.reply('867-5309');
},
};

View File

@ -1,17 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
const { emoji } = require('../strings.json');
module.exports = {
data: new SlashCommandBuilder()
.setName('joint')
.setDescription('Replies with a random cannabis-related quote.'),
async execute(interaction) {
let joints = [];
for (const entry of interaction.client.joints.map(joint => joint.content)) {
joints.push(entry);
}
const randIndex = Math.floor(Math.random() * joints.length);
interaction.reply(`${joints[randIndex]} ${emoji.joint}`);
},
};

View File

@ -1,29 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
const indexer = require('../CustomModules/Indexer.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('joints')
.setDescription('Send a list of all the /joint phrases.'),
async execute(interaction) {
if (!interaction.client.joints) {
interaction.reply('For some reason I don\'t have access to the collection of joints. Sorry about that!');
return;
}
let iStorage = interaction.client.iStorage.get(interaction.id);
let indexedJoints = indexer(interaction.client.joints, 0);
indexedJoints.jointsString = new String();
iStorage.page = 0;
for (const joint of indexedJoints.thisPage) {
indexedJoints.jointsString += `${joint.content}\n`;
}
const commandData = {
command: "/joints",
author: interaction.member.displayName
};
interaction.reply(fn.embeds.joints(commandData, indexedJoints));
},
};

View File

@ -1,11 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('lenny')
.setDescription('( ͡° ͜ʖ ͡°)'),
async execute(interaction) {
interaction.reply('( ͡° ͜ʖ ͡°)');
},
};

View File

@ -1,30 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const { config } = require('dotenv');
const fn = require('../functions.js');
const indexer = require('../CustomModules/Indexer.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('pastas')
.setDescription('Get a list of currently saved copypastas.'),
async execute(interaction) {
if (!interaction.client.pastas) {
interaction.reply({ content: 'For some reason I don\'t have access to the collection of copypastas. Sorry about that!', ephemeral: true });
return;
}
let iStorage = interaction.client.iStorage.get(interaction.id);
let indexedPastas = indexer(interaction.client.pastas, 0);
indexedPastas.pastasString = new String();
iStorage.page = 0;
for (const pasta of indexedPastas.thisPage) {
indexedPastas.pastasString += `${pasta.name}.pasta\n`;
}
const commandData = {
command: "/pastas",
author: interaction.member.displayName
};
interaction.reply(fn.embeds.pastas(commandData, indexedPastas));
},
};

View File

@ -1,11 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('ping')
.setDescription('Check that the bot is alive and responding.'),
async execute(interaction) {
await interaction.reply({ content: 'Pong!', ephemeral: true });
},
};

View File

@ -1,20 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('reload')
.setDescription('Reload all saved content, useful if saving something fails.'),
async execute(interaction) {
const { client } = interaction;
fn.collections.slashCommands(client);
fn.collections.dotCommands(client);
fn.collections.setvalidCommands(client);
fn.download.gifs(client);
fn.download.pastas(client);
fn.download.joints(client);
fn.download.requests(client);
fn.download.strains(client);
interaction.reply({ content: 'Reloaded!', ephemeral: true });
},
};

View File

@ -1,31 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const { config } = require('dotenv');
const fn = require('../functions.js');
const indexer = require('../CustomModules/Indexer.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('requests')
.setDescription('Get a list of Active requests from the database'),
async execute(interaction) {
if (!interaction.client.requests) {
interaction.reply('For some reason I don\'t have access to the collection of requests. Sorry about that!');
return;
}
let iStorage = interaction.client.iStorage.get(interaction.id);
let indexedRequests = indexer(interaction.client.requests, 0);
indexedRequests.requestsString = new String();
iStorage.page = 0;
for (const request of indexedRequests.thisPage) {
indexedRequests.requestsString += `[${request.id}]: ${request.request} (submitted by ${request.author})\n`;
}
const commandData = {
command: "/requests",
author: interaction.member.displayName
};
interaction.reply(fn.embeds.requests(commandData, indexedRequests));
},
};

View File

@ -1,232 +0,0 @@
const tenor = require('tenorjs').client({
'Key': process.env.tenorAPIKey, // https://tenor.com/developer/keyregistration
'Filter': 'off', // "off", "low", "medium", "high", not case sensitive
'Locale': 'en_US',
'MediaFilter': 'minimal',
'DateFormat': 'D/MM/YYYY - H:mm:ss A',
});
const { SlashCommandBuilder } = require('@discordjs/builders');
const { MessageActionRow, MessageButton } = require('discord.js');
const fn = require('../functions.js');
const strings = require('../strings.json');
const { GifData } = require('../CustomModules/NodBot.js');
const customEmbeds = require('../CustomModules/Embeds.js');
const { emoji } = strings;
module.exports = {
data: new SlashCommandBuilder()
.setName('save')
.setDescription('Save content to Nodbot\'s database.')
// GIF Search
.addSubcommand(subcommand =>
subcommand
.setName('gifsearch')
.setDescription('Search Tenor for a GIF.')
.addStringOption(option =>
option
.setName('query')
.setDescription('Search Query')
.setRequired(true))
.addStringOption(option =>
option
.setName('name')
.setDescription('What to save the gif as')
.setRequired(true))
)
// GIF URL
.addSubcommand(subcommand =>
subcommand
.setName('gifurl')
.setDescription('Specify a URL to save.')
.addStringOption(option =>
option
.setName('url')
.setDescription('URL Link to the GIF')
.setRequired(true))
.addStringOption(option =>
option
.setName('name')
.setDescription('What to save the gif as')
.setRequired(true))
)
// Joint
.addSubcommand(subcommand =>
subcommand
.setName('joint')
.setDescription('Roll a joint and stash it in the database.')
.addStringOption(option =>
option
.setName('joint-content')
.setDescription('Phrase to save')
.setRequired(true)
)
)
// MD
.addSubcommand(subcommand =>
subcommand
.setName('md')
.setDescription('Add medical advice to the database.')
.addStringOption(option =>
option
.setName('advice-content')
.setDescription('Advice to save')
.setRequired(true)
)
)
// Pasta
.addSubcommand(subcommand =>
subcommand
.setName('pasta')
.setDescription('Save a copypasta to the database.')
.addStringOption(option =>
option
.setName('pasta-name')
.setDescription('Title of the copypasta')
.setRequired(true)
)
.addStringOption(option =>
option
.setName('pasta-content')
.setDescription('Content of the copypasta')
.setRequired(true)
)
)
// Strain
.addSubcommand(subcommand =>
subcommand
.setName('strain')
.setDescription('Store a new Strain in the database!')
.addStringOption(option =>
option
.setName('name')
.setDescription('Name of the Strain')
.setRequired(true))
.addStringOption(option =>
option
.setName('type')
.setDescription('Indica/Sativa/Hybrid')
.setRequired(true)
.addChoices(
{ name: "Indica", value: "Indica" },
{ name: "Hybrid", value: "Hybrid" },
{ name: "Sativa", value: "Sativa" }
)
)
.addStringOption(option =>
option
.setName('effects')
.setDescription('The effects given by the strain')
.setRequired(false))
.addStringOption(option =>
option
.setName('flavor')
.setDescription('Flavor notes')
.setRequired(false))
.addStringOption(option =>
option
.setName('rating')
.setDescription('Number of stars')
.setRequired(false))
.addStringOption(option =>
option
.setName('description')
.setDescription('Description of the strain')
.setRequired(false))
),
async execute(interaction) {
await interaction.deferReply({ ephemeral: true });
try {
// Code Here...
const subcommand = interaction.options.getSubcommand();
switch (subcommand) {
// GIF Search
case "gifsearch":
// TODO Check on option names
const actionRow = customEmbeds.gifSearchAR();
// Get the query
const query = interaction.options.getString('query');
strings.temp.gifName = interaction.options.getString('name').toLowerCase();
// Search Tenor for the GIF
tenor.Search.Query(query, '10').then(res => {
strings.temp.gifs = [];
strings.temp.gifIndex = 0;
strings.temp.gifLimit = res.length - 1;
strings.temp.gifUserId = interaction.user.id;
if (res[0] == undefined) {
interaction.editReply('Sorry I was unable to find a GIF of ' + query);
return;
}
for (const row of res) {
strings.temp.gifs.push({
embed_url: row.media_formats.gif.url,
});
}
interaction.editReply({ content: strings.temp.gifs[0].embed_url, components: [actionRow], ephemeral: true });
});
break;
// GIF URL
case "gifurl":
//TODO Check on option names
// const gifData = {
// name: interaction.options.getString('name').toLowerCase(),
// url: interaction.options.getString('url'),
// };
const gifData = new GifData().setInfo(interaction.options.getString('name').toLowerCase(), interaction.options.getString('url'));
fn.upload.gif(gifData, interaction.client);
interaction.editReply({ content: `I've saved the GIF as ${gifData.name}.gif`, ephemeral: true });
fn.download.gifs(interaction.client);
break;
// Joint
case "joint":
//TODO
fn.upload.joint(interaction.options.getString('joint-content'), interaction.client);
interaction.editReply({ content: `The joint has been rolled${emoji.joint}`, ephemeral: true });
break;
// MD
case "md":
//TODO
fn.upload.medicalAdvice(interaction.options.getString('advice-content'), interaction.client);
interaction.editReply({ content: `The advice has been saved!`, ephemeral: true });
break;
// Pasta
case "pasta":
//TODO
const pastaData = {
name: interaction.options.getString('pasta-name').toLowerCase(),
content: interaction.options.getString('pasta-content'),
};
await fn.upload.pasta(pastaData, interaction.client);
interaction.editReply({content: `The copypasta has been saved as ${pastaData.name}.pasta`, ephemeral: true });
break;
// Strain
case "strain":
//TODO
fn.upload.strain(interaction).then(res => {
interaction.editReply({
content: `The strain information has been saved. (${interaction.options.getString('name')})`,
ephemeral: true
});
}).catch(err => {
console.log(`E: ${err}`);
interaction.editReply({
content: 'There was a problem saving the strain.',
ephemeral: true
});
});
break;
// Default
default:
break;
}
} catch (err) {
const errorId = fn.generateErrorId();
console.error(`${errorId}: err`);
await interaction.editReply(`Sorry, an error has occured. Error ID: ${errorId}`);
}
}
};

View File

@ -1,15 +0,0 @@
// UNDER DEVELOPMENT
// This *should* create the tables required to use Nodbot,
// assuming you have a database set up with proper permissions.
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('setup')
.setDescription('Create the tables required to use Nodbot'),
async execute(interaction) {
await interaction.reply({ content: fn.upload.setup(), ephemeral: true });
},
};

View File

@ -1,17 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('strain')
.setDescription('Look up information about a cannabis strain.')
.addStringOption(option =>
option
.setName('name')
.setDescription('Strain Name')
.setRequired(true)
.setAutocomplete(true)),
async execute(interaction) {
fn.download.strain(interaction.options.getString('name'), interaction);
},
};

View File

@ -1,11 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('')
.setDescription(''),
async execute(interaction) {
await
},
};

View File

@ -1,11 +0,0 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const fn = require('../functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('truth')
.setDescription('The truth about the MHallihan Flight Simulator'),
async execute(interaction) {
await interaction.reply('https://www.twitch.tv/hochmania/clip/EsteemedSlickDootStinkyCheese-hncmP8aIP8_WQb_a?filter=clips&range=all&sort=time');
},
};