diff --git a/CustomModules/NodBot.js b/CustomModules/NodBot.js new file mode 100644 index 0000000..ecb8c53 --- /dev/null +++ b/CustomModules/NodBot.js @@ -0,0 +1,15 @@ +module.exports = { + GifData: class { + constructor() { + this.gifName = ""; + this.gifUrl = ""; + } + setInfo(name, url) { + if ((!name) || (!url)) throw `Expected a name and url, receieved {name: ${name}, url: ${url}}`; + this.name = name; + this.url = url; + + return this; + } + } +} \ No newline at end of file diff --git a/dot-commands/gif.js b/dot-commands/gif.js index c7dedd7..b9f746a 100644 --- a/dot-commands/gif.js +++ b/dot-commands/gif.js @@ -13,7 +13,7 @@ module.exports = { async execute(message, commandData) { // if (message.deletable) message.delete(); const client = message.client; - if (!client.gifs.has(commandData.args)) { + 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'); const q = await axios.get( 'https://tenor.googleapis.com/v2/search?' + @@ -43,11 +43,11 @@ module.exports = { // }).catch(err => console.error(err)); } else { // message.reply(commandData.args + ' requested by ' + message.author.username + '\n' + client.gifs.get(commandData.args).embed_url); - commandData.embed_url = client.gifs.get(commandData.args).embed_url; + const gifData = client.gifs.get(commandData.args.toLowerCase()); // 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(gifData.url); } } } \ No newline at end of file diff --git a/functions.js b/functions.js index 358d552..b02a9bc 100644 --- a/functions.js +++ b/functions.js @@ -45,6 +45,7 @@ const dotCommandFiles = fs.readdirSync('./dot-commands/').filter(file => file.en // MySQL database connection const mysql = require('mysql'); +const { GifData } = require('./CustomModules/NodBot'); const db = new mysql.createPool({ connectionLimit: 10, host: dbHost, @@ -102,12 +103,13 @@ const functions = { if (!client.gifs) client.gifs = new Discord.Collection(); client.gifs.clear(); for (const row of rows) { - const gif = { - id: row.id, - name: row.name, - embed_url: row.embed_url - }; - client.gifs.set(gif.name, gif); + // const gif = { + // id: row.id, + // name: row.name, + // embed_url: row.embed_url + // }; + const gifData = new GifData().setInfo(row.name, row.embed_url); + client.gifs.set(gifData.name, gifData); } if (isDev) console.log('GIFs Collection Built'); }, @@ -215,7 +217,7 @@ const functions = { // Construct the Help Embed const helpEmbed = new Discord.MessageEmbed() .setColor('BLUE') - .setAuthor('Help Page') + .setAuthor({name: 'Help Page'}) .setDescription(strings.help.description) .setThumbnail(strings.urls.avatar); @@ -268,14 +270,14 @@ const functions = { }, gif(commandData) { return { embeds: [new Discord.MessageEmbed() - .setAuthor(`${commandData.args}.${commandData.command}`) + .setAuthor({name: `${commandData.args}.${commandData.command}`}) .setImage(commandData.embed_url) .setTimestamp() .setFooter(commandData.author)]}; }, pasta(commandData) { return { embeds: [ new Discord.MessageEmbed() - .setAuthor(`${commandData.args}.${commandData.command}`) + .setAuthor({name: `${commandData.args}.${commandData.command}`}) .setDescription(commandData.content) .setThumbnail(commandData.iconUrl) .setTimestamp() @@ -284,7 +286,7 @@ const functions = { pastas(commandData) { const pastasArray = []; const pastasEmbed = new Discord.MessageEmbed() - .setAuthor(commandData.command) + .setAuthor({name: commandData.command}) .setTimestamp() .setFooter(commandData.author); @@ -297,32 +299,25 @@ const functions = { return { embeds: [pastasEmbed], ephemeral: true }; }, - gifs(commandData) { - const gifsArray = []; + gifs(commandData, gifList) { const gifsEmbed = new Discord.MessageEmbed() - .setAuthor(commandData.command) + .setAuthor({name: commandData.command}) .setTimestamp() - .setFooter(commandData.author); - - for (const row of commandData.gifs) { - gifsArray.push(`#${row.id} - ${row.name}.gif`); - } - - const gifsString = gifsArray.join('\n'); - gifsEmbed.setDescription(gifsString); + .setFooter(commandData.author) + .setDescription(gifList.join('\n')); return { embeds: [gifsEmbed] }; }, text(commandData) { return { embeds: [new Discord.MessageEmbed() - .setAuthor(commandData.command) + .setAuthor({name: commandData.command}) .setDescription(commandData.content) .setTimestamp() .setFooter(commandData.author)]}; }, requests(commandData) { const requestsEmbed = new Discord.MessageEmbed() - .setAuthor(commandData.command) + .setAuthor({name: commandData.command}) .setTimestamp() .setFooter(commandData.author); @@ -418,7 +413,7 @@ const functions = { }); }, pasta(pastaData, client) { - const query = `INSERT INTO pastas (name, content) VALUES (${db.escape(pastaData.name)},${db.escape(pastaData.content)})`; + const query = `INSERT INTO pastas (name, content) VALUES (${db.escape(pastaData.name)},${db.escape(pastaData.content)}) ON DUPLICATE KEY UPDATE content=${db.escape(pastaData.content)}`; db.query(query, (err, rows, fields) => { if (err) throw err; functions.download.pastas(client); @@ -431,9 +426,9 @@ const functions = { functions.download.joints(client); }); }, - gif(gifData, client) { - const query = `INSERT INTO gifs (name, embed_url) VALUES (${db.escape(gifData.name)}, ${db.escape(gifData.embed_url)})`; - db.query(query, (err, rows, fields) => { + async gif(gifData, client) { + const query = `INSERT INTO gifs (name, embed_url) VALUES (${db.escape(gifData.name)}, ${db.escape(gifData.url)}) ON DUPLICATE KEY UPDATE embed_url=${db.escape(gifData.embed_url)}`; + await db.query(query, (err, rows, fields) => { if (err) throw err; functions.download.gifs(client); }); @@ -487,7 +482,7 @@ const functions = { const description = db.escape(( interaction.options.getString('description') || 'Unknown' )); const flavor = db.escape(( interaction.options.getString('flavor') || 'Unknown' )); const rating = db.escape(( interaction.options.getString('rating') || '3' )); - const strainQuery = `INSERT INTO strains (strain, type, effects, description, flavor, rating) VALUES (${strain}, ${type}, ${effects}, ${description}, ${flavor}, ${rating})`; + const strainQuery = `INSERT INTO strains (strain, type, effects, description, flavor, rating) VALUES (${strain}, ${type}, ${effects}, ${description}, ${flavor}, ${rating}) ON DUPLICATE KEY UPDATE strain=${db.escape(strain)}, type=${db.escape(type)}, effects=${db.escape(effects)}, description=${db.escape(description)}, flavor=${db.escape(flavor)}, rating=${db.escape(rating)}`; console.log(strainQuery); return new Promise((resolve, reject) => { db.query(strainQuery, (err, rows, fields) => { @@ -519,9 +514,9 @@ const functions = { functions.collections.pastas(rows, client); }); }, - gifs(client) { + async gifs(client) { const query = 'SELECT * FROM gifs ORDER BY id ASC'; - db.query(query, (err, rows, fields) => { + await db.query(query, (err, rows, fields) => { if (err) throw err; functions.collections.gifs(rows, client); }); @@ -608,6 +603,16 @@ const functions = { }); } }, + search: { + gifs(query, client) { + const gifSearcher = new FuzzySearch(client.gifs.map(element => element.name)); + return gifSearcher.search(query).slice(0,25); + }, + pastas(query, client) { + const pastaSearcher = new FuzzySearch(client.pastas.map(element => element.name)); + return pastaSearcher.search(query).slice(0,25); + } + }, // Parent-Level functions (miscellaneuous) closeRequest(requestId, interaction) { if (interaction.user.id == ownerId) { diff --git a/main.js b/main.js index 0ee3d91..ed084ef 100644 --- a/main.js +++ b/main.js @@ -27,6 +27,7 @@ const { MessageActionRow, MessageButton } = require('discord.js'); const fn = require('./functions.js'); const config = require('./config.json'); const strings = require('./strings.json'); +const { GifData } = require('./CustomModules/NodBot.js'); const isDev = process.env.isDev; client.once('ready', () => { @@ -108,10 +109,11 @@ client.on('interactionCreate', async interaction => { interaction.update(strings.temp.gifs[newIndex].embed_url); break; case 'confirmGif': - const gifData = { - name: strings.temp.gifName, - embed_url: strings.temp.gifs[strings.temp.gifIndex].embed_url, - }; + // 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); @@ -176,14 +178,39 @@ client.on('interactionCreate', async interaction => { // Handle autocomplete requests if (interaction.isAutocomplete()) { - if (interaction.commandName == '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 })) - ) - } else { - return; + 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; } } }); diff --git a/slash-commands/edit.js b/slash-commands/edit.js new file mode 100644 index 0000000..2c9394c --- /dev/null +++ b/slash-commands/edit.js @@ -0,0 +1,101 @@ +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 } = 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.') + .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) + ) + ) + .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 + 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`); + } +}; \ No newline at end of file diff --git a/slash-commands/gifs.js b/slash-commands/gifs.js index 934ff86..0409968 100644 --- a/slash-commands/gifs.js +++ b/slash-commands/gifs.js @@ -11,23 +11,26 @@ module.exports = { interaction.reply('For some reason I don\'t have access to the collection of gifs. Sorry about that!'); return; } - const gifsMap = interaction.client.gifs.map(e => { - return { - id: e.id, - name: e.name, - }; + // const gifsMap = interaction.client.gifs.map(e => {e.name, e.url}); + // const commandData = { + // gifs: [], + // command: 'gifs', + // author: interaction.user.tag, + // }; + // for (const row of gifsMap) { + // commandData.gifs.push({ + // id: row.id, + // name: row.name, + // }); + // } + let gifList = []; + interaction.client.gifs.forEach(element => { + gifList.push(`[${element.name}](${element.url})`); }); const commandData = { - gifs: [], - command: 'gifs', - author: interaction.user.tag, + command: "/gifs", + author: interaction.member.displayName }; - for (const row of gifsMap) { - commandData.gifs.push({ - id: row.id, - name: row.name, - }); - } - interaction.reply(fn.embeds.gifs(commandData)); + interaction.reply(fn.embeds.gifs(commandData, gifList)); }, }; \ No newline at end of file diff --git a/slash-commands/save.js b/slash-commands/save.js index 13f5d38..6390e8b 100644 --- a/slash-commands/save.js +++ b/slash-commands/save.js @@ -10,6 +10,7 @@ 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 { emoji } = strings; module.exports = { @@ -178,10 +179,11 @@ module.exports = { // GIF URL case "gifurl": //TODO Check on option names - const gifData = { - name: interaction.options.getString('name').toLowerCase(), - embed_url: interaction.options.getString('url'), - }; + // 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);