Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
eddf16a821 | |||
80f89d0117 | |||
d06cac6f3d | |||
7e2664083e |
46
.gitea/workflows/dev-docker.yml
Normal file
46
.gitea/workflows/dev-docker.yml
Normal file
@ -0,0 +1,46 @@
|
||||
name: NodBot PE Dockerization
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*-dev*'
|
||||
|
||||
env:
|
||||
DHUB_UNAME: ${{ secrets.DHUB_UNAME }}
|
||||
DHUB_PWORD: ${{ secrets.DHUB_PWORD }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Pull latest from Git
|
||||
run: |
|
||||
echo "Branch: tags/${{ gitea.ref_name }}"
|
||||
pwd
|
||||
whoami
|
||||
mkdir -p /var/lib/act_runner/
|
||||
cd /var/lib/act_runner/
|
||||
if [ ! -d "nodbot" ]; then
|
||||
git clone https://git.vfsh.dev/voidf1sh/nodbot-dev
|
||||
cd nodbot-dev
|
||||
else
|
||||
cd nodbot-dev
|
||||
git checkout main
|
||||
git pull
|
||||
fi
|
||||
git checkout tags/${{ gitea.ref_name }}
|
||||
- name: Build the Docker image
|
||||
run: |
|
||||
cd /var/lib/act_runner/nodbot-dev
|
||||
docker build . --file Dockerfile --tag v0idf1sh/nodbot-dev
|
||||
- name: Log into Docker Hub
|
||||
run: docker login -u $DHUB_UNAME -p $DHUB_PWORD
|
||||
- name: Push image to Docker Hub
|
||||
run: |
|
||||
cd /var/lib/act_runner/nodbot-dev
|
||||
docker push v0idf1sh/nodbot-dev
|
||||
- name: Restart the container
|
||||
run: |
|
||||
cd /srv/docker/nodbot-dev
|
||||
docker-compose down
|
||||
docker-compose up -d
|
@ -1,9 +1,9 @@
|
||||
name: NodBot Production Dockerization
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
push:
|
||||
tags:
|
||||
- 'v*-prod*'
|
||||
|
||||
env:
|
||||
DHUB_UNAME: ${{ secrets.DHUB_UNAME }}
|
||||
@ -15,7 +15,7 @@ jobs:
|
||||
steps:
|
||||
- name: Pull latest from Git
|
||||
run: |
|
||||
echo "Branch: ${{ gitea.head_ref }}"
|
||||
echo "Branch: tags/${{ gitea.ref_name }}"
|
||||
pwd
|
||||
whoami
|
||||
mkdir -p /var/lib/act_runner/
|
||||
@ -27,7 +27,7 @@ jobs:
|
||||
cd nodbot
|
||||
git pull
|
||||
fi
|
||||
git checkout ${{ gitea.head_ref }}
|
||||
git checkout tags/${{ gitea.ref_name }}
|
||||
- name: Build the Docker image
|
||||
run: |
|
||||
cd /var/lib/act_runner/nodbot
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,6 +4,7 @@ package-lock.json
|
||||
.VSCodeCounter/
|
||||
.env*
|
||||
*.env
|
||||
|
||||
# Custom folders
|
||||
# gifs/*
|
||||
# pastas/*
|
||||
|
@ -1,7 +1,3 @@
|
||||
## 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.3 (#20)
|
||||
* Fixed content-list slash commands `/gifs`, `/pastas`, `/joints`, `/requests` (#19)
|
||||
|
@ -8,7 +8,6 @@ module.exports = {
|
||||
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.author = message.author.username;
|
||||
this.message = message;
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -17,110 +16,14 @@ module.exports = {
|
||||
if (this.args.startsWith('http')) 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) {
|
||||
if (key === this.command) {
|
||||
this.isValid = true;
|
||||
return this;
|
||||
} else if (value.alias) {
|
||||
if (typeof value.alias === 'string' && value.alias === this.command) {
|
||||
} else if (value.alias && value.alias.includes(this.command)) {
|
||||
this.command = key;
|
||||
this.isValid = true;
|
||||
return this;
|
||||
} else if (typeof value.alias === 'object' && value.alias.includes(this.command)) {
|
||||
this.command = key;
|
||||
this.isValid = true;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM node:20
|
||||
FROM node:18
|
||||
RUN mkdir -p /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
|
27
_clear-commands.js
Normal file
27
_clear-commands.js
Normal file
@ -0,0 +1,27 @@
|
||||
// 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);
|
||||
}
|
||||
})();
|
40
_deploy-commands.js
Normal file
40
_deploy-commands.js
Normal file
@ -0,0 +1,40 @@
|
||||
// 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);
|
||||
}
|
||||
})();
|
39
_deploy-global.js
Normal file
39
_deploy-global.js
Normal file
@ -0,0 +1,39 @@
|
||||
// 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);
|
||||
}
|
||||
})();
|
@ -1,9 +1,7 @@
|
||||
const fn = require('../functions');
|
||||
const axios = require('axios');
|
||||
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
|
||||
// general API usage. See: https://github.com/Jinzulen/TenorJS/issues/12
|
||||
// see also: https://developers.google.com/tenor/guides/migrate-from-v1
|
||||
@ -18,17 +16,32 @@ module.exports = {
|
||||
const client = message.client;
|
||||
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');
|
||||
tenor.search(commandData.args, "1").then(res => {
|
||||
if (res[0] == undefined) {
|
||||
const q = await axios.get(
|
||||
'https://tenor.googleapis.com/v2/search?' +
|
||||
`&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);
|
||||
return;
|
||||
};
|
||||
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);
|
||||
commandData.embed_url = res.data.results[0].url;
|
||||
message.reply(commandData.embed_url);
|
||||
}).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 {
|
||||
// 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());
|
||||
|
@ -12,9 +12,8 @@ module.exports = {
|
||||
content: "Sorry, I couldn't find that pasta."
|
||||
};
|
||||
} else {
|
||||
commandData.content = client.pastas.get(commandData.args).content;
|
||||
pastaData = client.pastas.get(commandData.args);
|
||||
}
|
||||
const messagePayload = fn.embeds.pasta(commandData);
|
||||
message.reply(messagePayload);
|
||||
message.reply(fn.embeds.pasta(commandData, pastaData));
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@ module.exports = {
|
||||
execute(message, commandData) {
|
||||
const request = commandData.args;
|
||||
commandData.content = `Your request has been submitted!\nRequest: ${request}`;
|
||||
commandData.requestUrl = message.url;
|
||||
message.reply(fn.embeds.text(commandData));
|
||||
commandData.content = `A new request has been submitted by ${message.author.tag}:\n${commandData.args}`;
|
||||
message.client.users.fetch(process.env.ownerID).then(user => {
|
||||
|
64
functions.js
64
functions.js
@ -2,13 +2,12 @@
|
||||
// dotenv for handling environment variables
|
||||
const dotenv = require('dotenv').config();
|
||||
// Assignment of environment variables for database access
|
||||
const dbHost = process.env.DB_HOST;
|
||||
const dbUser = process.env.DB_USER;
|
||||
const dbName = process.env.DB_NAME;
|
||||
const dbPass = process.env.DB_PASS;
|
||||
const dbPort = process.env.DB_PORT;
|
||||
const isDev = process.env.IS_DEV;
|
||||
|
||||
const dbHost = process.env.dbHost;
|
||||
const dbUser = process.env.dbUser;
|
||||
const dbName = process.env.dbName;
|
||||
const dbPass = process.env.dbPass;
|
||||
const dbPort = process.env.dbPort;
|
||||
const isDev = process.env.isDev;
|
||||
const ownerId = process.env.ownerId;
|
||||
|
||||
// filesystem
|
||||
@ -27,6 +26,7 @@ const axios = require('axios');
|
||||
// Various imports from other files
|
||||
const config = require('./config.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 customEmbeds = require('./CustomModules/Embeds.js');
|
||||
|
||||
@ -249,16 +249,26 @@ const functions = {
|
||||
], ephemeral: true };
|
||||
},
|
||||
gif(commandData) {
|
||||
return commandData.embed_url;
|
||||
return { embeds: [new Discord.MessageEmbed()
|
||||
.setAuthor({name: `${commandData.args}.${commandData.command}`})
|
||||
.setImage(commandData.embed_url)
|
||||
.setTimestamp()
|
||||
.setFooter({text: commandData.author})]};
|
||||
},
|
||||
pasta(commandData) {
|
||||
return commandData.content;
|
||||
pasta(commandData, pastaData) {
|
||||
return { embeds: [ new Discord.MessageEmbed()
|
||||
.setAuthor({name: `${commandData.args}.${commandData.command}`})
|
||||
.setDescription(pastaData.content)
|
||||
.setThumbnail("https://assets.vfsh.dev/shednod.png")
|
||||
.setTimestamp()
|
||||
.setFooter({text: commandData.author})]};
|
||||
},
|
||||
pastas(commandData, indexedPastas) {
|
||||
const pastasEmbed = new Discord.MessageEmbed()
|
||||
.setAuthor({name: commandData.command})
|
||||
.setTimestamp()
|
||||
.setFooter({text: commandData.author});
|
||||
.setFooter({text: `Page: ${indexedPastas.pagesString}`})
|
||||
.setDescription(indexedPastas.pastasString);
|
||||
|
||||
const pastasPageAR = customEmbeds.pastasPageAR(indexedPastas.state);
|
||||
return { embeds: [pastasEmbed], components: [pastasPageAR], ephemeral: true };
|
||||
@ -267,7 +277,8 @@ const functions = {
|
||||
const gifsEmbed = new Discord.MessageEmbed()
|
||||
.setAuthor({name: commandData.command})
|
||||
.setTimestamp()
|
||||
.setFooter({text: commandData.author});
|
||||
.setFooter({text: `Page: ${indexedGifs.pagesString}`})
|
||||
.setDescription(indexedGifs.gifsString);
|
||||
|
||||
const gifsPageAR = customEmbeds.gifsPageAR(indexedGifs.state);
|
||||
return { embeds: [gifsEmbed], components: [gifsPageAR], ephemeral: true };
|
||||
@ -293,16 +304,15 @@ const functions = {
|
||||
const requestsEmbed = new Discord.MessageEmbed()
|
||||
.setAuthor({name: commandData.command})
|
||||
.setTimestamp()
|
||||
.setFooter({text: commandData.author});
|
||||
.setFooter({text: `Page: ${indexedRequests.pagesString}`})
|
||||
.setDescription(indexedRequests.requestsString);
|
||||
|
||||
const requestsPageAR = customEmbeds.requestsPageAR(indexedRequests.state);
|
||||
return { embeds: [requestsEmbed], components: [requestsPageAR], ephemeral: true };
|
||||
},
|
||||
strain(commandData, message) {
|
||||
strain(strainInfo, interaction) {
|
||||
const strainEmbed = new Discord.MessageEmbed()
|
||||
.setTimestamp()
|
||||
.setFooter({text: commandData.author});
|
||||
const { strainInfo } = commandData;
|
||||
.setTimestamp();
|
||||
strainEmbed.addFields([
|
||||
{
|
||||
name: 'Strain Name',
|
||||
@ -326,7 +336,7 @@ const functions = {
|
||||
},
|
||||
{
|
||||
name: 'Rating',
|
||||
value: `${strainInfo.rating}⭐️s`,
|
||||
value: `⭐️${strainInfo.rating}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
@ -336,7 +346,7 @@ const functions = {
|
||||
},
|
||||
]);
|
||||
|
||||
message.reply({ embeds: [ strainEmbed ]});
|
||||
interaction.reply({ embeds: [ strainEmbed ]});
|
||||
},
|
||||
dalle(prompt, imageUrl, size) {
|
||||
const dalleEmbed = new Discord.MessageEmbed()
|
||||
@ -429,7 +439,7 @@ const functions = {
|
||||
},
|
||||
upload: {
|
||||
request(commandData, client) {
|
||||
const query = `INSERT INTO requests (author, request, status, url) VALUES (${db.escape(commandData.author)},${db.escape(commandData.args)},'Active',${db.escape(commandData.url)})`;
|
||||
const query = `INSERT INTO requests (author, request, status) VALUES (${db.escape(commandData.author)},${db.escape(commandData.args)},'Active')`;
|
||||
db.query(query, (err, rows, fields) => {
|
||||
if (err) throw err;
|
||||
functions.download.requests(client);
|
||||
@ -552,12 +562,11 @@ const functions = {
|
||||
functions.collections.joints(rows, client);
|
||||
});
|
||||
},
|
||||
async strain(commandData, message) {
|
||||
const { strainName } = commandData;
|
||||
async strain(strainName, interaction) {
|
||||
const query = `SELECT id, strain, type, effects, description, flavor, rating FROM strains WHERE strain = ${db.escape(strainName)}`;
|
||||
await db.query(query, (err, rows, fields) => {
|
||||
if (rows != undefined) {
|
||||
commandData.strainInfo = {
|
||||
const strainInfo = {
|
||||
id: `${rows[0].id}`,
|
||||
strain: `${rows[0].strain}`,
|
||||
type: `${rows[0].type}`,
|
||||
@ -566,7 +575,7 @@ const functions = {
|
||||
flavor: `${rows[0].flavor}`,
|
||||
rating: `${rows[0].rating}`,
|
||||
};
|
||||
functions.embeds.strain(commandData, message);
|
||||
functions.embeds.strain(strainInfo, interaction);
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -589,12 +598,7 @@ const functions = {
|
||||
strain: {
|
||||
lookup(strainName, client) {
|
||||
const strainSearcher = new FuzzySearch(client.strains.map(e => e.name));
|
||||
const name = strainSearcher.search(strainName)[0];
|
||||
if (name != undefined) {
|
||||
return name;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return strainSearcher.search(strainName).slice(0,25);
|
||||
},
|
||||
submit(strainName) {
|
||||
const query = ``
|
||||
|
195
main.js
195
main.js
@ -4,11 +4,18 @@
|
||||
const dotenv = require('dotenv');
|
||||
dotenv.config();
|
||||
const token = process.env.TOKEN;
|
||||
const statusChannelId = process.env.STATUS_CHANNEL_ID;
|
||||
const statusChannelId = process.env.statusChannelId;
|
||||
|
||||
// Discord.JS
|
||||
const { Client } = require('discord.js-selfbot-v13');
|
||||
const { Client, Intents } = require('discord.js');
|
||||
const client = new Client({
|
||||
intents: [
|
||||
'GUILDS',
|
||||
'GUILD_MESSAGES',
|
||||
'GUILD_MESSAGE_REACTIONS',
|
||||
'DIRECT_MESSAGES',
|
||||
'DIRECT_MESSAGE_REACTIONS',
|
||||
],
|
||||
partials: [
|
||||
'CHANNEL',
|
||||
'MESSAGE',
|
||||
@ -21,9 +28,13 @@ const fn = require('./functions.js');
|
||||
const config = require('./config.json');
|
||||
const strings = require('./strings.json');
|
||||
const { GifData, CommandData } = require('./CustomModules/NodBot.js');
|
||||
const isDev = process.env.IS_DEV;
|
||||
const ButtonHandlers = require('./CustomModules/ButtonHandlers.js');
|
||||
const InteractionStorage = require('./CustomModules/InteractionStorage.js');
|
||||
const isDev = process.env.isDev;
|
||||
|
||||
client.once('ready', async () => {
|
||||
fn.collections.interactionStorage(client);
|
||||
fn.collections.slashCommands(client);
|
||||
fn.collections.dotCommands(client);
|
||||
fn.collections.setvalidCommands(client);
|
||||
fn.collections.roaches(client);
|
||||
@ -38,15 +49,189 @@ client.once('ready', async () => {
|
||||
await fn.avWx.datis.getAllICAOs();
|
||||
// console.log(JSON.stringify(icaoArray));
|
||||
client.channels.fetch(statusChannelId).then(channel => {
|
||||
channel.send(`${new Date().toISOString()} -- <@${process.env.OWNER_ID}>\nStartup Sequence Complete`);
|
||||
channel.send(`${new Date().toISOString()} -- <@${process.env.ownerId}>\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
|
||||
client.on('messageCreate', message => {
|
||||
// Some basic checking to prevent running unnecessary code
|
||||
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
|
||||
const lowerContent = message.content.toLowerCase();
|
||||
|
13
package.json
13
package.json
@ -1,23 +1,22 @@
|
||||
{
|
||||
"name": "nodbot",
|
||||
"version": "3.4.0",
|
||||
"description": "Nods and Nod Accessories",
|
||||
"version": "3.3.3",
|
||||
"description": "Nods and Nod Accessories, now with ChatGPT!",
|
||||
"main": "main.js",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^1.9.0",
|
||||
"@discordjs/builders": "^0.16.0",
|
||||
"@discordjs/rest": "^0.1.0-canary.0",
|
||||
"axios": "^0.21.4",
|
||||
"discord-api-types": "^0.22.0",
|
||||
"discord.js": "^13.15.1",
|
||||
"discord.js-selfbot-v13": "^3.4.0",
|
||||
"dotenv": "^10.0.0",
|
||||
"fuzzy-search": "^3.2.1",
|
||||
"mysql": "^2.18.1",
|
||||
"tenorjs": "1.0.10",
|
||||
"tenorjs-v2": "^1.0.2"
|
||||
"openai": "^4.12.0",
|
||||
"tenorjs": "^1.0.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.x"
|
||||
"node": "18.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^7.32.0"
|
||||
|
16
slash-commands/closereq.js
Normal file
16
slash-commands/closereq.js
Normal file
@ -0,0 +1,16 @@
|
||||
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);
|
||||
},
|
||||
};
|
110
slash-commands/edit.js
Normal file
110
slash-commands/edit.js
Normal file
@ -0,0 +1,110 @@
|
||||
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`);
|
||||
}
|
||||
};
|
30
slash-commands/gifs.js
Normal file
30
slash-commands/gifs.js
Normal file
@ -0,0 +1,30 @@
|
||||
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));
|
||||
}
|
||||
};
|
11
slash-commands/help.js
Normal file
11
slash-commands/help.js
Normal file
@ -0,0 +1,11 @@
|
||||
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));
|
||||
}
|
||||
};
|
11
slash-commands/jenny.js
Normal file
11
slash-commands/jenny.js
Normal file
@ -0,0 +1,11 @@
|
||||
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');
|
||||
},
|
||||
};
|
17
slash-commands/joint.js
Normal file
17
slash-commands/joint.js
Normal file
@ -0,0 +1,17 @@
|
||||
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}`);
|
||||
},
|
||||
};
|
29
slash-commands/joints.js
Normal file
29
slash-commands/joints.js
Normal file
@ -0,0 +1,29 @@
|
||||
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));
|
||||
},
|
||||
};
|
11
slash-commands/lenny.js
Normal file
11
slash-commands/lenny.js
Normal file
@ -0,0 +1,11 @@
|
||||
const { SlashCommandBuilder } = require('@discordjs/builders');
|
||||
const fn = require('../functions.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('lenny')
|
||||
.setDescription('( ͡° ͜ʖ ͡°)'),
|
||||
async execute(interaction) {
|
||||
interaction.reply('( ͡° ͜ʖ ͡°)');
|
||||
},
|
||||
};
|
30
slash-commands/pastas.js
Normal file
30
slash-commands/pastas.js
Normal file
@ -0,0 +1,30 @@
|
||||
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));
|
||||
},
|
||||
};
|
11
slash-commands/ping.js
Normal file
11
slash-commands/ping.js
Normal file
@ -0,0 +1,11 @@
|
||||
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 });
|
||||
},
|
||||
};
|
20
slash-commands/reload.js
Normal file
20
slash-commands/reload.js
Normal file
@ -0,0 +1,20 @@
|
||||
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 });
|
||||
},
|
||||
};
|
31
slash-commands/requests.js
Normal file
31
slash-commands/requests.js
Normal file
@ -0,0 +1,31 @@
|
||||
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));
|
||||
},
|
||||
};
|
232
slash-commands/save.js
Normal file
232
slash-commands/save.js
Normal file
@ -0,0 +1,232 @@
|
||||
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}`);
|
||||
}
|
||||
}
|
||||
};
|
15
slash-commands/setup.js
Normal file
15
slash-commands/setup.js
Normal file
@ -0,0 +1,15 @@
|
||||
// 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 });
|
||||
},
|
||||
};
|
17
slash-commands/strain.js
Normal file
17
slash-commands/strain.js
Normal file
@ -0,0 +1,17 @@
|
||||
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);
|
||||
},
|
||||
};
|
11
slash-commands/template
Normal file
11
slash-commands/template
Normal file
@ -0,0 +1,11 @@
|
||||
const { SlashCommandBuilder } = require('@discordjs/builders');
|
||||
const fn = require('../functions.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('')
|
||||
.setDescription(''),
|
||||
async execute(interaction) {
|
||||
await
|
||||
},
|
||||
};
|
11
slash-commands/truth.js
Normal file
11
slash-commands/truth.js
Normal file
@ -0,0 +1,11 @@
|
||||
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');
|
||||
},
|
||||
};
|
Loading…
Reference in New Issue
Block a user