MVP for meme generation
All checks were successful
NodBot PE Dockerization / build (push) Successful in 1m23s

This commit is contained in:
Skylar Grant 2025-02-09 19:43:06 -05:00
parent 720366b04b
commit 7df608e0e6
4 changed files with 256 additions and 0 deletions

View File

@ -16,6 +16,7 @@ const zlib = require('zlib');
// Discord.js
const Discord = require('discord.js');
const { MessageActionRow, Modal, TextInputComponent } = require('discord.js');
// Fuzzy text matching for db lookups
const FuzzySearch = require('fuzzy-search');
@ -23,6 +24,16 @@ const FuzzySearch = require('fuzzy-search');
// Axios for APIs
const axios = require('axios');
// Imgflip API
let imgflip;
(async () => {
const Imgflip = (await import('imgflip')).default;
imgflip = new Imgflip({
username: process.env.imgflipUser,
password: process.env.imgflipPass,
});
})();
// Various imports from other files
const config = require('./config.json');
const strings = require('./strings.json');
@ -616,6 +627,143 @@ const functions = {
return pastaSearcher.search(query).slice(0,25);
}
},
memes: {
generate(templateId, panelData) {
return new Promise((resolve, reject) => {
imgflip.meme(templateId, {
captions: panelData
}).then((res) => {
resolve(res);
}).catch((err) => {
reject(err);
});
});
},
oneFieldModal(templateId) {
// Create the modal
const modal = new Modal()
.setCustomId('oneFieldMemeModal')
.setTitle('Meme Generator');
// Create the text input
const textInput = new TextInputComponent()
.setCustomId('memeTextField')
.setLabel('Text Field:')
.setStyle('SHORT');
// Create and pre-fill a template ID field
const templateIdField = new TextInputComponent()
.setCustomId('memeTemplateId')
.setLabel('Template ID: (advanced)')
.setStyle('SHORT')
.setValue(templateId);
// Add the components to the modal
const textRow = new MessageActionRow().addComponents(textInput);
const templateIdRow = new MessageActionRow().addComponents(templateIdField);
modal.addComponents(textRow, templateIdRow);
return modal;
},
twoFieldModal(templateId) {
// Create the modal
const modal = new Modal()
.setCustomId('twoFieldMemeModal')
.setTitle('Meme Generator');
// Create the first text input
const fieldOneTextInput = new TextInputComponent()
.setCustomId('memeTextFieldOne')
.setLabel('Text Field 1:')
.setStyle('SHORT');
// Create the second text input
const fieldTwoTextInput = new TextInputComponent()
.setCustomId('memeTextFieldTwo')
.setLabel('Text Field 2:')
.setStyle('SHORT');
// Create and pre-fill a template ID field
const templateIdField = new TextInputComponent()
.setCustomId('memeTemplateId')
.setLabel('Template ID: (advanced)')
.setStyle('SHORT')
.setValue(templateId);
// Add the components to the modal
const fieldOneRow = new MessageActionRow().addComponents(fieldOneTextInput);
const fieldTwoRow = new MessageActionRow().addComponents(fieldTwoTextInput);
const templateIdRow = new MessageActionRow().addComponents(templateIdField);
modal.addComponents(fieldOneRow, fieldTwoRow, templateIdRow);
return modal;
},
threeFieldModal(templateId) {
// Create the modal
const modal = new Modal()
.setCustomId('threeFieldMemeModal')
.setTitle('Meme Generator');
// Create the first text input
const fieldOneTextInput = new TextInputComponent()
.setCustomId('memeTextFieldOne')
.setLabel('Text Field 1:')
.setStyle('SHORT');
// Create the second text input
const fieldTwoTextInput = new TextInputComponent()
.setCustomId('memeTextFieldTwo')
.setLabel('Text Field 2:')
.setStyle('SHORT');
// Create the third text input
const fieldThreeTextInput = new TextInputComponent()
.setCustomId('memeTextFieldThree')
.setLabel('Text Field 3:')
.setStyle('SHORT');
// Create and pre-fill a template ID field
const templateIdField = new TextInputComponent()
.setCustomId('memeTemplateId')
.setLabel('Template ID: (advanced)')
.setStyle('SHORT')
.setValue(templateId);
// Add the components to the modal
const fieldOneRow = new MessageActionRow().addComponents(fieldOneTextInput);
const fieldTwoRow = new MessageActionRow().addComponents(fieldTwoTextInput);
const fieldThreeRow = new MessageActionRow().addComponents(fieldThreeTextInput);
const templateIdRow = new MessageActionRow().addComponents(templateIdField);
modal.addComponents(fieldOneRow, fieldTwoRow, fieldThreeRow, templateIdRow);
return modal;
},
fourFieldModal(templateId) {
// Create the modal
const modal = new Modal()
.setCustomId('fourFieldMemeModal')
.setTitle('Meme Generator');
// Create the first text input
const fieldOneTextInput = new TextInputComponent()
.setCustomId('memeTextFieldOne')
.setLabel('Text Field 1:')
.setStyle('SHORT');
// Create the second text input
const fieldTwoTextInput = new TextInputComponent()
.setCustomId('memeTextFieldTwo')
.setLabel('Text Field 2:')
.setStyle('SHORT');
// Create the third text input
const fieldThreeTextInput = new TextInputComponent()
.setCustomId('memeTextFieldThree')
.setLabel('Text Field 3:')
.setStyle('SHORT');
// Create the fourth text input
const fieldFourTextInput = new TextInputComponent()
.setCustomId('memeTextFieldFour')
.setLabel('Text Field 4:')
.setStyle('SHORT');
// Create and pre-fill a template ID field
const templateIdField = new TextInputComponent()
.setCustomId('memeTemplateId')
.setLabel('Template ID: (advanced)')
.setStyle('SHORT')
.setValue(templateId);
// Add the components to the modal
const fieldOneRow = new MessageActionRow().addComponents(fieldOneTextInput);
const fieldTwoRow = new MessageActionRow().addComponents(fieldTwoTextInput);
const fieldThreeRow = new MessageActionRow().addComponents(fieldThreeTextInput);
const fieldFourRow = new MessageActionRow().addComponents(fieldFourTextInput);
const templateIdRow = new MessageActionRow().addComponents(templateIdField);
modal.addComponents(fieldOneRow, fieldTwoRow, fieldThreeRow, fieldFourRow, templateIdRow);
return modal;
},
},
// Parent-Level functions (miscellaneuous)
closeRequest(requestId, interaction) {
if (interaction.user.id == ownerId) {

45
main.js
View File

@ -57,6 +57,7 @@ client.once('ready', async () => {
// slash-commands
client.on('interactionCreate', async interaction => {
if (isDev) console.log('Interaction Type: ' + interaction.type);
if (interaction.isCommand()) {
if (isDev) {
console.log('Interaction ID: ' + interaction.id);
@ -118,6 +119,50 @@ client.on('interactionCreate', async interaction => {
break;
}
}
if (interaction.isModalSubmit()) {
if (isDev) console.log('Modal Submit ID: ' + interaction.id);
const template = interaction.fields.getTextInputValue('memeTemplateId');
let memeTextFieldOne, memeTextFieldTwo, memeTextFieldThree, memeTextFieldFour, memeUrl;
switch (interaction.customId) {
case 'oneFieldMemeModal':
memeTextFieldOne = interaction.fields.getTextInputValue('memeTextFieldOne');
console.log(`Text: ${memeTextFieldOne}`);
memeUrl = await fn.memes.generate(template, [memeTextFieldOne]);
console.log(memeUrl);
await interaction.reply({ content: 'Here is your meme: ' + memeUrl });
break;
case 'twoFieldMemeModal':
memeTextFieldOne = interaction.fields.getTextInputValue('memeTextFieldOne');
memeTextFieldTwo = interaction.fields.getTextInputValue('memeTextFieldTwo');
console.log(`Text: ${memeTextFieldOne}, ${memeTextFieldTwo}`);
memeUrl = await fn.memes.generate(template, [memeTextFieldOne, memeTextFieldTwo]);
console.log(memeUrl);
await interaction.reply({ content: 'Here is your meme: ' + memeUrl });
break;
case 'threeFieldMemeModal':
memeTextFieldOne = interaction.fields.getTextInputValue('memeTextFieldOne');
memeTextFieldTwo = interaction.fields.getTextInputValue('memeTextFieldTwo');
memeTextFieldThree = interaction.fields.getTextInputValue('memeTextFieldThree');
console.log(`Text: ${memeTextFieldOne}, ${memeTextFieldTwo}, ${memeTextFieldThree}`);
memeUrl = await fn.memes.generate(template, [memeTextFieldOne, memeTextFieldTwo, memeTextFieldThree]);
console.log(memeUrl);
await interaction.reply({ content: 'Here is your meme: ' + memeUrl });
break;
case 'fourFieldMemeModal':
memeTextFieldOne = interaction.fields.getTextInputValue('memeTextFieldOne');
memeTextFieldTwo = interaction.fields.getTextInputValue('memeTextFieldTwo');
memeTextFieldThree = interaction.fields.getTextInputValue('memeTextFieldThree');
memeTextFieldFour = interaction.fields.getTextInputValue('memeTextFieldFour');
console.log(`Text: ${memeTextFieldOne}, ${memeTextFieldTwo}, ${memeTextFieldThree}, ${memeTextFieldFour}`);
memeUrl = await fn.memes.generate(template, [memeTextFieldOne, memeTextFieldTwo, memeTextFieldThree, memeTextFieldFour]);
console.log(memeUrl);
await interaction.reply({ content: 'Here is your meme: ' + memeUrl });
break;
default:
break;
}
}
});
// dot-commands

View File

@ -11,6 +11,7 @@
"discord.js": "^13.15.1",
"dotenv": "^10.0.0",
"fuzzy-search": "^3.2.1",
"imgflip": "^4.0.0",
"mysql": "^2.18.1",
"openai": "^4.12.0",
"tenorjs": "^1.0.10"

62
slash-commands/meme.js Normal file
View File

@ -0,0 +1,62 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const { MessageActionRow, Modal, TextInputComponent } = require('discord.js');
const fn = require('../functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('meme')
.setDescription('Generate a meme from a template')
.addStringOption(option =>
option.setName('template')
.setDescription('The meme template')
.setRequired(true)
.addChoices(
{ name: 'Drake Hotline Bling', value: '181913649' },
{ name: 'Anakin & Padme', value: '322841258' },
{ name: 'Y\'all Got Any More...', value: '124055727' },
{ name: 'We Are Not The Same', value: '342785297' },
{ name: 'Surprised Pikachu', value: '155067746' },
{ name: 'Two Buttons', value: '87743020' },
{ name: 'Uno Draw 25', value: '217743513' }
)
),
async execute(interaction) {
try {
const template = interaction.options.getString('template');
// Switch the template
switch (template) {
// One-Field Memes
case '342785297': // We are not the same
// Generate a modal with one text input
const oneFieldMemeModal = fn.memes.oneFieldModal(template);
await interaction.showModal(oneFieldMemeModal);
break;
// Two-Field Memes
case '181913649': // Y'all got any more of that
case '124055727': // Drake Hotline Bling No/Yes
case '217743513': // Uno Draw 25
// Generate a modal with two text inputs
const twoFieldMemeModal = fn.memes.twoFieldModal(template);
await interaction.showModal(twoFieldMemeModal);
break;
// Three-Field Memes
case '322841258': // Anakin & Padme
case '342785297': // We are not the same
case '155067746': // Surprised Pikachu
case '87743020': // Two Buttons
// Generate a modal with three text inputs
const threeFieldMemeModal = fn.memes.threeFieldModal(template);
await interaction.showModal(threeFieldMemeModal);
break;
default:
await interaction.reply('Invalid meme template');
break;
}
} catch (error) {
console.error(error);
await interaction.reply('There was an error while executing this command!');
}
},
};