Compare commits
No commits in common. 'Slash-V14' and 'akairo' have entirely different histories.
@ -1,19 +0,0 @@
|
|||||||
token=YourToken
|
|
||||||
clientId=BotClientId
|
|
||||||
guildId=DevGuildId
|
|
||||||
ownerId=OwnerUserId
|
|
||||||
statusChannel=CHannelIdForStatus
|
|
||||||
uptimeURL=UptimeKumaOrWhateverStatusThingYouUseOrJustLeaveEmpty
|
|
||||||
uptimeInterval=60
|
|
||||||
twiConsumer=TwitterConsumerToken
|
|
||||||
twiConsumerSecret=TwitterConsumerSecretToken
|
|
||||||
twiToken=TwitterToken
|
|
||||||
twiTokenSecret=TwitterSecretToken
|
|
||||||
twiChannel=ChannelWhereJustTheTwitterLinkAreSent
|
|
||||||
twiLogChannel=ChannelWhereTheDetailedInfoOfTheCommandIsSent
|
|
||||||
botsggToken=APITokenForBots.gg
|
|
||||||
botsggEndpoint=https://discord.bots.gg/api/v1
|
|
||||||
stableHordeApi=0000000000
|
|
||||||
stableHordeID=0000
|
|
||||||
NODE_ENV=development
|
|
||||||
ytdlpMaxResolution=720
|
|
@ -1,57 +1,28 @@
|
|||||||
{
|
{
|
||||||
"extends": "eslint:recommended",
|
|
||||||
"env": {
|
"env": {
|
||||||
"node": true,
|
"es6": true,
|
||||||
"es6": true
|
"node": true
|
||||||
},
|
},
|
||||||
"parser": "@babel/eslint-parser",
|
"extends": "eslint:recommended",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 2022,
|
"ecmaVersion": 2018,
|
||||||
"sourceType": "module",
|
"sourceType": "module"
|
||||||
"requireConfigFile": false,
|
|
||||||
"babelOptions": {
|
|
||||||
"plugins": [
|
|
||||||
"@babel/plugin-syntax-import-assertions"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"arrow-spacing": ["warn", { "before": true, "after": true }],
|
"no-console": [
|
||||||
"brace-style": ["error", "stroustrup", { "allowSingleLine": true }],
|
"off"
|
||||||
"comma-dangle": ["error", "always-multiline"],
|
],
|
||||||
"comma-spacing": "error",
|
"indent": [
|
||||||
"comma-style": "error",
|
"error",
|
||||||
"curly": ["error", "multi-line", "consistent"],
|
"tab"
|
||||||
"dot-location": ["error", "property"],
|
],
|
||||||
"handle-callback-err": "off",
|
"quotes": [
|
||||||
"indent": ["error", "tab"],
|
"error",
|
||||||
"keyword-spacing": "error",
|
"single"
|
||||||
"max-nested-callbacks": ["error", { "max": 4 }],
|
],
|
||||||
"max-statements-per-line": ["error", { "max": 2 }],
|
"semi": [
|
||||||
"no-console": "off",
|
"error",
|
||||||
"no-empty-function": "error",
|
"always"
|
||||||
"no-floating-decimal": "error",
|
]
|
||||||
"no-inline-comments": "error",
|
|
||||||
"no-lonely-if": "error",
|
|
||||||
"no-multi-spaces": "error",
|
|
||||||
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }],
|
|
||||||
"no-shadow": ["error", { "allow": ["err", "resolve", "reject"] }],
|
|
||||||
"no-trailing-spaces": ["error"],
|
|
||||||
"no-var": "error",
|
|
||||||
"object-curly-spacing": ["error", "always"],
|
|
||||||
"prefer-const": "error",
|
|
||||||
"quotes": ["error", "single"],
|
|
||||||
"semi": ["error", "always"],
|
|
||||||
"space-before-blocks": "error",
|
|
||||||
"space-before-function-paren": ["error", {
|
|
||||||
"anonymous": "never",
|
|
||||||
"named": "never",
|
|
||||||
"asyncArrow": "always"
|
|
||||||
}],
|
|
||||||
"space-in-parens": "error",
|
|
||||||
"space-infix-ops": "error",
|
|
||||||
"space-unary-ops": "error",
|
|
||||||
"spaced-comment": "error",
|
|
||||||
"yoda": "error"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,37 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
name: "Bug"
|
|
||||||
about: "Use this if you found a bug in the bot."
|
|
||||||
title: "[BUG] "
|
|
||||||
ref: "main"
|
|
||||||
labels:
|
|
||||||
|
|
||||||
- bug
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- Please provide the commit of the bot at the time of the report. You can find it by doing /about or haha about. -->
|
|
||||||
**Commit number**
|
|
||||||
|
|
||||||
**Bot varient**
|
|
||||||
<!-- Put a x between the brackets to signify the version you used. -->
|
|
||||||
- [ ] Slash <!-- The current and latest version that use the slash commands. -->
|
|
||||||
- [ ] Legacy <!-- The old version of the bot with the "haha" prefix. -->
|
|
||||||
|
|
||||||
**Describe the issue**
|
|
||||||
|
|
||||||
**Intended result**
|
|
||||||
|
|
||||||
**Screenshots**
|
|
||||||
|
|
||||||
**Steps to reproduce the issue**
|
|
||||||
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
|
|
||||||
**Did someone already report that bug?**
|
|
||||||
|
|
||||||
- [ ] Yes <!-- If you have to put yes you don't need to submit that bug report. -->
|
|
||||||
- [ ] No
|
|
@ -1,19 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
name: "Feature request"
|
|
||||||
about: "Use this if you want a new feature in the bot."
|
|
||||||
title: "[Feature request] "
|
|
||||||
ref: "main"
|
|
||||||
labels:
|
|
||||||
|
|
||||||
- Feature request
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Describe the feature you want**
|
|
||||||
|
|
||||||
|
|
||||||
**Did someone already request that feature?**
|
|
||||||
|
|
||||||
- [ ] Yes <!-- If you have to put yes you don't need to submit that feature request. -->
|
|
||||||
- [ ] No
|
|
@ -1,16 +1,55 @@
|
|||||||
.env
|
# root /
|
||||||
node_modules/
|
|
||||||
config/config.json
|
config.json
|
||||||
json/board/
|
.DS_Store
|
||||||
unloaded/
|
node_modules
|
||||||
database.sqlite3
|
.vscode
|
||||||
tmp/*.js
|
error/
|
||||||
|
|
||||||
bin/yt-dlp
|
# video
|
||||||
bin/HandBrakeCLI
|
|
||||||
bin/upload.sh
|
video.mp4
|
||||||
bin/dectalk
|
videoReady.mp4
|
||||||
|
SPOILER_video.mp4
|
||||||
asset/ytp/sources
|
SPOILER_videoReady.mp4
|
||||||
asset/ytp/music
|
|
||||||
asset/ytp/sounds
|
## images
|
||||||
|
|
||||||
|
img/frame001.png
|
||||||
|
img/spb.png
|
||||||
|
img/de.png
|
||||||
|
img/nolight.png
|
||||||
|
img/memeInput.gif
|
||||||
|
img/meme.gif
|
||||||
|
spb.png
|
||||||
|
|
||||||
|
### audio
|
||||||
|
|
||||||
|
tts.mp3
|
||||||
|
ttsvc.mp3
|
||||||
|
music.mp3
|
||||||
|
dectalk.wav
|
||||||
|
dectalkvc.wav
|
||||||
|
sam.wav
|
||||||
|
samvc.wav
|
||||||
|
|
||||||
|
# json
|
||||||
|
|
||||||
|
json/blacklist.json
|
||||||
|
json/customresponse.json
|
||||||
|
board/*.json
|
||||||
|
tag/*.json
|
||||||
|
welcome/*.json
|
||||||
|
bye/*.json
|
||||||
|
webhook/*.json
|
||||||
|
json/censor.json
|
||||||
|
json/uncensor.json
|
||||||
|
|
||||||
|
# other
|
||||||
|
dectalk/
|
||||||
|
*_unloaded.js
|
||||||
|
asset/ytp/userVid/*.mp4
|
||||||
|
asset/ytp/music/
|
||||||
|
asset/ytp/resources/
|
||||||
|
asset/ytp/sounds/
|
||||||
|
asset/ytp/sources/
|
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
// Use IntelliSense to learn about possible attributes.
|
|
||||||
// Hover to view descriptions of existing attributes.
|
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"type": "pwa-node",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "Launch Program",
|
|
||||||
"skipFiles": [
|
|
||||||
"<node_internals>/**"
|
|
||||||
],
|
|
||||||
"program": "${workspaceFolder}/index.js"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -0,0 +1,83 @@
|
|||||||
|
# Haha Yes
|
||||||
|
|
||||||
|
A multi function discord bot.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
These instructions will get you a copy of the project up and running on your local machine
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
You need to install the following
|
||||||
|
|
||||||
|
|
||||||
|
* https://github.com/Automattic/node-canvas
|
||||||
|
* sequelize-cli (``npm install -g sequelize-cli``)
|
||||||
|
* mysql
|
||||||
|
* ffmpeg (Optional but recommanded: for all command that require to interact with voice chat and [vid2gif.js](commands/utility/vid2gif.js), [vidshittyfier.js](commands/fun/vidshittyfier.js) and [ytp.js](commands/fun/ytp.js))
|
||||||
|
* handbrake-cli (Optional but recommanded: for [download.js](commands/utility/download.js))
|
||||||
|
* apngasm (Optional: for [nolight.js](commands/images/nolight))
|
||||||
|
* [Google credentials](https://cloud.google.com/docs/authentication/getting-started) (Optional: for [tts.js](commands/fun/tts/tts.js) and [ttsvc.js](commands/fun/tts/ttsvc.js), without that it will spam error on startup but not important)
|
||||||
|
* Wine (Optional: required for linux/mac for [dectalk.js](commands/fun/tts/dectalk.js) and [dectalkvc.js](commands/fun/tts/dectalkvc.js))
|
||||||
|
* xvfb (Optional: for wine if using headless server)
|
||||||
|
* waon (Optional: used to convert sound files to midi for [midify.js](commands/fun/midify.js))
|
||||||
|
* timidity (Optional: used to convert the midi files back to mp3 for [midify.js](commands/fun/midify.js))
|
||||||
|
|
||||||
|
### Installing
|
||||||
|
```
|
||||||
|
git clone https://git.namejeff.xyz/Supositware/Haha-Yes
|
||||||
|
cd discordbot
|
||||||
|
npm install
|
||||||
|
|
||||||
|
sequelize db:migrate
|
||||||
|
```
|
||||||
|
|
||||||
|
If the youtube-dl module didn't install youtube-dl by himself you can go in ``node_modules/youtube-dl/scripts`` and run ``node download.js``
|
||||||
|
Configure [config.json](config-exemple.jsonc) and [config/config.json](config/config-example.json )
|
||||||
|
|
||||||
|
To run the bot either use pm2
|
||||||
|
```
|
||||||
|
npm install -g pm2
|
||||||
|
pm2 start index.js --name(insert name)
|
||||||
|
```
|
||||||
|
or with node ``node index.js``
|
||||||
|
|
||||||
|
If on linux you can also do
|
||||||
|
|
||||||
|
``nohup node index.js &``
|
||||||
|
|
||||||
|
To use [ytp.js](commands/fun/ytp.js)
|
||||||
|
1. Download the folder 'sounds', 'music', 'resources', 'sources' from [YTPPlus](https://github.com/philosophofee/YTPPlus)
|
||||||
|
2. Put them in the [asset/ytp](asset/ytp) folder
|
||||||
|
|
||||||
|
To use dectalk on linux you will need
|
||||||
|
1. Get dectalk
|
||||||
|
2. install wine
|
||||||
|
3. install Xvfb & run `Xvfb :0 -screen 0 1024x768x16 &`
|
||||||
|
|
||||||
|
## Built With
|
||||||
|
|
||||||
|
* [Discord.JS](https://github.com/discordjs/discord.js) - The discord api used
|
||||||
|
* [Discord-Akairo](https://github.com/1Computer1/discord-akairo) - The framework used for Discord.JS
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
|
||||||
|
* **Loïc Bersier**
|
||||||
|
|
||||||
|
## Donation link
|
||||||
|
|
||||||
|
[![Paypal](https://www.paypalobjects.com/en_US/CH/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/paypalme2/supositware/)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the **GNU Affero General Public License v3.0** License - see the [LICENSE](LICENSE) file for details
|
||||||
|
|
||||||
|
## Acknowledgments
|
||||||
|
|
||||||
|
* [discord.JS team](https://github.com/discordjs/discord.js)
|
||||||
|
* [1computer1](https://github.com/1Computer1/) for discord-akairo & the help command from [hoshi](https://github.com/1Computer1/hoshi)
|
||||||
|
* [Rantionary](https://github.com/RantLang/Rantionary) for there dictionnary.
|
||||||
|
* Tina the Cyclops girl#0064 for inspiring me for making this bot
|
||||||
|
* [Jetbrains](https://www.jetbrains.com/?from=Hahayesdiscordbot) for providing their IDE free of charges!
|
||||||
|
|
||||||
|
<img src="https://its.gamingti.me/XT8F.svg" width=20%></img>
|
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 258 KiB |
After Width: | Height: | Size: 283 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 147 KiB |
After Width: | Height: | Size: 172 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 401 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 164 KiB |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 197 KiB |
After Width: | Height: | Size: 259 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 46 KiB |
@ -0,0 +1 @@
|
|||||||
|
# You Will need to edit the config files to includes absolute path
|
@ -0,0 +1 @@
|
|||||||
|
soundfont /restricted/hahayes/hahaTest/asset/timidity/sf/MCNBS_3_3_4.sf2
|
@ -0,0 +1 @@
|
|||||||
|
soundfont /restricted/hahayes/hahaTest/asset/timidity/sf/E3Kay_s_Epic_Soundfont.sf2
|
@ -0,0 +1,6 @@
|
|||||||
|
# Credits
|
||||||
|
|
||||||
|
MCNBS_3_3_4.sf2 - [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/deed.en) Author: Stuff by David
|
||||||
|
|
||||||
|
|
||||||
|
E3Kay's Epic Soundfont - [Creative Commons Attribution 3.0 Unported](http://creativecommons.org/licenses/by-3/4.0/deed.en) Author: E3Kay
|
@ -1,171 +0,0 @@
|
|||||||
/* TODO
|
|
||||||
*
|
|
||||||
* To be merged with commands/AI/txt2img.js
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
import { SlashCommandBuilder, EmbedBuilder, AttachmentBuilder, ButtonBuilder, ActionRowBuilder, ButtonStyle } from 'discord.js';
|
|
||||||
import fetch from 'node-fetch';
|
|
||||||
import os from 'node:os';
|
|
||||||
import fs from 'node:fs';
|
|
||||||
import stream from 'node:stream';
|
|
||||||
import util from 'node:util';
|
|
||||||
|
|
||||||
import db from '../../models/index.js';
|
|
||||||
|
|
||||||
const { stableHordeApi, stableHordeID } = process.env;
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data: new SlashCommandBuilder()
|
|
||||||
.setName('img2img')
|
|
||||||
.setDescription('AI generated image with stable diffusion (If credit are low it may be slow)')
|
|
||||||
.addAttachmentOption(option =>
|
|
||||||
option.setName('image')
|
|
||||||
.setDescription('Image you want to modify')
|
|
||||||
.setRequired(true))
|
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('prompt')
|
|
||||||
.setDescription('What do you want the AI to generate?')
|
|
||||||
.setRequired(true)),
|
|
||||||
category: 'AI',
|
|
||||||
alias: ['i2i'],
|
|
||||||
async execute(interaction, args, client) {
|
|
||||||
await interaction.deferReply();
|
|
||||||
|
|
||||||
const streamPipeline = util.promisify(stream.pipeline);
|
|
||||||
const res = await fetch(args.image.url);
|
|
||||||
if (!res.ok) return interaction.editReply('An error has occured while trying to download your image.');
|
|
||||||
await streamPipeline(res.body, fs.createWriteStream(`${os.tmpdir()}/${args.image.name}.webp`));
|
|
||||||
|
|
||||||
const b64Image = fs.readFileSync(`${os.tmpdir()}/${args.image.name}.webp`, { encoding: 'base64' });
|
|
||||||
generate(interaction, args.prompt, client, b64Image);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
async function generate(i, prompt, client, b64Img) {
|
|
||||||
console.log('Generating image');
|
|
||||||
const body = {
|
|
||||||
prompt: prompt,
|
|
||||||
params: {
|
|
||||||
n: 1,
|
|
||||||
width: 512,
|
|
||||||
height: 512,
|
|
||||||
},
|
|
||||||
cfg_scale: 9,
|
|
||||||
use_gfpgan: true,
|
|
||||||
use_real_esrgan: true,
|
|
||||||
use_ldsr: true,
|
|
||||||
use_upscaling: true,
|
|
||||||
steps: 50,
|
|
||||||
nsfw: i.channel.nsfw ? true : false,
|
|
||||||
censor_nsfw: i.channel.nsfw ? true : false,
|
|
||||||
source_image: b64Img,
|
|
||||||
source_processing: 'img2img',
|
|
||||||
shared: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const isOptOut = await db.optout.findOne({ where: { userID: i.user.id } });
|
|
||||||
|
|
||||||
if (isOptOut) {
|
|
||||||
body.shared = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchParameters = {
|
|
||||||
method: 'post',
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
headers: { 'Content-Type': 'application/json', 'apikey': stableHordeApi },
|
|
||||||
};
|
|
||||||
|
|
||||||
let response = await fetch('https://stablehorde.net/api/v2/generate/async', fetchParameters);
|
|
||||||
|
|
||||||
response = await response.json();
|
|
||||||
|
|
||||||
if (!response.id) {
|
|
||||||
console.log(response);
|
|
||||||
return i.editReply({ content: `An error has occured, please try again later. \`${response.message}\`` });
|
|
||||||
}
|
|
||||||
|
|
||||||
let wait_time = 5000;
|
|
||||||
let checkURL = `https://stablehorde.net/api/v2/generate/check/${response.id}`;
|
|
||||||
const checking = setInterval(async () => {
|
|
||||||
const checkResult = await checkGeneration(checkURL);
|
|
||||||
|
|
||||||
if (checkResult === undefined) return;
|
|
||||||
if (!checkResult.done) {
|
|
||||||
if (checkResult.wait_time === -1) {
|
|
||||||
console.log(checkResult.raw);
|
|
||||||
return i.editReply({ content: `An error has occured, please try again later. \`${checkResult.raw.message}\`` });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkResult.wait_time < 0) {
|
|
||||||
console.log(checkResult.raw);
|
|
||||||
clearInterval(checking);
|
|
||||||
return i.editReply({ content: 'No servers are currently available to fulfill your request, please try again later.' });
|
|
||||||
}
|
|
||||||
if (checkResult.wait_time === 0) {
|
|
||||||
checkURL = `https://stablehorde.net/api/v2/generate/status/${response.id}`;
|
|
||||||
}
|
|
||||||
wait_time = checkResult.wait_time;
|
|
||||||
}
|
|
||||||
else if (checkResult.done && checkResult.image) {
|
|
||||||
clearInterval(checking);
|
|
||||||
let creditResponse = await fetch(`https://stablehorde.net/api/v2/users/${stableHordeID}`);
|
|
||||||
creditResponse = await creditResponse.json();
|
|
||||||
|
|
||||||
const streamPipeline = util.promisify(stream.pipeline);
|
|
||||||
const res = await fetch(checkResult.image);
|
|
||||||
if (!res.ok) return i.editReply('An error has occured while trying to download your image.');
|
|
||||||
await streamPipeline(res.body, fs.createWriteStream(`${os.tmpdir()}/${i.id}.webp`));
|
|
||||||
|
|
||||||
const generatedImg = new AttachmentBuilder(`${os.tmpdir()}/${i.id}.webp`);
|
|
||||||
|
|
||||||
const stableEmbed = new EmbedBuilder()
|
|
||||||
.setColor(i.member ? i.member.displayHexColor : 'Navy')
|
|
||||||
.setTitle(prompt)
|
|
||||||
.setURL('https://aqualxx.github.io/stable-ui/')
|
|
||||||
.setImage(`attachment://${i.id}.webp`)
|
|
||||||
.setFooter({ text: `**Credit left: ${creditResponse.kudos}** Seed: ${checkResult.seed} worker ID: ${checkResult.worker_id} worker name: ${checkResult.worker_name}` });
|
|
||||||
|
|
||||||
const row = new ActionRowBuilder()
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`regenerate${i.user.id}${i.id}`)
|
|
||||||
.setLabel('🔄 Regenerate')
|
|
||||||
.setStyle(ButtonStyle.Primary),
|
|
||||||
);
|
|
||||||
|
|
||||||
await i.editReply({ embeds: [stableEmbed], components: [row], files: [generatedImg] });
|
|
||||||
|
|
||||||
listenButton(client, i, prompt);
|
|
||||||
}
|
|
||||||
}, wait_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkGeneration(url) {
|
|
||||||
let check = await fetch(url);
|
|
||||||
check = await check.json();
|
|
||||||
|
|
||||||
if (!check.is_possible) {
|
|
||||||
return { done: false, wait_time: -1, raw: check };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check.done) {
|
|
||||||
if (!check.generations) {
|
|
||||||
return { done: false, wait_time: check.wait_time * 1000, raw: check };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { done: true, image: check.generations[0].img, seed: check.generations[0].seed, worker_id: check.generations[0].worker_id, worker_name: check.generations[0].worker_name, raw: check };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function listenButton(client, interaction, prompt) {
|
|
||||||
client.once('interactionCreate', async (interactionMenu) => {
|
|
||||||
if (!interactionMenu.isButton()) return;
|
|
||||||
|
|
||||||
await interactionMenu.update({ components: [] });
|
|
||||||
|
|
||||||
if (interactionMenu.customId === `regenerate${interactionMenu.user.id}${interaction.id}`) {
|
|
||||||
await interactionMenu.deferReply();
|
|
||||||
await generate(interactionMenu, prompt, client);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,145 +0,0 @@
|
|||||||
/* TODO
|
|
||||||
*
|
|
||||||
* To be merged with commands/AI/img2img.js
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
import { SlashCommandBuilder, EmbedBuilder, AttachmentBuilder, ButtonBuilder, ActionRowBuilder, ButtonStyle } from 'discord.js';
|
|
||||||
import fetch from 'node-fetch';
|
|
||||||
import os from 'node:os';
|
|
||||||
import fs from 'node:fs';
|
|
||||||
import stream from 'node:stream';
|
|
||||||
import util from 'node:util';
|
|
||||||
|
|
||||||
import db from '../../models/index.js';
|
|
||||||
|
|
||||||
const { stableHordeApi, stableHordeID } = process.env;
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data: new SlashCommandBuilder()
|
|
||||||
.setName('txt2img')
|
|
||||||
.setDescription('AI generated image with stable diffusion (If credit are low it may be slow)')
|
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('prompt')
|
|
||||||
.setDescription('What do you want the AI to generate?')
|
|
||||||
.setRequired(true)),
|
|
||||||
category: 'AI',
|
|
||||||
alias: ['t2i'],
|
|
||||||
async execute(interaction, args, client) {
|
|
||||||
await interaction.deferReply();
|
|
||||||
generate(interaction, args.prompt, client);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
async function generate(i, prompt, client) {
|
|
||||||
const body = {
|
|
||||||
prompt: prompt,
|
|
||||||
params: {
|
|
||||||
n: 1,
|
|
||||||
width: 512,
|
|
||||||
height: 512,
|
|
||||||
},
|
|
||||||
cfg_scale: 9,
|
|
||||||
use_gfpgan: true,
|
|
||||||
use_real_esrgan: true,
|
|
||||||
use_ldsr: true,
|
|
||||||
use_upscaling: true,
|
|
||||||
steps: 50,
|
|
||||||
nsfw: i.channel.nsfw ? true : false,
|
|
||||||
censor_nsfw: i.channel.nsfw ? true : false,
|
|
||||||
shared: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const isOptOut = await db.optout.findOne({ where: { userID: i.user.id } });
|
|
||||||
|
|
||||||
if (isOptOut) {
|
|
||||||
body.shared = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchParameters = {
|
|
||||||
method: 'post',
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
headers: { 'Content-Type': 'application/json', 'apikey': stableHordeApi },
|
|
||||||
};
|
|
||||||
|
|
||||||
let response = await fetch('https://stablehorde.net/api/v2/generate/async', fetchParameters);
|
|
||||||
|
|
||||||
response = await response.json();
|
|
||||||
let wait_time = 5000;
|
|
||||||
let checkURL = `https://stablehorde.net/api/v2/generate/check/${response.id}`;
|
|
||||||
const checking = setInterval(async () => {
|
|
||||||
const checkResult = await checkGeneration(checkURL);
|
|
||||||
|
|
||||||
if (checkResult === undefined) return;
|
|
||||||
if (!checkResult.done) {
|
|
||||||
if (checkResult.wait_time < 0) {
|
|
||||||
clearInterval(checking);
|
|
||||||
return i.editReply({ content: 'No servers are currently available to fulfill your request, please try again later.' });
|
|
||||||
}
|
|
||||||
if (checkResult.wait_time === 0) {
|
|
||||||
checkURL = `https://stablehorde.net/api/v2/generate/status/${response.id}`;
|
|
||||||
}
|
|
||||||
wait_time = checkResult.wait_time;
|
|
||||||
}
|
|
||||||
else if (checkResult.done && checkResult.image) {
|
|
||||||
clearInterval(checking);
|
|
||||||
let creditResponse = await fetch(`https://stablehorde.net/api/v2/users/${stableHordeID}`);
|
|
||||||
creditResponse = await creditResponse.json();
|
|
||||||
|
|
||||||
const streamPipeline = util.promisify(stream.pipeline);
|
|
||||||
const res = await fetch(checkResult.image);
|
|
||||||
if (!res.ok) return i.editReply('An error has occured while trying to download your image.');
|
|
||||||
await streamPipeline(res.body, fs.createWriteStream(`${os.tmpdir()}/${i.id}.webp`));
|
|
||||||
|
|
||||||
const generatedImg = new AttachmentBuilder(`${os.tmpdir()}/${i.id}.webp`);
|
|
||||||
|
|
||||||
const stableEmbed = new EmbedBuilder()
|
|
||||||
.setColor(i.member ? i.member.displayHexColor : 'Navy')
|
|
||||||
.setTitle(prompt)
|
|
||||||
.setURL('https://aqualxx.github.io/stable-ui/')
|
|
||||||
.setImage(`attachment://${i.id}.webp`)
|
|
||||||
.setFooter({ text: `**Credit left: ${creditResponse.kudos}** Seed: ${checkResult.seed} worker ID: ${checkResult.worker_id} worker name: ${checkResult.worker_name}` });
|
|
||||||
|
|
||||||
const row = new ActionRowBuilder()
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`regenerate${i.user.id}${i.id}`)
|
|
||||||
.setLabel('🔄 Regenerate')
|
|
||||||
.setStyle(ButtonStyle.Primary),
|
|
||||||
);
|
|
||||||
|
|
||||||
await i.editReply({ embeds: [stableEmbed], components: [row], files: [generatedImg] });
|
|
||||||
|
|
||||||
listenButton(client, i, prompt);
|
|
||||||
}
|
|
||||||
}, wait_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkGeneration(url) {
|
|
||||||
let check = await fetch(url);
|
|
||||||
check = await check.json();
|
|
||||||
|
|
||||||
if (!check.is_possible) {
|
|
||||||
return { done: false, wait_time: -1 };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check.done) {
|
|
||||||
if (!check.generations) {
|
|
||||||
return { done: false, wait_time: check.wait_time * 1000 };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { done: true, image: check.generations[0].img, seed: check.generations[0].seed, worker_id: check.generations[0].worker_id, worker_name: check.generations[0].worker_name };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function listenButton(client, interaction, prompt) {
|
|
||||||
client.once('interactionCreate', async (interactionMenu) => {
|
|
||||||
if (!interactionMenu.isButton()) return;
|
|
||||||
|
|
||||||
await interactionMenu.update({ components: [] });
|
|
||||||
|
|
||||||
if (interactionMenu.customId === `regenerate${interactionMenu.user.id}${interaction.id}`) {
|
|
||||||
await interactionMenu.deferReply();
|
|
||||||
await generate(interactionMenu, prompt, client);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,62 +1,45 @@
|
|||||||
import { SlashCommandBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder, PermissionFlagsBits } from 'discord.js';
|
const { Command } = require('discord-akairo');
|
||||||
import db from '../../models/index.js';
|
const autoResponseStat = require('../../models').autoresponseStat;
|
||||||
|
|
||||||
export default {
|
class autoresponseCommand extends Command {
|
||||||
data: new SlashCommandBuilder()
|
constructor() {
|
||||||
.setName('autoresponse')
|
super('autoresponse', {
|
||||||
.setDescription('Enable or disable autoresponse')
|
aliases: ['autoresponse'],
|
||||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages),
|
|
||||||
category: 'admin',
|
category: 'admin',
|
||||||
async execute(interaction, args, client) {
|
args: [
|
||||||
const autoresponseStat = await db.autoresponseStat.findOne({ where: { serverID: interaction.guild.id } });
|
{
|
||||||
if (!autoresponseStat) {
|
id: 'stat',
|
||||||
const body = { serverID: interaction.guild.id, stat: 'enable' };
|
type: 'string',
|
||||||
await db.autoresponseStat.create(body);
|
prompt: {
|
||||||
return await interaction.reply({ content: 'Autoresponse has been enabled.', ephemeral: true });
|
start: 'Do you want to **enable** or **disable** auto response?',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const row = new ActionRowBuilder()
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`yes${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('Yes')
|
|
||||||
.setStyle(ButtonStyle.Primary),
|
|
||||||
)
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`no${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('No')
|
|
||||||
.setStyle(ButtonStyle.Danger),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (autoresponseStat.stat === 'enable') {
|
|
||||||
await interaction.reply({ content: 'Autoresponse is already enabled, do you wish to disable it?', components: [row], ephemeral: true });
|
|
||||||
}
|
}
|
||||||
else {
|
],
|
||||||
const body = { serverID: interaction.guild.id, stat: 'enable' };
|
clientPermissions: ['SEND_MESSAGES'],
|
||||||
await db.autoresponseStat.update(body, { where: { serverID: interaction.guild.id } });
|
userPermissions: ['MANAGE_MESSAGES'],
|
||||||
return interaction.editReply({ content: 'Auto response has been enabled.', ephemeral: true });
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'enable/disable autoresponse',
|
||||||
|
usage: '[enable/disable]',
|
||||||
|
examples: ['enable']
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return listenButton(client, interaction, interaction.user);
|
async exec(message, args) {
|
||||||
},
|
if (args.stat.toLowerCase() == 'enable' || args.stat.toLowerCase() == 'disable') {
|
||||||
};
|
const autoresponseStat = await autoResponseStat.findOne({where: {serverID: message.guild.id}});
|
||||||
|
|
||||||
async function listenButton(client, interaction, user = interaction.user, originalId = interaction.id) {
|
|
||||||
client.once('interactionCreate', async (interactionMenu) => {
|
|
||||||
if (user !== interactionMenu.user) return listenButton(client, interaction, user, originalId);
|
|
||||||
if (!interactionMenu.isButton()) return;
|
|
||||||
|
|
||||||
await interactionMenu.update({ components: [] });
|
|
||||||
|
|
||||||
if (interactionMenu.customId === `yes${interaction.user.id}${originalId}`) {
|
if (!autoresponseStat) {
|
||||||
const body = { serverID: interaction.guild.id, stat: 'disable' };
|
const body = {serverID: message.guild.id, stat: args.stat};
|
||||||
await db.autoresponseStat.update(body, { where: { serverID: interaction.guild.id } });
|
autoResponseStat.create(body);
|
||||||
return interaction.editReply({ content: 'Auto response has been disabled.', ephemeral: true });
|
return message.channel.send(`Autoresponse have been ${args.stat}d`);
|
||||||
|
} else {
|
||||||
|
const body = {serverID: message.guild.id, stat: args.stat};
|
||||||
|
autoResponseStat.update(body, {where: {serverID: message.guild.id}});
|
||||||
|
return message.channel.send(`Autoresponse have been ${args.stat}d`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return interaction.editReply({ content: 'Nothing has been changed.', ephemeral: true });
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
module.exports = autoresponseCommand;
|
@ -0,0 +1,70 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
|
||||||
|
class BanCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('ban', {
|
||||||
|
aliases: ['ban'],
|
||||||
|
category: 'admin',
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'which user do you want to ban?',
|
||||||
|
retry: 'This doesn\'t look like a user, please try again!'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'reasons',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'For what reasons?',
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
clientPermissions: ['BAN_MEMBERS', 'SEND_MESSAGES'],
|
||||||
|
userPermissions: ['BAN_MEMBERS'],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'Ban user | For hackban precise the userid',
|
||||||
|
usage: '[@user] [reason] OR [userID] [reason]',
|
||||||
|
examples: ['@user big dumb dumb', 'userID hackban']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let reasons = args.reasons;
|
||||||
|
let user = args.user;
|
||||||
|
if (message.mentions.members.first())
|
||||||
|
user = message.mentions.members.first().id;
|
||||||
|
|
||||||
|
if(user === this.client.user.id)
|
||||||
|
return message.channel.send('Can\'t ban me fool!');
|
||||||
|
if(!reasons)
|
||||||
|
reasons = 'Nothing have been specified';
|
||||||
|
if(user === message.author.id)
|
||||||
|
return message.channel.send('Why would you ban yourself ?');
|
||||||
|
|
||||||
|
if (message.mentions.members.first()) {
|
||||||
|
user = message.mentions.members.first();
|
||||||
|
await user.send(`You have been banned from **${message.guild.name}** for the following reasons: "**${reasons}**"`, {files: ['./asset/vid/You_Have_Been_Banned_From_Mickey_Mouse_Club.mp4']})
|
||||||
|
.catch(() => console.log('could not send message to the concerned user'));
|
||||||
|
|
||||||
|
return user.ban({reason: `Banned by : ${message.author.username} for the following reasons : ${reasons}`})
|
||||||
|
.then(() => message.reply(`${user.user.username} was succesfully banned with the following reasons "${reasons}".`))
|
||||||
|
//.catch(() => message.reply('Uh oh, an error has occurred! can the bot ban this user?'));
|
||||||
|
.catch(err => console.error(err));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
message.guild.members.ban(user, {reason: `Banned by : ${message.author.username} for the following reasons : ${reasons}`})
|
||||||
|
.then(() => message.reply(`user ID ${args.user} was succesfully hackbanned with the following reasons "${reasons}".`))
|
||||||
|
//.catch(() => message.reply('Uh oh, an error has occurred! can the bot ban this user?'));
|
||||||
|
.catch(err => console.error(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BanCommand;
|
@ -0,0 +1,71 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const safe = require('safe-regex');
|
||||||
|
const BannedWords = require('../../models').bannedWords;
|
||||||
|
|
||||||
|
class BannedWordsCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('BannedWords', {
|
||||||
|
aliases: ['bannedword', 'banword', 'unbanword', 'censor', 'uncensor', 'blacklistword', 'blacklist', 'unblacklist'],
|
||||||
|
category: 'admin',
|
||||||
|
userPermissions: ['MANAGE_MESSAGES'],
|
||||||
|
clientPermissions: ['MANAGE_MESSAGES', 'SEND_MESSAGES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'word',
|
||||||
|
type: 'string',
|
||||||
|
match: 'rest'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'remove',
|
||||||
|
match: 'flag',
|
||||||
|
flag: '--remove'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'removeall',
|
||||||
|
match: 'flag',
|
||||||
|
flag: '--removeall'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'Ban word on the server. use the unbanword alias to delete a banned word, unbanword alias and --removeaall to remove every banned word',
|
||||||
|
usage: '[word to ban]',
|
||||||
|
examples: ['owo']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
if (!safe(message.content)) return;
|
||||||
|
|
||||||
|
if (!args.word) args.word = '';
|
||||||
|
args.word = args.word.replace(/[\u0250-\ue007]/g, '');
|
||||||
|
const bannedWords = await BannedWords.findOne({where: {word: args.word.toLowerCase(), serverID: message.guild.id}});
|
||||||
|
|
||||||
|
if (message.util.parsed.alias == 'unbanword' || message.util.parsed.alias == 'uncensor' || message.util.parsed.alias == 'unblacklist' || args.remove || args.removeall) {
|
||||||
|
if (args.removeall) {
|
||||||
|
BannedWords.destroy({where: {serverID: message.guild.id}});
|
||||||
|
return message.channel.send('The banned words have been reset.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bannedWords) {
|
||||||
|
BannedWords.destroy({where: {word: args.word.toLowerCase(), serverID: message.guild.id}});
|
||||||
|
return message.channel.send(`The word ${args.word.toLowerCase()} is no longer banned`);
|
||||||
|
} else {
|
||||||
|
return message.channel.send('There was no word to unban');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args.word) return message.channel.send('Please specify a word to ban!');
|
||||||
|
|
||||||
|
if (!bannedWords) {
|
||||||
|
const body = {word: args.word.toLowerCase(), serverID: message.guild.id};
|
||||||
|
await BannedWords.create(body);
|
||||||
|
return message.channel.send(`The word ${args.word.toLowerCase()} has been banned`);
|
||||||
|
} else {
|
||||||
|
message.channel.send('This word is already banned');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BannedWordsCommand;
|
@ -1,74 +1,75 @@
|
|||||||
import { SlashCommandBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder, PermissionFlagsBits } from 'discord.js';
|
const { Command } = require('discord-akairo');
|
||||||
import db from '../../models/index.js';
|
const leaveChannel = require('../../models').leaveChannel;
|
||||||
|
|
||||||
export default {
|
class byeCommand extends Command {
|
||||||
data: new SlashCommandBuilder()
|
constructor() {
|
||||||
.setName('bye')
|
super('bye', {
|
||||||
.setDescription('Set a leave message')
|
aliases: ['bye', 'leave'],
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('message')
|
|
||||||
.setDescription('The message you want the bot to say when someone leave in the current channel.')),
|
|
||||||
category: 'admin',
|
category: 'admin',
|
||||||
userPermissions: [PermissionFlagsBits.ManageChannels],
|
channel: 'guild',
|
||||||
async execute(interaction, args, client) {
|
userPermissions: ['MANAGE_CHANNELS'],
|
||||||
const leave = await db.leaveChannel.findOne({ where: { guildID: interaction.guild.id } });
|
clientPermissions: ['SEND_MESSAGES'],
|
||||||
|
args: [
|
||||||
if (!leave && !args.message) {
|
{
|
||||||
return interaction.reply({ content: 'You need a message for me to say anything!', ephemeral: true });
|
id: 'remove',
|
||||||
|
match: 'flag',
|
||||||
|
flag: '--remove'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'message',
|
||||||
|
type: 'string',
|
||||||
|
match: 'rest',
|
||||||
|
default: '[member] just left the server :('
|
||||||
}
|
}
|
||||||
else if (!leave) {
|
],
|
||||||
const body = { guildID: interaction.guild.id, channelID: interaction.channel.id, message: args.message };
|
description: {
|
||||||
await db.leaveChannel.create(body);
|
content: 'Send a message to the current channel when a person leave, you can use [member] to show the member username and [server] to show the name of the server',
|
||||||
return interaction.reply({ content: `The leave message have been set with ${args.message}`, ephemeral: true });
|
usage: '[bye message]',
|
||||||
|
examples: ['[member] left the server, he deserve a ban']
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const row = new ActionRowBuilder()
|
async exec(message, args) {
|
||||||
.addComponents(
|
const leave = await leaveChannel.findOne({where: {guildID: message.guild.id}});
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`edit${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('Edit')
|
|
||||||
.setStyle(ButtonStyle.Primary),
|
|
||||||
)
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`remove${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('Remove')
|
|
||||||
.setStyle(ButtonStyle.Danger),
|
|
||||||
)
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`nothing${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('Do nothing')
|
|
||||||
.setStyle(ButtonStyle.Secondary),
|
|
||||||
);
|
|
||||||
|
|
||||||
await interaction.reply({ content: 'The server already has a message set, do you want to edit it or remove it?', components: [row], ephemeral: true });
|
|
||||||
|
|
||||||
return listenButton(client, interaction, args, interaction.user);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
async function listenButton(client, interaction, args, user = interaction.user, originalId = interaction.id) {
|
|
||||||
client.once('interactionCreate', async (interactionMenu) => {
|
|
||||||
if (user !== interactionMenu.user) return listenButton(client, interaction, args, user, originalId);
|
|
||||||
if (!interactionMenu.isButton()) return;
|
|
||||||
|
|
||||||
await interactionMenu.update({ components: [] });
|
if (args.remove) {
|
||||||
|
if (leave) {
|
||||||
|
leave.destroy({where: {guildID: message.guild.id, channelID: message.channel.id}});
|
||||||
|
return message.channel.send('successfully deleted the leave message');
|
||||||
|
} else {
|
||||||
|
return message.channel.send('Did not find the a leave message, are you sure you have one setup?');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (interactionMenu.customId === `edit${interaction.user.id}${originalId}`) {
|
|
||||||
if (!args.message) {
|
if (!args.message) {
|
||||||
return interaction.reply({ content: 'You need to input a message for me to edit!', ephemeral: true });
|
return message.channel.send('Please provide a message');
|
||||||
}
|
}
|
||||||
const body = { guildID: interaction.guild.id, channelID: interaction.channel.id, message: args.message };
|
|
||||||
await db.leaveChannel.update(body, { where: { guildID: interaction.guild.id } });
|
if (!leave) {
|
||||||
return interaction.editReply({ content: `The leave message has been set to ${args.message}`, ephemeral: true });
|
const body = {guildID: message.guild.id, channelID: message.channel.id, message: args.message};
|
||||||
|
await leaveChannel.create(body);
|
||||||
|
return message.channel.send(`The leave message have been set with ${args.message}`);
|
||||||
|
} else {
|
||||||
|
message.channel.send('The server already have a leave message, do you want to replace it? y/n');
|
||||||
|
const filter = m => m.content && m.author.id == message.author.id;
|
||||||
|
message.channel.awaitMessages(filter, {time: 5000, max: 1, errors: ['time'] })
|
||||||
|
.then(async messages => {
|
||||||
|
let messageContent = messages.map(messages => messages.content);
|
||||||
|
if (messageContent[0] === 'y' || messageContent[0] === 'yes') {
|
||||||
|
const body = {guildID: message.guild.id, channelID: message.channel.id, message: args.message};
|
||||||
|
await leaveChannel.update(body, {where: {guildID: message.guild.id}});
|
||||||
|
return message.channel.send(`The leave message have been set with ${args.message}`);
|
||||||
|
} else {
|
||||||
|
return message.channel.send('Not updating.');
|
||||||
}
|
}
|
||||||
else if (interactionMenu.customId === `remove${interaction.user.id}${originalId}`) {
|
})
|
||||||
db.leaveChannel.destroy({ where: { guildID: interaction.guild.id, channelID: interaction.channel.id } });
|
.catch(err => {
|
||||||
return interaction.editReply({ content: 'The leave message has been deleted.', ephemeral: true });
|
console.error(err);
|
||||||
|
return message.channel.send('Took too long to answer. didin\'t update anything.');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return interaction.editReply({ content: 'Nothing has been changed.', ephemeral: true });
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = byeCommand;
|
@ -0,0 +1,45 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const commandblock = require('../../models').commandBlock;
|
||||||
|
|
||||||
|
class commandblockCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('commandblock', {
|
||||||
|
aliases: ['commandblock', 'blockcommand'],
|
||||||
|
category: 'admin',
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'command',
|
||||||
|
type: 'command',
|
||||||
|
prompt: {
|
||||||
|
start: 'What command do you want to block?',
|
||||||
|
retry: 'Not a valid command, please try again'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
clientPermissions: ['SEND_MESSAGES'],
|
||||||
|
userPermissions: ['ADMINISTRATOR'],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'Block a command. Execute that command again to unblock a command',
|
||||||
|
usage: '[command name]',
|
||||||
|
examples: ['owned']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
if (args.command.id == 'commandblock') return message.channel.send('Whoa there, i can\'t let you block this command or else how would you unblock it?');
|
||||||
|
|
||||||
|
const blocked = await commandblock.findOne({where: {serverID: message.guild.id, command: args.command.id}});
|
||||||
|
|
||||||
|
if (!blocked) {
|
||||||
|
const body = {serverID: message.guild.id, command: args.command.id};
|
||||||
|
commandblock.create(body);
|
||||||
|
return message.channel.send(`Blocked command ${args.command.id}`);
|
||||||
|
} else {
|
||||||
|
commandblock.destroy({where: {serverID: message.guild.id, command: args.command.id}});
|
||||||
|
return message.channel.send(`The command ${args.command.id} has been unblocked`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = commandblockCommand;
|
@ -0,0 +1,52 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const commandblockuser = require('../../models').commandblockuser;
|
||||||
|
|
||||||
|
class commandblockuserCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('commandblockuser', {
|
||||||
|
aliases: ['commandblockuser', 'userblockcommand'],
|
||||||
|
category: 'admin',
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'command',
|
||||||
|
type: 'command',
|
||||||
|
prompt: {
|
||||||
|
start: 'What command do you want to block?',
|
||||||
|
retry: 'Not a valid command, please try again'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
type: 'user',
|
||||||
|
prompt: {
|
||||||
|
start: 'Which user you want to block?'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
clientPermissions: ['SEND_MESSAGES'],
|
||||||
|
userPermissions: ['ADMINISTRATOR'],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'Block a command from a user. Execute that command again to unblock a command',
|
||||||
|
usage: '[command name] [@user]',
|
||||||
|
examples: ['owned @supositware']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
if (args.command.id == 'commandblockuser') return message.channel.send('Whoa there, i can\'t let you block this command or else how would you unblock it?');
|
||||||
|
|
||||||
|
const blocked = await commandblockuser.findOne({where: {serverID: message.guild.id, userID: args.user.id, command: args.command.id}});
|
||||||
|
|
||||||
|
if (!blocked) {
|
||||||
|
const body = {serverID: message.guild.id, userID: args.user.id, command: args.command.id};
|
||||||
|
commandblockuser.create(body);
|
||||||
|
return message.channel.send(`Blocked command ${args.command.id}`);
|
||||||
|
} else {
|
||||||
|
commandblockuser.destroy({where: {serverID: message.guild.id, userID: args.user.id, command: args.command.id}});
|
||||||
|
return message.channel.send(`The command ${args.command.id} has been unblocked`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = commandblockuserCommand;
|
@ -0,0 +1,43 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const joinChannel = require('../../models').joinChannel;
|
||||||
|
|
||||||
|
class fakejoinCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('fakejoin', {
|
||||||
|
aliases: ['fakejoin'],
|
||||||
|
category: 'admin',
|
||||||
|
channel: 'guild',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
type: 'user',
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Fake join message',
|
||||||
|
usage: '[text]',
|
||||||
|
examples: ['Supositware']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let member;
|
||||||
|
const join = await joinChannel.findOne({where: {guildID: message.guild.id}});
|
||||||
|
|
||||||
|
if (join) {
|
||||||
|
if (args.user)
|
||||||
|
member = message.guild.members.resolve(args.user.id);
|
||||||
|
else
|
||||||
|
member = message.guild.members.resolve(message.author.id);
|
||||||
|
} else {
|
||||||
|
return message.reply('There is no join channel setup');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client.emit('guildMemberAdd', member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = fakejoinCommand;
|
@ -0,0 +1,43 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const leaveChannel = require('../../models').leaveChannel;
|
||||||
|
|
||||||
|
class fakeleaveCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('fakeleave', {
|
||||||
|
aliases: ['fakeleave'],
|
||||||
|
category: 'admin',
|
||||||
|
channel: 'guild',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
type: 'user',
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Fake leave message',
|
||||||
|
usage: '[user]',
|
||||||
|
examples: ['Supositware']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let member;
|
||||||
|
const leave = await leaveChannel.findOne({where: {guildID: message.guild.id}});
|
||||||
|
|
||||||
|
if (leave) {
|
||||||
|
if (args.user)
|
||||||
|
member = message.guild.members.resolve(args.user.id);
|
||||||
|
else
|
||||||
|
member = message.guild.members.resolve(message.author.id);
|
||||||
|
} else {
|
||||||
|
return message.reply('There is no leave channel setup');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client.emit('guildMemberRemove', member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = fakeleaveCommand;
|
@ -0,0 +1,57 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
|
||||||
|
class KickCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('kick', {
|
||||||
|
aliases: ['kick'],
|
||||||
|
category: 'admin',
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'member',
|
||||||
|
type: 'member',
|
||||||
|
prompt: {
|
||||||
|
start: 'which member do you want to ban?',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'reasons',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'For what reasons?',
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
clientPermissions: ['KICK_MEMBERS', 'SEND_MESSAGES'],
|
||||||
|
userPermissions: ['KICK_MEMBERS'],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'Kick user',
|
||||||
|
usage: '[@user] [reason]',
|
||||||
|
examples: ['@user big dumb dumb']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let member = args.member;
|
||||||
|
let reasons = args.reasons;
|
||||||
|
|
||||||
|
if(member === this.client.user)
|
||||||
|
return message.channel.send('Cant kick me fool');
|
||||||
|
if(member.id === message.author.id)
|
||||||
|
return message.channel.send('Why would you kick yourself ?');
|
||||||
|
if(!reasons)
|
||||||
|
reasons = 'Nothing have been specified.';
|
||||||
|
|
||||||
|
await member.send(`You have been kicked from **${message.guild.name}** for the following reasons: "**${reasons}**"`)
|
||||||
|
.catch(() => console.log('could not send message to the concerned user'));
|
||||||
|
|
||||||
|
return member.kick({reason: `Kicked by : ${message.author.username} for the following reasons: ${reasons}`})
|
||||||
|
.then(() => message.reply(`${member.user.username} was succesfully kicked with the following reasons "${reasons}".`))
|
||||||
|
.catch(err => console.error(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = KickCommand;
|
@ -0,0 +1,51 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const LogStats = require('../../models').LogStats;
|
||||||
|
|
||||||
|
class logCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('log', {
|
||||||
|
aliases: ['log', 'logging'],
|
||||||
|
category: 'admin',
|
||||||
|
userPermissions: ['MANAGE_MESSAGES'],
|
||||||
|
clientPermissions: ['MANAGE_GUILD'],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'Setup logging in current channel (W.I.P)',
|
||||||
|
usage: '',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
const logStats = await LogStats.findOne({where: {guild: message.guild.id}});
|
||||||
|
const ownerID = this.client.ownerID;
|
||||||
|
|
||||||
|
if (!logStats) {
|
||||||
|
const body = {guild: message.guild.id, channel: message.channel.id};
|
||||||
|
await LogStats.create(body);
|
||||||
|
return message.channel.send('Logging has been enabled on this channel');
|
||||||
|
} else if (logStats.get('ownerID') == message.author.id || message.member.hasPermission('ADMINISTRATOR') || message.author.id == ownerID) {
|
||||||
|
message.channel.send('The log channel is already setup, do you want to delete it? y/n');
|
||||||
|
const filter = m => m.content && m.author.id == message.author.id;
|
||||||
|
message.channel.awaitMessages(filter, {time: 5000, max: 1, errors: ['time'] })
|
||||||
|
.then(async messages => {
|
||||||
|
let messageContent = messages.map(messages => messages.content.toLowerCase());
|
||||||
|
if (messageContent[0] === 'y' || messageContent[0] === 'yes') {
|
||||||
|
await LogStats.destroy({where: {guild: message.guild.id}});
|
||||||
|
return message.channel.send('Log channel has been disabled!');
|
||||||
|
} else {
|
||||||
|
return message.channel.send('Not updating.');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
return message.channel.send('Took too long to answer. didin\'t change anything.');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return message.channel.send(`You are not the owner of this tag, if you think it is problematic ask an admin to remove it by doing ${this.client.commandHandler.prefix[0]}tag ${args.trigger} --remove`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = logCommand;
|
@ -0,0 +1,34 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
|
||||||
|
class PruneCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('Prune', {
|
||||||
|
aliases: ['Prune', 'clean', 'purge', 'clear'],
|
||||||
|
category: 'admin',
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'amount',
|
||||||
|
prompt: {
|
||||||
|
start: 'How many message should i delete?',
|
||||||
|
},
|
||||||
|
type: 'integer'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
clientPermissions: ['MANAGE_MESSAGES', 'SEND_MESSAGES'],
|
||||||
|
userPermissions: ['MANAGE_MESSAGES'],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'Bulk delete messages',
|
||||||
|
usage: '[amount]',
|
||||||
|
examples: ['50']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message,args) {
|
||||||
|
if (args.amount >= 100) return;
|
||||||
|
message.channel.bulkDelete(args.amount + 1, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = PruneCommand;
|
@ -1,62 +1,45 @@
|
|||||||
import { SlashCommandBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder, PermissionFlagsBits } from 'discord.js';
|
const { Command } = require('discord-akairo');
|
||||||
import db from '../../models/index.js';
|
const quotationStat = require('../../models').quotationStat;
|
||||||
|
|
||||||
export default {
|
class quotationCommand extends Command {
|
||||||
data: new SlashCommandBuilder()
|
constructor() {
|
||||||
.setName('quotation')
|
super('quotation', {
|
||||||
.setDescription('Enable or disable quotations')
|
aliases: ['quotation'],
|
||||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages),
|
|
||||||
category: 'admin',
|
category: 'admin',
|
||||||
async execute(interaction, args, client) {
|
args: [
|
||||||
const quotationstat = await db.quotationStat.findOne({ where: { serverID: interaction.guild.id } });
|
{
|
||||||
|
id: 'stat',
|
||||||
if (!quotationstat) {
|
type: 'string',
|
||||||
const body = { serverID: interaction.guild.id, stat: 'enable' };
|
prompt: {
|
||||||
await db.quotationStat.create(body);
|
start: 'Do you want to **enable** or **disable** quotation?',
|
||||||
return await interaction.reply({ content: 'Quotation has been enabled.', ephemeral: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const row = new ActionRowBuilder()
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`yes${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('Yes')
|
|
||||||
.setStyle(ButtonStyle.Primary),
|
|
||||||
)
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`no${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('No')
|
|
||||||
.setStyle(ButtonStyle.Danger),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (quotationstat.stat === 'enable') {
|
|
||||||
await interaction.reply({ content: 'Quotation is already enabled, do you wish to disable it?', components: [row], ephemeral: true });
|
|
||||||
}
|
}
|
||||||
else {
|
],
|
||||||
const body = { serverID: interaction.guild.id, stat: 'enable' };
|
clientPermissions: ['SEND_MESSAGES'],
|
||||||
await db.autoresponseStat.update(body, { where: { serverID: interaction.guild.id } });
|
userPermissions: ['MANAGE_MESSAGES'],
|
||||||
return interaction.editReply({ content: 'Quotation has been enabled.', ephemeral: true });
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'enable/disable quotation',
|
||||||
|
usage: '[enable/disable]',
|
||||||
|
examples: ['enable']
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return listenButton(client, interaction, interaction.user);
|
async exec(message, args) {
|
||||||
},
|
if (args.stat.toLowerCase() == 'enable' || args.stat.toLowerCase() == 'disable') {
|
||||||
};
|
const quotationstat = await quotationStat.findOne({where: {serverID: message.guild.id}});
|
||||||
|
|
||||||
async function listenButton(client, interaction, user = interaction.user, originalId = interaction.id) {
|
|
||||||
client.once('interactionCreate', async (interactionMenu) => {
|
|
||||||
if (user !== interactionMenu.user) return listenButton(client, interaction, user, originalId);
|
|
||||||
if (!interactionMenu.isButton()) return;
|
|
||||||
|
|
||||||
interactionMenu.update({ components: [] });
|
|
||||||
|
|
||||||
if (interactionMenu.customId === `yes${interaction.user.id}${originalId}`) {
|
if (!quotationstat) {
|
||||||
await db.quotationStat.destroy({ where: { serverID: interaction.guild.id } });
|
const body = {serverID: message.guild.id, stat: args.stat};
|
||||||
return interaction.editReply({ content: 'Quotation has been disabled.', ephemeral: true });
|
quotationStat.create(body);
|
||||||
|
return message.channel.send(`Quotation has been ${args.stat}d`);
|
||||||
|
} else {
|
||||||
|
const body = {serverID: message.guild.id, stat: args.stat};
|
||||||
|
quotationStat.update(body, {where: {serverID: message.guild.id}});
|
||||||
|
return message.channel.send(`Quotation has been ${args.stat}d`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return interaction.editReply({ content: 'Nothing has been changed.', ephemeral: true });
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
module.exports = quotationCommand;
|
@ -1,38 +1,66 @@
|
|||||||
import { SlashCommandBuilder, PermissionFlagsBits } from 'discord.js';
|
const { Command } = require('discord-akairo');
|
||||||
import fs from 'node:fs';
|
const fs = require('fs');
|
||||||
|
|
||||||
export default {
|
class shameboardCommand extends Command {
|
||||||
data: new SlashCommandBuilder()
|
constructor() {
|
||||||
.setName('shameboard')
|
super('shameboard', {
|
||||||
.setDescription('Set shameboard to the current channel.')
|
aliases: ['shameboard'],
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('emote')
|
|
||||||
.setDescription('The emote that should be used to enter the shameboard.'))
|
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('count')
|
|
||||||
.setDescription('How many react for it to enter shameboard.'))
|
|
||||||
.addBooleanOption(option =>
|
|
||||||
option.setName('remove')
|
|
||||||
.setDescription('Remove the shameboard')
|
|
||||||
.setRequired(false)),
|
|
||||||
category: 'admin',
|
category: 'admin',
|
||||||
userPermissions: [PermissionFlagsBits.ManageChannels],
|
channel: 'guild',
|
||||||
async execute(interaction, args) {
|
userPermissions: ['MANAGE_CHANNELS'],
|
||||||
if (args.remove) {
|
args: [
|
||||||
fs.unlink(`./json/board/shame${interaction.guild.id}.json`, (err) => {
|
{
|
||||||
if (err) {return interaction.reply('There is no shameboard');}
|
id: 'emote',
|
||||||
return interaction.reply('Deleted the shameboard');
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'What emote should be used to enter the shameboard?',
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
default: '👎',
|
||||||
|
unordered: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'count',
|
||||||
|
prompt: {
|
||||||
|
start: 'How many times should that emote be reacted to enter the shameboard?',
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
type: 'integer',
|
||||||
|
default: '4',
|
||||||
|
unordered: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'remove',
|
||||||
|
match: 'flag',
|
||||||
|
flag: '--remove'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Set shameobard in the current channel. --remove to remove the shameboard',
|
||||||
|
usage: '[emote] [minimum number required to enter shameboard]',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (!args.emote || !args.count) return interaction.reply('You are missing the emote or the count arg!');
|
async exec(message, args) {
|
||||||
fs.writeFile(`./json/board/shame${interaction.guild.id}.json`, `{"shameboard": "${interaction.channel.id}", "emote": "${args.emote}", "count": "${args.count}"}`, (err) => {
|
if (!args.remove) {
|
||||||
|
let shameboardChannel = message.channel.id;
|
||||||
|
|
||||||
|
fs.writeFile(`./board/shame${message.guild.id}.json`, `{"shameboard": "${shameboardChannel}" , "emote": "${args.emote}", "count": "${args.count}"}`, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return interaction.reply(`This channel have been set as the shameboard with ${args.emote} with the minimum of ${args.count}`);
|
return message.channel.send(`This channel have been set as the shameboard with ${args.emote} with the minimum of ${args.count}`);
|
||||||
|
} else {
|
||||||
|
fs.unlink(`./board/shame${message.guild.id}.json`, function (err) {
|
||||||
|
if (err) return message.channel.send('There is no shameboard');
|
||||||
|
return message.channel.send('Deleted the shameboard');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
module.exports = shameboardCommand;
|
@ -0,0 +1,65 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
|
||||||
|
class SlowmodeCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('Slowmode', {
|
||||||
|
aliases: ['slowmode', 'slow', 'cooldown'],
|
||||||
|
category: 'admin',
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'slowmodeNumber',
|
||||||
|
prompt: {
|
||||||
|
start: 'what do you want the delay to be between each message?',
|
||||||
|
},
|
||||||
|
type: 'integer'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'realtime',
|
||||||
|
prompt: {
|
||||||
|
start: 'For how long should the slowmode last?',
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
type: 'integer',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
clientPermissions: ['MANAGE_CHANNELS'],
|
||||||
|
userPermissions: ['MANAGE_MESSAGES'],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'Put a channel in slowmode',
|
||||||
|
usage: '[1-120 slowmode] [Number of minutes the slowmode stay active]',
|
||||||
|
examples: ['5 60']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message,args) {
|
||||||
|
try {
|
||||||
|
let slowmodeNumber = args.slowmodeNumber;
|
||||||
|
let realtime = args.realtime;
|
||||||
|
|
||||||
|
if (slowmodeNumber > 120)
|
||||||
|
return message.channel.send('Slowmode can only be set to 120 seconds or lower!');
|
||||||
|
|
||||||
|
message.channel.setRateLimitPerUser(slowmodeNumber);
|
||||||
|
|
||||||
|
if (realtime) {
|
||||||
|
let time = 60000 * realtime;
|
||||||
|
message.channel.send(`Slowmode have been set to ${slowmodeNumber} seconds and will end in ${realtime} minutes!`);
|
||||||
|
setTimeout (function (){
|
||||||
|
message.channel.setRateLimitPerUser(0);
|
||||||
|
return message.channel.send('Slowmode is now disabled!');
|
||||||
|
}, time);
|
||||||
|
} else {
|
||||||
|
if (slowmodeNumber == 0)
|
||||||
|
return message.channel.send('Slowmode have been disabled!');
|
||||||
|
return message.channel.send(`Slowmode have been set to ${slowmodeNumber} seconds!`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = SlowmodeCommand;
|
@ -1,38 +1,64 @@
|
|||||||
import { SlashCommandBuilder, PermissionFlagsBits } from 'discord.js';
|
const { Command } = require('discord-akairo');
|
||||||
import fs from 'node:fs';
|
const fs = require('fs');
|
||||||
|
|
||||||
export default {
|
class StarBoardCommand extends Command {
|
||||||
data: new SlashCommandBuilder()
|
constructor() {
|
||||||
.setName('starboard')
|
super('starboard', {
|
||||||
.setDescription('Set starboard to the current channel.')
|
aliases: ['starboard'],
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('emote')
|
|
||||||
.setDescription('The emote that should be used to enter the starboard.'))
|
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('count')
|
|
||||||
.setDescription('How many react for it to enter starboard.'))
|
|
||||||
.addBooleanOption(option =>
|
|
||||||
option.setName('remove')
|
|
||||||
.setDescription('Remove the starboard')
|
|
||||||
.setRequired(false)),
|
|
||||||
category: 'admin',
|
category: 'admin',
|
||||||
userPermissions: [PermissionFlagsBits.ManageChannels],
|
channel: 'guild',
|
||||||
async execute(interaction, args) {
|
userPermissions: ['MANAGE_CHANNELS'],
|
||||||
if (args.remove) {
|
args: [
|
||||||
fs.unlink(`./json/board/star${interaction.guild.id}.json`, (err) => {
|
{
|
||||||
if (err) {return interaction.reply('There is no starboard');}
|
id: 'emote',
|
||||||
return interaction.reply('Deleted the starboard');
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'What emote should be used to enter the shameboard?',
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
default: '👍',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'count',
|
||||||
|
type: 'integer',
|
||||||
|
prompt: {
|
||||||
|
start: 'How many times should that emote be reacted to enter the shameboard?',
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
default: '4',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'remove',
|
||||||
|
match: 'flag',
|
||||||
|
flag: '--remove'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Set starboard to the current channel. --remove to remove the starboard',
|
||||||
|
usage: '[emote] [minimum number required to enter starboard]',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (!args.emote || !args.count) return interaction.reply('You are missing the emote or the count arg!');
|
async exec(message, args) {
|
||||||
fs.writeFile(`./json/board/star${interaction.guild.id}.json`, `{"starboard": "${interaction.channel.id}", "emote": "${args.emote}", "count": "${args.count}"}`, (err) => {
|
if (!args.remove) {
|
||||||
|
let starboardChannel = message.channel.id;
|
||||||
|
|
||||||
|
fs.writeFile(`./board/star${message.guild.id}.json`, `{"starboard": "${starboardChannel}", "emote": "${args.emote}", "count": "${args.count}"}`, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return interaction.reply(`This channel have been set as the starboard with ${args.emote} with the minimum of ${args.count}`);
|
return message.channel.send(`This channel have been set as the starboard with ${args.emote} with the minimum of ${args.count}`);
|
||||||
|
} else {
|
||||||
|
fs.unlink(`./board/star${message.guild.id}.json`, function (err) {
|
||||||
|
if (err) return message.channel.send('There is no shameboard');
|
||||||
|
return message.channel.send('Deleted the starboard');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
module.exports = StarBoardCommand;
|
@ -1,127 +1,114 @@
|
|||||||
import { SlashCommandBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder, PermissionFlagsBits, PermissionsBitField } from 'discord.js';
|
const { Command } = require('discord-akairo');
|
||||||
import os from 'node:os';
|
const Tag = require('../../models').Tag;
|
||||||
import fs from 'node:fs';
|
|
||||||
|
|
||||||
import db from '../../models/index.js';
|
class TagCommand extends Command {
|
||||||
|
constructor() {
|
||||||
const { ownerId } = process.env;
|
super('tag', {
|
||||||
|
aliases: ['tag'],
|
||||||
export default {
|
|
||||||
data: new SlashCommandBuilder()
|
|
||||||
.setName('tag')
|
|
||||||
.setDescription('Create custom autoresponse')
|
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('trigger')
|
|
||||||
.setDescription('The strings that will trigger the tag')
|
|
||||||
.setRequired(false))
|
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('response')
|
|
||||||
.setDescription('What it will answer back')
|
|
||||||
.setRequired(false))
|
|
||||||
.addBooleanOption(option =>
|
|
||||||
option.setName('remove')
|
|
||||||
.setDescription('(ADMIN ONLY!) Remove the tag')
|
|
||||||
.setRequired(false))
|
|
||||||
.addBooleanOption(option =>
|
|
||||||
option.setName('list')
|
|
||||||
.setDescription('List all the tags for the server')
|
|
||||||
.setRequired(false)),
|
|
||||||
category: 'admin',
|
category: 'admin',
|
||||||
userPermissions: [PermissionFlagsBits.ManageChannels],
|
userPermissions: ['MANAGE_MESSAGES'],
|
||||||
async execute(interaction, args, client) {
|
args: [
|
||||||
await interaction.deferReply();
|
{
|
||||||
|
id: 'trigger',
|
||||||
if (args.list) {
|
type: 'string',
|
||||||
let tagList = await db.Tag.findAll({ attributes: ['trigger', 'response', 'ownerID'], where: { serverID: interaction.guild.id } });
|
},
|
||||||
|
{
|
||||||
if (args.trigger) {
|
id: 'remove',
|
||||||
tagList = await db.Tag.findOne({ attributes: ['trigger', 'response', 'ownerID'], where: { trigger: args.trigger, serverID: interaction.guild.id } });
|
match: 'flag',
|
||||||
|
flag: '--remove'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'reset',
|
||||||
|
match: 'flag',
|
||||||
|
flag: '--reset'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'response',
|
||||||
|
type: 'string',
|
||||||
|
match: 'rest',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'Create custom autoresponse (--remove to delete a tag, --reset to delete EVERY tag on the server) [Click here to see the complete list of "tag"](https://cdn.discordapp.com/attachments/502198809355354133/561043193949585418/unknown.png) (Need "" if the trigger contains spaces)',
|
||||||
|
usage: '[trigger] [response]',
|
||||||
|
examples: ['"do you know da wea" Fuck off dead meme', 'hello Hello [author], how are you today?', 'hello --remove']
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tagList) return interaction.editReply('It looks like the server has no tags.');
|
|
||||||
|
|
||||||
const path = `${os.tmpdir()}/${interaction.guild.id}.json`;
|
|
||||||
fs.writeFile(path, JSON.stringify(tagList, null, 2), function(err) {
|
|
||||||
if (err) return console.error(err);
|
|
||||||
});
|
});
|
||||||
return interaction.editReply({ files: [path] });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const tag = await db.Tag.findOne({ where: { trigger: args.trigger, serverID: interaction.guild.id } });
|
async exec(message, args) {
|
||||||
|
const tag = await Tag.findOne({where: {trigger: args.trigger, serverID: message.guild.id}});
|
||||||
if (args.remove) {
|
const ownerID = this.client.ownerID;
|
||||||
if (tag) {
|
|
||||||
if (tag.get('ownerID') == interaction.user.id || interaction.member.permissionsIn(interaction.channel).has(PermissionsBitField.Flags.Administrator) || interaction.user.id == ownerId) {
|
if (args.reset) {
|
||||||
db.Tag.destroy({ where: { trigger: args.trigger, serverID: interaction.guild.id } });
|
if (message.member.hasPermission('ADMINISTRATOR')) {
|
||||||
return interaction.editReply('successfully deleted the following tag: ' + args.trigger);
|
message.channel.send('Are you sure you want to delete EVERY tag? There is no way to recover them. y/n');
|
||||||
}
|
|
||||||
else {
|
const filter = m => m.content && m.author.id == message.author.id;
|
||||||
return interaction.editReply(`You are not the owner of this tag, if you think it is problematic ask a user with the 'Administrator' permission to remove it by doing ${this.client.commandHandler.prefix[0]}tag ${args.trigger} --remove`);
|
return message.channel.awaitMessages(filter, {time: 5000, max: 1, errors: ['time'] })
|
||||||
}
|
.then(async messages => {
|
||||||
|
let messageContent = messages.map(messages => messages.content.toLowerCase());
|
||||||
|
if (messageContent[0] === 'y' || messageContent[0] === 'yes') {
|
||||||
|
Tag.destroy({where: {serverID: message.guild.id}});
|
||||||
|
return message.channel.send('Tags have been reset.');
|
||||||
|
} else {
|
||||||
|
return message.channel.send('Not reseting.');
|
||||||
}
|
}
|
||||||
else {
|
})
|
||||||
return interaction.editReply('Did not find the specified tag, are you sure it exist?');
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
return message.channel.send('Took too long to answer. didin\'t update anything.');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return message.channel.send('Only person with the `ADMINISTRATOR` rank can reset tags.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.trigger) return interaction.editReply('You need to specify what you want me to respond to.');
|
if (args.remove) {
|
||||||
if (!args.response) return interaction.editReply('You need to specify what you want me to answer with.');
|
if (tag) {
|
||||||
|
if (tag.get('ownerID') == message.author.id || message.member.hasPermission('ADMINISTRATOR') || message.author.id == ownerID) {
|
||||||
if (!tag) {
|
Tag.destroy({where: {trigger: args.trigger, serverID: message.guild.id}});
|
||||||
const body = { trigger: args.trigger, response: args.response, ownerID: interaction.user.id, serverID: interaction.guild.id };
|
return message.channel.send('successfully deleted the following tag: ' + args.trigger);
|
||||||
await db.Tag.create(body);
|
} else {
|
||||||
return interaction.editReply(`tag have been set to ${args.trigger} : ${args.response}`);
|
return message.channel.send(`You are not the owner of this tag, if you think it is problematic ask an admin to remove it by doing ${this.client.commandHandler.prefix[0]}tag ${args.trigger} --remove`);
|
||||||
}
|
}
|
||||||
else if (tag.get('ownerID') == interaction.user.id || interaction.member.permissionsIn(interaction.channel).has('ADMINISTRATOR') || interaction.user.id == ownerId) {
|
} else {
|
||||||
|
return message.channel.send('Did not find the specified tag, are you sure it exist?');
|
||||||
const row = new ActionRowBuilder()
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`edit${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('Edit')
|
|
||||||
.setStyle(ButtonStyle.Primary),
|
|
||||||
)
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`remove${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('Remove')
|
|
||||||
.setStyle(ButtonStyle.Danger),
|
|
||||||
)
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`nothing${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('Do nothing')
|
|
||||||
.setStyle(ButtonStyle.Secondary),
|
|
||||||
);
|
|
||||||
|
|
||||||
await interaction.editReply({ content: 'This tag already exist, do you want to update it, remove it or do nothing?', components: [row], ephemeral: true });
|
|
||||||
|
|
||||||
return listenButton(client, interaction, args, interaction.user);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return interaction.editReply(`You are not the owner of this tag, if you think it is problematic ask an admin to remove it by doing ${this.client.commandHandler.prefix[0]}tag ${args.trigger} --remove`);
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
async function listenButton(client, interaction, args, user = interaction.user, originalId = interaction.id) {
|
|
||||||
client.once('interactionCreate', async (interactionMenu) => {
|
|
||||||
if (user !== interactionMenu.user) return listenButton(client, interaction, args, user, originalId);
|
|
||||||
if (!interactionMenu.isButton()) return;
|
|
||||||
|
|
||||||
await interactionMenu.update({ components: [] });
|
if (!args.trigger) return message.channel.send('Please provide a trigger in order to create a tag.');
|
||||||
|
|
||||||
if (interactionMenu.customId === `edit${interaction.user.id}${originalId}`) {
|
if (!args.response) return message.channel.send('Please provide the response for that tag');
|
||||||
const body = { trigger: args.trigger, response: args.response, ownerID: interaction.user.id, serverID: interaction.guild.id };
|
|
||||||
db.Tag.update(body, { where: { serverID: interaction.guild.id } });
|
if (!tag) {
|
||||||
return interaction.editReply({ content: `The tag ${args.trigger} has been set to ${args.response}`, ephemeral: true });
|
const body = {trigger: args.trigger, response: args.response, ownerID: message.author.id, serverID: message.guild.id};
|
||||||
|
await Tag.create(body);
|
||||||
|
return message.channel.send(`tag have been set to ${args.trigger} : ${args.response}`);
|
||||||
|
} else if (tag.get('ownerID') == message.author.id || message.member.hasPermission('ADMINISTRATOR') || message.author.id == ownerID) {
|
||||||
|
message.channel.send('This tag already exist, do you want to update it? y/n');
|
||||||
|
const filter = m => m.content && m.author.id == message.author.id;
|
||||||
|
message.channel.awaitMessages(filter, {time: 5000, max: 1, errors: ['time'] })
|
||||||
|
.then(async messages => {
|
||||||
|
let messageContent = messages.map(messages => messages.content.toLowerCase());
|
||||||
|
if (messageContent[0] === 'y' || messageContent[0] === 'yes') {
|
||||||
|
const body = {trigger: args.trigger, response: args.response, ownerID: message.author.id, serverID: message.guild.id};
|
||||||
|
await Tag.update(body, {where: {trigger: args.trigger, serverID: message.guild.id}});
|
||||||
|
return message.channel.send(`tag have been set to ${args.trigger} : ${args.response}`);
|
||||||
|
} else {
|
||||||
|
return message.channel.send('Not updating.');
|
||||||
}
|
}
|
||||||
else if (interactionMenu.customId === `remove${interaction.user.id}${originalId}`) {
|
})
|
||||||
db.Tag.destroy({ where: { trigger: args.trigger, serverID: interaction.guild.id } });
|
.catch(err => {
|
||||||
return interaction.editReply({ content: `The tag ${args.trigger} has been deleted`, ephemeral: true });
|
console.error(err);
|
||||||
|
return message.channel.send('Took too long to answer. didin\'t update anything.');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return message.channel.send(`You are not the owner of this tag, if you think it is problematic ask an admin to remove it by doing ${this.client.commandHandler.prefix[0]}tag ${args.trigger} --remove`);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return interaction.editReply({ content: 'Nothing has been changed.', ephemeral: true });
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = TagCommand;
|
@ -0,0 +1,40 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
|
||||||
|
class UnbanCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('unban', {
|
||||||
|
aliases: ['unban'],
|
||||||
|
category: 'admin',
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'member',
|
||||||
|
type: 'integer',
|
||||||
|
prompt: {
|
||||||
|
start: 'which member do you want to unban?',
|
||||||
|
retry: 'This doesn\'t look like an ID, please try again'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
clientPermissions: ['BAN_MEMBERS'],
|
||||||
|
userPermissions: ['BAN_MEMBERS'],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'unban users',
|
||||||
|
usage: '[user id]',
|
||||||
|
examples: ['267065637183029248']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
message.guild.members.unban(args.member.toString())
|
||||||
|
.then(() => {
|
||||||
|
return message.reply('user was succesfully unbanned.');
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
return message.reply('Could not unban this user, is he banned in the first place?');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = UnbanCommand;
|
@ -1,75 +1,74 @@
|
|||||||
import { SlashCommandBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder, PermissionFlagsBits } from 'discord.js';
|
const { Command } = require('discord-akairo');
|
||||||
import db from '../../models/index.js';
|
const joinChannel = require('../../models').joinChannel;
|
||||||
|
|
||||||
export default {
|
class welcomeCommand extends Command {
|
||||||
data: new SlashCommandBuilder()
|
constructor() {
|
||||||
.setName('welcome')
|
super('welcome', {
|
||||||
.setDescription('Set a join message')
|
aliases: ['welcome', 'join'],
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('message')
|
|
||||||
.setDescription('The message you want the bot to say when someone join in the current channel.')),
|
|
||||||
category: 'admin',
|
category: 'admin',
|
||||||
userPermissions: [PermissionFlagsBits.ManageChannels],
|
channel: 'guild',
|
||||||
async execute(interaction, args, client) {
|
userPermissions: ['MANAGE_CHANNELS'],
|
||||||
const join = await db.joinChannel.findOne({ where: { guildID: interaction.guild.id } });
|
args: [
|
||||||
|
{
|
||||||
if (!join && !args.message) {
|
id: 'remove',
|
||||||
return interaction.reply({ content: 'You need a message for me to say anything!', ephemeral: true });
|
match: 'flag',
|
||||||
|
flag: '--remove'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'message',
|
||||||
|
type: 'string',
|
||||||
|
match: 'rest',
|
||||||
|
default: 'Welcome [member] to [server]!'
|
||||||
}
|
}
|
||||||
else if (!join) {
|
],
|
||||||
const body = { guildID: interaction.guild.id, channelID: interaction.channel.id, message: args.message };
|
description: {
|
||||||
await db.joinChannel.create(body);
|
content: 'Send a message to the current channel when a person join, you can use [member] to show the member username and [server] to show the name of the server',
|
||||||
return interaction.reply({ content: `The join message have been set with ${args.message}`, ephemeral: true });
|
usage: '[welcome message]',
|
||||||
|
examples: ['everyone welcome [adjectives] [member] and welcome on [server]']
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
const join = await joinChannel.findOne({where: {guildID: message.guild.id}});
|
||||||
|
|
||||||
const row = new ActionRowBuilder()
|
if (args.remove) {
|
||||||
.addComponents(
|
if (join) {
|
||||||
new ButtonBuilder()
|
join.destroy({where: {guildID: message.guild.id, channelID: message.channel.id}});
|
||||||
.setCustomId(`edit${interaction.user.id}${interaction.id}`)
|
return message.channel.send('successfully deleted the join message');
|
||||||
.setLabel('Edit')
|
} else {
|
||||||
.setStyle(ButtonStyle.Primary),
|
return message.channel.send('Did not find the a join message, are you sure you have one setup?');
|
||||||
)
|
}
|
||||||
.addComponents(
|
}
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`remove${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('Remove')
|
|
||||||
.setStyle(ButtonStyle.Danger),
|
|
||||||
)
|
|
||||||
.addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`nothing${interaction.user.id}${interaction.id}`)
|
|
||||||
.setLabel('Do nothing')
|
|
||||||
.setStyle(ButtonStyle.Secondary),
|
|
||||||
);
|
|
||||||
|
|
||||||
await interaction.reply({ content: 'The server already has a message set, do you want to edit it or remove it?', components: [row], ephemeral: true });
|
|
||||||
|
|
||||||
return listenButton(client, interaction, args, interaction.user);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
async function listenButton(client, interaction, args, user = interaction.user, originalId = interaction.id) {
|
|
||||||
client.once('interactionCreate', async (interactionMenu) => {
|
|
||||||
if (user !== interactionMenu.user) return listenButton(client, interaction, args, user, originalId);
|
|
||||||
if (!interactionMenu.isButton()) return;
|
|
||||||
|
|
||||||
await interactionMenu.update({ components: [] });
|
|
||||||
|
|
||||||
if (interactionMenu.customId === `edit${interaction.user.id}${originalId}`) {
|
|
||||||
if (!args.message) {
|
if (!args.message) {
|
||||||
return interaction.reply({ content: 'You need to input a message for me to edit!', ephemeral: true });
|
return message.channel.send('Please provide a message');
|
||||||
}
|
}
|
||||||
const body = { guildID: interaction.guild.id, channelID: interaction.channel.id, message: args.message };
|
|
||||||
await db.joinChannel.update(body, { where: { guildID: interaction.guild.id } });
|
if (!join) {
|
||||||
return interaction.editReply({ content: `The join message has been set to ${args.message}`, ephemeral: true });
|
const body = {guildID: message.guild.id, channelID: message.channel.id, message: args.message};
|
||||||
|
await joinChannel.create(body);
|
||||||
|
return message.channel.send(`The join message have been set with ${args.message}`);
|
||||||
|
} else {
|
||||||
|
message.channel.send('The server already have a join message, do you want to replace it? y/n');
|
||||||
|
const filter = m => m.content && m.author.id == message.author.id;
|
||||||
|
message.channel.awaitMessages(filter, {time: 5000, max: 1, errors: ['time'] })
|
||||||
|
.then(async messages => {
|
||||||
|
let messageContent = messages.map(messages => messages.content);
|
||||||
|
if (messageContent[0] === 'y' || messageContent[0] === 'yes') {
|
||||||
|
const body = {guildID: message.guild.id, channelID: message.channel.id, message: args.message};
|
||||||
|
await joinChannel.update(body, {where: {guildID: message.guild.id}});
|
||||||
|
return message.channel.send(`The join message have been set with ${args.message}`);
|
||||||
|
} else {
|
||||||
|
return message.channel.send('Not updating.');
|
||||||
}
|
}
|
||||||
else if (interactionMenu.customId === `remove${interaction.user.id}${originalId}`) {
|
})
|
||||||
db.joinChannel.destroy({ where: { guildID: interaction.guild.id, channelID: interaction.channel.id } });
|
.catch(err => {
|
||||||
return interaction.editReply({ content: 'The join message has been deleted.', ephemeral: true });
|
console.error(err);
|
||||||
|
return message.channel.send('Took too long to answer. didin\'t update anything.');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return interaction.editReply({ content: 'Nothing has been changed.', ephemeral: true });
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = welcomeCommand;
|
@ -0,0 +1,68 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const whitelistWord = require('../../models').whitelistWord;
|
||||||
|
|
||||||
|
class whitelistWordCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('whitelistWord', {
|
||||||
|
aliases: ['whitelistWord', 'unwhitelistword', 'whitelist', 'unwhitelist'],
|
||||||
|
category: 'admin',
|
||||||
|
userPermissions: ['MANAGE_MESSAGES'],
|
||||||
|
clientPermissions: ['MANAGE_MESSAGES', 'SEND_MESSAGES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'word',
|
||||||
|
type: 'string',
|
||||||
|
match: 'rest'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'remove',
|
||||||
|
match: 'flag',
|
||||||
|
flag: '--remove'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'removeall',
|
||||||
|
match: 'flag',
|
||||||
|
flag: '--removeall'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'Whitelist word so it is not affected by the banned word, unwhitelistword alias and --removeaall to remove every banned whitelisted word',
|
||||||
|
usage: '[word to whitelist]',
|
||||||
|
examples: ['sexuality']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
if (!args.word) args.word = '';
|
||||||
|
args.word = args.word.replace(/[\u0250-\ue007]/g, '');
|
||||||
|
const WhitelistWord = await whitelistWord.findOne({where: {word: args.word.toLowerCase(), serverID: message.guild.id}});
|
||||||
|
|
||||||
|
if (message.util.parsed.alias == 'unwhitelistword' || message.util.parsed.alias == 'unwhitelist' || args.remove || args.removeall) {
|
||||||
|
if (args.removeall) {
|
||||||
|
whitelistWord.destroy({where: {serverID: message.guild.id}});
|
||||||
|
return message.channel.send('The whitelisted words has been reset.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WhitelistWord) {
|
||||||
|
whitelistWord.destroy({where: {word: args.word.toLowerCase(), serverID: message.guild.id}});
|
||||||
|
return message.channel.send(`The word ${args.word.toLowerCase()} is no longer whitelisted`);
|
||||||
|
} else {
|
||||||
|
return message.channel.send('There was no word to unwhitelist');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args.word) return message.channel.send('Please specify a word to whiteliste!');
|
||||||
|
|
||||||
|
if (!WhitelistWord) {
|
||||||
|
const body = {word: args.word.toLowerCase(), serverID: message.guild.id};
|
||||||
|
await whitelistWord.create(body);
|
||||||
|
return message.channel.send(`The word ${args.word.toLowerCase()} has been whitelisted`);
|
||||||
|
} else {
|
||||||
|
message.channel.send('This word is already whitelisted');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = whitelistWordCommand;
|
@ -0,0 +1,58 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const attachment = require('../../utils/attachment');
|
||||||
|
const os = require('os');
|
||||||
|
const fs = require('fs');
|
||||||
|
const asciify = require('asciify-image');
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
fit: 'box',
|
||||||
|
width: 200,
|
||||||
|
height: 50,
|
||||||
|
color: false
|
||||||
|
};
|
||||||
|
|
||||||
|
class asciifyCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('asciify', {
|
||||||
|
aliases: ['asciify'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'link',
|
||||||
|
type: 'url',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
cooldown: 600000,
|
||||||
|
ratelimit: 2,
|
||||||
|
description: {
|
||||||
|
content: 'Transform your image into ASCII! (This can be a bit spammy, so be careful!)',
|
||||||
|
usage: '[image in attachment]',
|
||||||
|
examples: ['image in attachment']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let url;
|
||||||
|
|
||||||
|
if (args.link)
|
||||||
|
url = args.link.href;
|
||||||
|
else
|
||||||
|
url = await attachment(message);
|
||||||
|
|
||||||
|
return asciify(url, options, function (err, asciified) {
|
||||||
|
if (err) throw err;
|
||||||
|
// Print to console
|
||||||
|
fs.writeFile(`${os.tmpdir()}/${message.id}ascii.txt`, asciified, function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return message.channel.send({files: [`${os.tmpdir()}/${message.id}ascii.txt`]});
|
||||||
|
});
|
||||||
|
//return message.channel.send(asciified, { split: true, code: true });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = asciifyCommand;
|
@ -1,60 +1,91 @@
|
|||||||
/* TODO
|
const { Command } = require('discord-akairo');
|
||||||
*
|
const attachment = require('../../utils/attachment');
|
||||||
* Merge with commands/fun/image2audio.js
|
const ffmpeg = require('fluent-ffmpeg');
|
||||||
*
|
const fetch = require('node-fetch');
|
||||||
*/
|
const fs = require('fs');
|
||||||
import { SlashCommandBuilder } from 'discord.js';
|
const os = require('os');
|
||||||
import fs from 'node:fs';
|
|
||||||
import os from 'node:os';
|
|
||||||
import fetch from 'node-fetch';
|
|
||||||
import util from 'node:util';
|
|
||||||
import stream from 'node:stream';
|
|
||||||
import utils from '../../utils/videos.js';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data: new SlashCommandBuilder()
|
|
||||||
.setName('audio2image')
|
|
||||||
.setDescription('Transform an audio file into an image.')
|
|
||||||
.addAttachmentOption(option =>
|
|
||||||
option.setName('audio')
|
|
||||||
.setDescription('The audio that will become image.')
|
|
||||||
.setRequired(true)),
|
|
||||||
category: 'fun',
|
|
||||||
alias: ['a2i'],
|
|
||||||
async execute(interaction, args) {
|
|
||||||
if (!args.audio) return interaction.reply('Please attach an image with your message.');
|
|
||||||
|
|
||||||
await interaction.deferReply();
|
class audio2imageCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('audio2image', {
|
||||||
|
aliases: ['audio2image', 'a2i'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'video_size',
|
||||||
|
match: 'option',
|
||||||
|
flag: '--size',
|
||||||
|
default: '640x480'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'link',
|
||||||
|
type: 'url',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Transform an audio file into an image.Use --size (a number) to get a bigger image! (NOTE: bigger image might fail, so be careful!)',
|
||||||
|
usage: '[link to audio] [--size anumber]',
|
||||||
|
examples: ['https://cdn.discordapp.com/attachments/532987690145021982/682654351772221480/jeff.wav (optional) --size 1920x1080']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ifExistDelete(`${os.tmpdir()}/${args.audio.name}`);
|
async exec(message, args) {
|
||||||
ifExistDelete(`${os.tmpdir()}/${args.audio.name}.png`);
|
let url;
|
||||||
ifExistDelete(`${os.tmpdir()}/${args.audio.name}.sw`);
|
|
||||||
ifExistDelete(`${os.tmpdir()}/${args.audio.name}.mp3`);
|
|
||||||
|
|
||||||
const streamPipeline = util.promisify(stream.pipeline);
|
if (args.link)
|
||||||
const res = await fetch(args.audio.url);
|
url = args.link.href;
|
||||||
if (!res.ok) return interaction.editReply('An error has occured while trying to download your image.');
|
else
|
||||||
await streamPipeline(res.body, fs.createWriteStream(`${os.tmpdir()}/${args.audio.name}`));
|
url = await attachment(message);
|
||||||
|
|
||||||
await utils.ffmpeg(['-i', `${os.tmpdir()}/${args.audio.name}`, '-sample_rate', '44100', '-ac', '1', '-f', 's16le', '-acodec', 'pcm_s16le', `${os.tmpdir()}/${args.audio.name}.sw`]);
|
let loadingmsg = await message.channel.send('Processing <a:loadingmin:527579785212329984>');
|
||||||
await utils.ffmpeg(['-pixel_format', 'rgb24', '-video_size', '128x128', '-f', 'rawvideo', '-i', `${os.tmpdir()}/${args.audio.name}.sw`, '-frames:v', '1', `${os.tmpdir()}/${args.audio.name}.png`]);
|
|
||||||
|
|
||||||
const file = fs.statSync(`${os.tmpdir()}/${args.audio.name}.png`);
|
if (!url) return message.channel.send('Please attach an audio file or use an url');
|
||||||
const fileSize = (file.size / 1000000.0).toFixed(2);
|
|
||||||
|
|
||||||
if (fileSize > await utils.getMaxFileSize(interaction.guild)) return interaction.editReply('error');
|
fetch(url)
|
||||||
interaction.editReply({ content: `Image file is ${fileSize} MB` });
|
.then(res => {
|
||||||
return interaction.followUp({ files: [`${os.tmpdir()}/${args.audio.name}.png`] });
|
const dest = fs.createWriteStream(`${os.tmpdir()}/${message.id}`);
|
||||||
},
|
res.body.pipe(dest);
|
||||||
};
|
dest.on('finish', () => {
|
||||||
|
ffmpeg(`${os.tmpdir()}/${message.id}`) // Convert to raw pcm
|
||||||
async function ifExistDelete(path) {
|
.audioBitrate(44100)
|
||||||
if (fs.existsSync(path)) {
|
.audioChannels(1)
|
||||||
fs.rm(path, (err) => {
|
.format('s16le')
|
||||||
console.log('deleted');
|
.audioCodec('pcm_s16le')
|
||||||
if (err) {
|
.output(`${os.tmpdir()}/${message.id}1.sw`)
|
||||||
return;
|
.on('error', (err, stdout, stderr) => {
|
||||||
}
|
console.error(`${err}\n${stdout}\n${stderr}`);
|
||||||
|
return message.channel.send('Uh oh, an error has occurred!');
|
||||||
|
})
|
||||||
|
.on('end', () => {
|
||||||
|
ffmpeg()
|
||||||
|
.input(`${os.tmpdir()}/${message.id}1.sw`)
|
||||||
|
.inputOption('-pixel_format rgb24')
|
||||||
|
.inputOption(`-video_size ${args.video_size}`)
|
||||||
|
.inputFormat('rawvideo')
|
||||||
|
.frames('1')
|
||||||
|
.output(`${os.tmpdir()}/a2i${message.id}.png`)
|
||||||
|
.on('error', (err, stdout, stderr) => {
|
||||||
|
console.error(`${err}\n${stdout}\n${stderr}`);
|
||||||
|
return message.channel.send('Uh oh, an error has occurred! The image size is most likely bigger than the content! Try again!');
|
||||||
|
})
|
||||||
|
.on('end', () => {
|
||||||
|
console.log('finished');
|
||||||
|
loadingmsg.delete();
|
||||||
|
let file = fs.statSync(`${os.tmpdir()}/a2i${message.id}.png`);
|
||||||
|
let fileSize = (file.size / 1000000.0).toFixed(2);
|
||||||
|
return message.channel.send(`Image is ${fileSize} MB for ${args.video_size} resolution`, {files: [`${os.tmpdir()}/a2i${message.id}.png`]})
|
||||||
|
.catch(() => {
|
||||||
|
return message.channel.send(`End result is too big to fit on discord! File is ${fileSize} MB! Unless it's GB or even TB, in which case that is a huge image!`); });
|
||||||
|
})
|
||||||
|
.run();
|
||||||
|
})
|
||||||
|
.run();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = audio2imageCommand;
|
@ -0,0 +1,55 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const cleverbot = require('cleverbot-free');
|
||||||
|
let conversation = {};
|
||||||
|
|
||||||
|
class CleverBotCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('CleverBot', {
|
||||||
|
aliases: ['CleverBot', 'cb'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'message',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'What do you want to say to cleverbot?'
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Talk to cleverbot!',
|
||||||
|
usage: '[message]',
|
||||||
|
examples: ['Hello']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let loadingmsg = await message.reply('Processing! <a:loadingmin:527579785212329984>');
|
||||||
|
if (!conversation[message.guild.id]) conversation[message.guild.id] = [];
|
||||||
|
|
||||||
|
if (!conversation[0]) {
|
||||||
|
cleverbot(args.message).then(response => {
|
||||||
|
conversation[message.guild.id].push(args.message);
|
||||||
|
conversation[message.guild.id].push(response);
|
||||||
|
return message.reply(response)
|
||||||
|
.then(() => {
|
||||||
|
loadingmsg.delete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cleverbot(args.message, conversation[message.guild.id]).then(response => {
|
||||||
|
conversation[message.guild.id].push(args.message);
|
||||||
|
conversation[message.guild.id].push(response);
|
||||||
|
return message.reply(response)
|
||||||
|
.then(() => {
|
||||||
|
loadingmsg.delete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log(conversation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = CleverBotCommand;
|
@ -0,0 +1,95 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const path = require('path');
|
||||||
|
const os = require('os');
|
||||||
|
const fs = require('fs');
|
||||||
|
const { Buffer } = require('buffer');
|
||||||
|
const attachment = require('../../utils/attachment');
|
||||||
|
const downloader = require('../../utils/download');
|
||||||
|
|
||||||
|
class cursesCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('curses', {
|
||||||
|
aliases: ['curses', 'curse'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'link',
|
||||||
|
type: 'url',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'webm',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--webm']
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Mess with video length. webm = expanding length and mp4 = very long length',
|
||||||
|
usage: '[link or attachment]',
|
||||||
|
examples: ['https://www.youtube.com/watch?v=QLCPgZ51poU']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let replaceAt = function(string, index, replacement) {
|
||||||
|
return string.substr(0, index) + replacement + string.substr(index + replacement.length);
|
||||||
|
};
|
||||||
|
|
||||||
|
let link;
|
||||||
|
if (args.link)
|
||||||
|
link = args.link.href;
|
||||||
|
else
|
||||||
|
link = await attachment(message);
|
||||||
|
|
||||||
|
if (!link) return message.channel.send('Please specify the URL of the video you want to curse.');
|
||||||
|
|
||||||
|
let ext = path.extname(link.toLowerCase());
|
||||||
|
console.log(ext);
|
||||||
|
if (ext !== '.webm' && ext !== '.mp4')
|
||||||
|
ext = '.mp4';
|
||||||
|
|
||||||
|
|
||||||
|
if (args.webm) ext = '.webm';
|
||||||
|
|
||||||
|
let loadingmsg = await message.channel.send('Processing <a:loadingmin:527579785212329984>');
|
||||||
|
downloader(link, [`--format=${ext.replace('.', '')}`], `${os.tmpdir()}/${message.id}${ext}`)
|
||||||
|
.on('error', async err => {
|
||||||
|
loadingmsg.delete();
|
||||||
|
console.error(err);
|
||||||
|
return message.channel.send(err, { code: true });
|
||||||
|
})
|
||||||
|
.on('end', output => {
|
||||||
|
let file = fs.readFileSync(output).toString('hex');
|
||||||
|
|
||||||
|
let searchHex = '6d766864';
|
||||||
|
let replaceHex = '0000180FFFFFF7F';
|
||||||
|
let skipByte = 34;
|
||||||
|
|
||||||
|
let endResult;
|
||||||
|
|
||||||
|
if (ext === '.webm') {
|
||||||
|
searchHex = '2ad7b1';
|
||||||
|
replaceHex = '42FFB060';
|
||||||
|
skipByte = 8;
|
||||||
|
|
||||||
|
endResult = replaceAt(file, file.indexOf(searchHex) + file.substring(file.indexOf(searchHex)).indexOf('4489') + skipByte, replaceHex);
|
||||||
|
} else {
|
||||||
|
endResult = replaceAt(file, file.indexOf(searchHex) + skipByte, replaceHex);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(`${os.tmpdir()}/cursed${message.id}${ext}`, Buffer.from(endResult, 'hex'));
|
||||||
|
message.delete();
|
||||||
|
return message.channel.send(`Cursed by ${message.author}`, {files: [`${os.tmpdir()}/cursed${message.id}${ext}`]})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
return message.channel.send('Video is too big! try again with something smaller');
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
loadingmsg.delete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = cursesCommand;
|
@ -0,0 +1,29 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const fs = require('fs');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
|
class dosentexistCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('dosentexist', {
|
||||||
|
aliases: ['doesntexist', 'thispersondoesnotexist', 'de'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
description: {
|
||||||
|
content: 'Send images from thispersondoesnotexist.com!',
|
||||||
|
usage: '',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message) {
|
||||||
|
fetch('https://thispersondoesnotexist.com/image')
|
||||||
|
.then(res => {
|
||||||
|
const dest = fs.createWriteStream('./asset/img/de.png');
|
||||||
|
res.body.pipe(dest);
|
||||||
|
dest.on('finish', () => {
|
||||||
|
return message.reply({files: ['./asset/img/de.png']});
|
||||||
|
});
|
||||||
|
}); }
|
||||||
|
}
|
||||||
|
module.exports = dosentexistCommand;
|
@ -0,0 +1,25 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const extract = require('meta-extractor');
|
||||||
|
|
||||||
|
class explosmCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('explosm', {
|
||||||
|
aliases: ['explosm', 'rcg'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
description: {
|
||||||
|
content: 'Comic randomly generated from http://explosm.net/rcg',
|
||||||
|
usage: '',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message) {
|
||||||
|
extract({ uri: 'http://explosm.net/rcg' }, (err, res) => {
|
||||||
|
return message.reply({files: [res.ogImage]});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
module.exports = explosmCommand;
|
@ -0,0 +1,76 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
|
||||||
|
class fakebotCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('fakebot', {
|
||||||
|
aliases: ['fakebot', 'fakeuser', 'fakemember'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['MANAGE_WEBHOOKS'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
type: 'user',
|
||||||
|
prompt: {
|
||||||
|
start: 'Who should i fake?',
|
||||||
|
retry: 'Didn\'t find any user named like that, please say the name again.'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'message',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'What message should i send?',
|
||||||
|
},
|
||||||
|
match: 'rest',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
channel: 'guild',
|
||||||
|
description: {
|
||||||
|
content: 'Fake a bot/user with webhook',
|
||||||
|
usage: '[user] [message]',
|
||||||
|
examples: ['Supositware#1616 hello!']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let Attachment = (message.attachments).array();
|
||||||
|
let url;
|
||||||
|
let username = args.user.username;
|
||||||
|
let member = message.guild.members.resolve(args.user.id);
|
||||||
|
// Get attachment link
|
||||||
|
if (Attachment[0]) {
|
||||||
|
url = Attachment[0].url;
|
||||||
|
}
|
||||||
|
// Show nickname if user is in guild
|
||||||
|
if (member) {
|
||||||
|
if (member.nickname) {
|
||||||
|
username = member.nickname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message.channel.createWebhook(username, {
|
||||||
|
avatar: args.user.displayAvatarURL(),
|
||||||
|
reason: `Fakebot/user command triggered by: ${message.author.username}`
|
||||||
|
})
|
||||||
|
.then(webhook => {
|
||||||
|
// Have to edit after creation otherwise the picture doesn't get applied
|
||||||
|
webhook.edit({
|
||||||
|
name: username,
|
||||||
|
avatar: args.user.displayAvatarURL(),
|
||||||
|
reason: `Fakebot/user command triggered by: ${message.author.username}`
|
||||||
|
});
|
||||||
|
this.client.fetchWebhook(webhook.id, webhook.token)
|
||||||
|
.then(webhook => {
|
||||||
|
message.delete();
|
||||||
|
|
||||||
|
if (url)
|
||||||
|
webhook.send(args.message, {files: [url]});
|
||||||
|
else
|
||||||
|
webhook.send(args.message);
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = fakebotCommand;
|
@ -1,49 +0,0 @@
|
|||||||
import { SlashCommandBuilder } from 'discord.js';
|
|
||||||
import { PermissionFlagsBits } from 'discord.js';
|
|
||||||
export default {
|
|
||||||
data: new SlashCommandBuilder()
|
|
||||||
.setName('fakeuser')
|
|
||||||
.setDescription('Fake a user with webhooks')
|
|
||||||
.addMentionableOption(option =>
|
|
||||||
option.setName('user')
|
|
||||||
.setDescription('Who do you want to fake?')
|
|
||||||
.setRequired(true))
|
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('message')
|
|
||||||
.setDescription('What message do you want me to send?')
|
|
||||||
.setRequired(true))
|
|
||||||
.addAttachmentOption(option =>
|
|
||||||
option.setName('image')
|
|
||||||
.setDescription('Optional attachment.')
|
|
||||||
.setRequired(false)),
|
|
||||||
category: 'fun',
|
|
||||||
clientPermissions: [ PermissionFlagsBits.ManageWebhooks ],
|
|
||||||
async execute(interaction, args) {
|
|
||||||
await interaction.deferReply({ ephemeral: true });
|
|
||||||
await interaction.guild.members.fetch();
|
|
||||||
const member = args.user;
|
|
||||||
const message = args.message;
|
|
||||||
const attachment = args.image;
|
|
||||||
const username = member.nickname ? member.nickname : member.user.username;
|
|
||||||
|
|
||||||
const webhook = await interaction.channel.createWebhook({
|
|
||||||
name: username,
|
|
||||||
avatar: member.user.displayAvatarURL(),
|
|
||||||
reason: `Fakebot/user command triggered by: ${interaction.user.username}`,
|
|
||||||
});
|
|
||||||
if (attachment) {
|
|
||||||
await webhook.send({ content: message, files: [attachment] });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
await webhook.send({ content: message });
|
|
||||||
}
|
|
||||||
await webhook.delete(`Fakebot/user command triggered by: ${interaction.user.username}`);
|
|
||||||
if (interaction.isMessage) {
|
|
||||||
await interaction.delete();
|
|
||||||
await interaction.deleteReply();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
await interaction.editReply({ content: `Faked the user ${member}` });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
@ -1,93 +0,0 @@
|
|||||||
// Tried something to make it work purely with slash commands but it did not work.
|
|
||||||
// The interaction created from a modal lack the showModal function so I can't just call another modal on top
|
|
||||||
// A "solution" for this that I could see is creating a button between each response asking the player to continue or stop which would create a new interaction and (maybe) allow to display a new modal
|
|
||||||
import { SlashCommandBuilder, ActionRowBuilder, TextInputBuilder, SelectMenuBuilder, ModalBuilder, TextInputStyle, InteractionType } from 'discord.js';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data: new SlashCommandBuilder()
|
|
||||||
.setName('guess')
|
|
||||||
.setDescription('Guess the number'),
|
|
||||||
category: 'fun',
|
|
||||||
async execute(interaction, args, client) {
|
|
||||||
const row = new ActionRowBuilder()
|
|
||||||
.addComponents(
|
|
||||||
new SelectMenuBuilder()
|
|
||||||
.setCustomId('difficulty')
|
|
||||||
.setPlaceholder('Nothing selected')
|
|
||||||
.addOptions([
|
|
||||||
{ label: 'Easy', value: '100' },
|
|
||||||
{ label: 'Normal', value: '1000' },
|
|
||||||
{ label: 'Hard', value: '10000' },
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
await interaction.reply({ content: 'Which difficulty do you want to play?', ephemeral: true, components: [row] });
|
|
||||||
|
|
||||||
let numberTry = 0;
|
|
||||||
let secretnumber = 0;
|
|
||||||
|
|
||||||
client.on('interactionCreate', async (interactionMenu) => {
|
|
||||||
if (interaction.user !== interactionMenu.user) return;
|
|
||||||
|
|
||||||
const modal = new ModalBuilder()
|
|
||||||
.setCustomId('guessModal')
|
|
||||||
.setTitle('Your guess');
|
|
||||||
|
|
||||||
|
|
||||||
const textRow = new ActionRowBuilder()
|
|
||||||
.addComponents(
|
|
||||||
new TextInputBuilder()
|
|
||||||
.setCustomId('input')
|
|
||||||
.setLabel('What is the number?')
|
|
||||||
.setStyle(TextInputStyle.Short),
|
|
||||||
);
|
|
||||||
|
|
||||||
modal.addComponents(textRow);
|
|
||||||
|
|
||||||
async function tryAgain(input) {
|
|
||||||
if (input != secretnumber) {
|
|
||||||
if (input > secretnumber) {
|
|
||||||
modal.setTitle('Its less!\nWhat is the number?');
|
|
||||||
}
|
|
||||||
else if (input < secretnumber) {
|
|
||||||
modal.setTitle('Its more!\nWhat is the number?');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await interactionMenu.showModal(modal);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkNumber(input) {
|
|
||||||
numberTry++;
|
|
||||||
if (input.toLowerCase() === 'stop') {
|
|
||||||
return interaction.reply('Ok, let\'s stop playing :(');
|
|
||||||
}
|
|
||||||
else if (input != secretnumber) {
|
|
||||||
console.log('trying again');
|
|
||||||
tryAgain(input);
|
|
||||||
}
|
|
||||||
else if (numberTry > 1) {
|
|
||||||
return interaction.reply(`Congratulations! You won! It took you ${numberTry} turns!`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return interaction.reply('Congratulations! You won! It took you 1 Turn!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interactionMenu.type === InteractionType.ModalSubmit) {
|
|
||||||
if (interactionMenu.customId === 'guessModal') {
|
|
||||||
const input = interactionMenu.fields.getTextInputValue('input');
|
|
||||||
checkNumber(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (interactionMenu.isSelectMenu()) {
|
|
||||||
if (interactionMenu.customId === 'difficulty') {
|
|
||||||
secretnumber = Math.floor((Math.random() * parseInt(interactionMenu.values[0])) + 1);
|
|
||||||
console.log(secretnumber);
|
|
||||||
|
|
||||||
// await interaction.followUp({ content: 'What is the number?', ephemeral: true });
|
|
||||||
await interactionMenu.showModal(modal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
@ -0,0 +1,24 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
|
class InspiroBotCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('InspiroBot', {
|
||||||
|
aliases: ['inspirobot', 'ib'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
description: {
|
||||||
|
content: 'Send images from Inspirobot',
|
||||||
|
usage: '',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message) {
|
||||||
|
fetch('http://inspirobot.me/api?generate=true')
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(body => message.channel.send({files: [body]}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = InspiroBotCommand;
|
@ -1,59 +1,87 @@
|
|||||||
/* TODO
|
const { Command } = require('discord-akairo');
|
||||||
*
|
const attachment = require('../../utils/attachment');
|
||||||
* Merge with commands/fun/audio2image.js
|
const ffmpeg = require('fluent-ffmpeg');
|
||||||
*
|
const fetch = require('node-fetch');
|
||||||
*/
|
const fs = require('fs');
|
||||||
import { SlashCommandBuilder } from 'discord.js';
|
const os = require('os');
|
||||||
import fs from 'node:fs';
|
|
||||||
import os from 'node:os';
|
|
||||||
import fetch from 'node-fetch';
|
|
||||||
import util from 'node:util';
|
|
||||||
import stream from 'node:stream';
|
|
||||||
import utils from '../../utils/videos.js';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data: new SlashCommandBuilder()
|
|
||||||
.setName('image2audio')
|
|
||||||
.setDescription('Transform an image binary data into audio ( MIGHT BE VERY LOUD )')
|
|
||||||
.addAttachmentOption(option =>
|
|
||||||
option.setName('img')
|
|
||||||
.setDescription('The image that will become audio. Only tested with png and jpg.')
|
|
||||||
.setRequired(true)),
|
|
||||||
category: 'fun',
|
|
||||||
alias: ['i2a'],
|
|
||||||
async execute(interaction, args) {
|
|
||||||
if (!args.img) return interaction.reply('Please attach an image with your message.');
|
|
||||||
|
|
||||||
await interaction.deferReply();
|
class image2audioCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('image2audio', {
|
||||||
|
aliases: ['image2audio', 'i2a'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'link',
|
||||||
|
type: 'url',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'wav',
|
||||||
|
type: 'flag',
|
||||||
|
flag: '--wav'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Transform an image binary data into audio ( MIGHT BECOME EAR RAPE ) --wav to get wav output',
|
||||||
|
usage: '[link to image]',
|
||||||
|
examples: ['https://cdn.discordapp.com/attachments/532987690145021982/682694359313022987/a2i682694012309864452.png']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ifExistDelete(`${os.tmpdir()}/${args.img.name}`);
|
async exec(message, args) {
|
||||||
ifExistDelete(`${os.tmpdir()}/1${args.img.name}`);
|
let url;
|
||||||
ifExistDelete(`${os.tmpdir()}/${args.img.name}.mp3`);
|
|
||||||
|
|
||||||
const streamPipeline = util.promisify(stream.pipeline);
|
if (args.link)
|
||||||
const res = await fetch(args.img.url);
|
url = args.link.href;
|
||||||
if (!res.ok) return interaction.editReply('An error has occured while trying to download your image.');
|
else
|
||||||
await streamPipeline(res.body, fs.createWriteStream(`${os.tmpdir()}/${args.img.name}`));
|
url = await attachment(message);
|
||||||
|
|
||||||
await utils.ffmpeg(['-i', `${os.tmpdir()}/${args.img.name}`, '-f', 'rawvideo', `${os.tmpdir()}/1${args.img.name}`]);
|
let loadingmsg = await message.channel.send('Processing <a:loadingmin:527579785212329984>');
|
||||||
await utils.ffmpeg(['-sample_rate', '44100', '-ac', '1', '-f', 's16le', '-i', `${os.tmpdir()}/1${args.img.name}`, `${os.tmpdir()}/${args.img.name}.mp3`]);
|
|
||||||
|
|
||||||
const file = fs.statSync(`${os.tmpdir()}/${args.img.name}.mp3`);
|
if (!url) return message.channel.send('Please attach an image or use an url');
|
||||||
const fileSize = (file.size / 1000000.0).toFixed(2);
|
|
||||||
|
|
||||||
if (fileSize > await utils.getMaxFileSize(interaction.guild)) return interaction.editReply('error');
|
fetch(url)
|
||||||
interaction.editReply({ content: `Audio file is ${fileSize} MB` });
|
.then(res => {
|
||||||
return interaction.followUp({ files: [`${os.tmpdir()}/${args.img.name}.mp3`] });
|
const dest = fs.createWriteStream(`${os.tmpdir()}/${message.id}.png`);
|
||||||
},
|
res.body.pipe(dest);
|
||||||
};
|
dest.on('finish', () => {
|
||||||
|
ffmpeg(`${os.tmpdir()}/${message.id}.png`)
|
||||||
async function ifExistDelete(path) {
|
.format('rawvideo')
|
||||||
if (fs.existsSync(path)) {
|
.output(`${os.tmpdir()}/${message.id}1.png`)
|
||||||
fs.rm(path, (err) => {
|
.on('error', (err, stdout, stderr) => {
|
||||||
console.log('deleted');
|
console.error(`${err}\n${stdout}\n${stderr}`);
|
||||||
if (err) {
|
return message.channel.send('Uh oh, an error has occurred!');
|
||||||
return;
|
})
|
||||||
}
|
.on('end', () => {
|
||||||
|
ffmpeg()
|
||||||
|
.audioBitrate(44100)
|
||||||
|
.audioChannels(1)
|
||||||
|
.input(`${os.tmpdir()}/${message.id}1.png`)
|
||||||
|
.inputFormat('s16le')
|
||||||
|
.output(`${os.tmpdir()}/i2a_${message.id}.${args.wav ? 'wav' : 'mp3'}`)
|
||||||
|
.on('error', (err, stdout, stderr) => {
|
||||||
|
console.error(`${err}\n${stdout}\n${stderr}`);
|
||||||
|
return message.channel.send('Uh oh, an error has occurred!');
|
||||||
|
})
|
||||||
|
.on('end', () => {
|
||||||
|
console.log('finished');
|
||||||
|
loadingmsg.delete();
|
||||||
|
let file = fs.statSync(`${os.tmpdir()}/i2a_${message.id}.${args.wav ? 'wav' : 'mp3'}`);
|
||||||
|
let fileSize = (file.size / 1000000.0).toFixed(2);
|
||||||
|
return message.channel.send(`Audio file is ${fileSize} MB`, {files: [`${os.tmpdir()}/i2a_${message.id}.${args.wav ? 'wav' : 'mp3'}`]})
|
||||||
|
.catch(() => {
|
||||||
|
return message.channel.send(`End result is too big to fit on discord! File is ${fileSize} MB`);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.run();
|
||||||
|
})
|
||||||
|
.run();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = image2audioCommand;
|
@ -0,0 +1,34 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
|
class ImgurCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('imgur', {
|
||||||
|
aliases: ['imgur', 'badmeme'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'EMBED_LINKS'],
|
||||||
|
description: {
|
||||||
|
content: 'Send some random images from imgur',
|
||||||
|
usage: '',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message) {
|
||||||
|
fetch('https://api.imgur.com/3/gallery/hot/day?showViral=true&mature=false&perPage=100&album_previews=true', {
|
||||||
|
headers: { 'Authorization': 'Client-ID e4cb6948f80f295' },
|
||||||
|
}).then((response) => {
|
||||||
|
return response.json();
|
||||||
|
}).then((response) => {
|
||||||
|
if (response.success == 'false')
|
||||||
|
return message.channel.send('An error has occurred');
|
||||||
|
|
||||||
|
const i = Math.floor((Math.random() * response.data.length));
|
||||||
|
|
||||||
|
message.channel.send(`**${response.data[i].title}**\n${response.data[i].link}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ImgurCommand;
|
@ -1,15 +0,0 @@
|
|||||||
import { SlashCommandBuilder } from 'discord.js';
|
|
||||||
import fetch from 'node-fetch';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data: new SlashCommandBuilder()
|
|
||||||
.setName('inspirobot')
|
|
||||||
.setDescription('Get an image from inspirobot'),
|
|
||||||
category: 'fun',
|
|
||||||
alias: ['ib'],
|
|
||||||
async execute(interaction) {
|
|
||||||
fetch('http://inspirobot.me/api?generate=true')
|
|
||||||
.then(res => res.text())
|
|
||||||
.then(body => interaction.reply({ files: [body] }));
|
|
||||||
},
|
|
||||||
};
|
|
@ -0,0 +1,133 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const attachment = require('../../utils/attachment');
|
||||||
|
const util = require('util');
|
||||||
|
const exec = util.promisify(require('child_process').exec);
|
||||||
|
const downloader = require('../../utils/download');
|
||||||
|
const os = require('os');
|
||||||
|
const ffmpeg = require('fluent-ffmpeg');
|
||||||
|
|
||||||
|
|
||||||
|
class midifyCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('midify', {
|
||||||
|
aliases: ['midify', 'wav2midi', 'w2m', 'mp32midi', 'm2m', 'sound2midi', 's2m'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'link',
|
||||||
|
type: 'url',
|
||||||
|
match: 'rest'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'raw',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--raw']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'noteblock',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--noteblock']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'voice',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--voice']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Transform the audio into midi --raw to get the .mid file',
|
||||||
|
usage: '[link to video/music/whatever you want to be midi]',
|
||||||
|
examples: ['https://www.youtube.com/watch?v=kXYiU_JCYtU']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let url;
|
||||||
|
|
||||||
|
if (args.link)
|
||||||
|
url = args.link.href;
|
||||||
|
else
|
||||||
|
url = await attachment(message);
|
||||||
|
|
||||||
|
let input = `${os.tmpdir()}/${message.id}`;
|
||||||
|
let input2 = `${os.tmpdir()}/${message.id}.wav`;
|
||||||
|
let output = `${os.tmpdir()}/${message.id}.mid`;
|
||||||
|
let output2 = `${os.tmpdir()}/${message.id}.mp3`;
|
||||||
|
|
||||||
|
|
||||||
|
let loadingmsg = await message.channel.send('Processing (this can take some time) <a:loadingmin:527579785212329984>');
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
downloader(url, null, input)
|
||||||
|
.on('error', (err) => {
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.channel.send(err, { code: true });
|
||||||
|
})
|
||||||
|
.on('end', output => {
|
||||||
|
// Convert to wav
|
||||||
|
ffmpeg()
|
||||||
|
.input(output)
|
||||||
|
.output(input2)
|
||||||
|
.on('end', () => {
|
||||||
|
midify();
|
||||||
|
})
|
||||||
|
.on('error', (err, stdout, stderr) => {
|
||||||
|
console.error(`${err}\n${stdout}\n${stderr}`);
|
||||||
|
return message.channel.send('Oh no! an error has occurred during the conversion, are you sure it is a valid file?');
|
||||||
|
})
|
||||||
|
.run();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return message.channel.send('You need a valid video link!');
|
||||||
|
}
|
||||||
|
|
||||||
|
function midify() {
|
||||||
|
// wav to midi
|
||||||
|
exec(`waon -i ${input2} -o ${output}`)
|
||||||
|
.then(() => {
|
||||||
|
|
||||||
|
if (args.raw) {
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.channel.send({files: [output]})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.channel.send('On no! an error just occurred! perhaps the file is too big?');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let option;
|
||||||
|
|
||||||
|
if (args.noteblock) {
|
||||||
|
option = '-c ./asset/timidity/config/noteblock.cfg';
|
||||||
|
} else if (args.voice) {
|
||||||
|
option = '-c ./asset/timidity/config/voice.cfg';
|
||||||
|
}
|
||||||
|
|
||||||
|
// midi to mp3 so we can listen from discord
|
||||||
|
exec(`timidity ${output} ${option} -Ow -o - | ffmpeg -i - -acodec libmp3lame -ab 64k ${output2}`)
|
||||||
|
.then(() => {
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.channel.send({files: [output2]})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.channel.send('On no! an error just occurred! perhaps the file is too big?');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
return message.channel.send('Oh no! an error has occurred during the conversion, are you sure it is a valid file?');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
return message.channel.send('Oh no! an error has occurred during the conversion, are you sure it is a valid file?');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = midifyCommand;
|
@ -0,0 +1,66 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const { proxy } = require('../../config.json');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
const cheerio = require('cheerio');
|
||||||
|
|
||||||
|
class PetitTubeCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('petittube', {
|
||||||
|
aliases: ['petittube', 'pt'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'proxy',
|
||||||
|
match: 'option',
|
||||||
|
flag: ['--proxy'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'listproxy',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--listproxy', '--proxylist']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Fetch a video from https://petittube.com/',
|
||||||
|
usage: '',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
if (args.listproxy) {
|
||||||
|
let proxys = [];
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
proxy.forEach(proxy => {
|
||||||
|
i++;
|
||||||
|
proxys.push(`[${i}] ${ proxy.hideip ? '[IP HIDDEN]' : proxy.ip.substring(0, proxy.ip.length - 5)} - ${proxy.country}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
const Embed = this.client.util.embed()
|
||||||
|
.setColor(message.member ? message.member.displayHexColor : 'NAVY')
|
||||||
|
.setTitle('List of available proxy')
|
||||||
|
.setDescription(proxys.join('\n'))
|
||||||
|
.setFooter('You can help me get more proxy by either donating to me or providing a proxy for me');
|
||||||
|
|
||||||
|
return message.channel.send(Embed);
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch('https://petittube.com/');
|
||||||
|
const body = await response.text();
|
||||||
|
|
||||||
|
const $ = cheerio.load(body);
|
||||||
|
|
||||||
|
const url = $('iframe')[0].attribs.src;
|
||||||
|
|
||||||
|
if (args.proxy) {
|
||||||
|
args.proxy = args.proxy -1;
|
||||||
|
if (!proxy[args.proxy]) args.proxy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client.commandHandler.runCommand(message, this.client.commandHandler.findCommand('download'), { link: new URL(url), proxy: args.proxy, spoiler: !message.channel.nsfw, caption: message.channel.nsfw ? '' : 'Video might be NSFW as always, be careful!'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = PetitTubeCommand;
|
@ -1,46 +1,61 @@
|
|||||||
import { SlashCommandBuilder, EmbedBuilder } from 'discord.js';
|
const { Command } = require('discord-akairo');
|
||||||
import fetch from 'node-fetch';
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
export default {
|
class RedditCommand extends Command {
|
||||||
data: new SlashCommandBuilder()
|
constructor() {
|
||||||
.setName('reddit')
|
super('reddit', {
|
||||||
.setDescription('Send random images from the subreddit you choose')
|
aliases: ['reddit'],
|
||||||
.addStringOption(option =>
|
|
||||||
option.setName('subreddit')
|
|
||||||
.setDescription('The subreddit you wish to see')
|
|
||||||
.setRequired(true)),
|
|
||||||
category: 'fun',
|
category: 'fun',
|
||||||
async execute(interaction, args) {
|
clientPermissions: ['SEND_MESSAGES', 'EMBED_LINKS'],
|
||||||
await interaction.deferReply({ ephemeral: false });
|
args: [
|
||||||
const subreddit = args.subreddit;
|
{
|
||||||
fetch('https://www.reddit.com/r/' + subreddit + '.json?limit=100').then((response) => {
|
id: 'sub',
|
||||||
return response.json();
|
type: 'string',
|
||||||
}).then((response) => {
|
prompt: {
|
||||||
if (response.error == 404) {
|
start: 'What subreddit do you want to browse?',
|
||||||
return interaction.editReply('Not a valid subreddit');
|
optional: true
|
||||||
|
},
|
||||||
|
default: 'random',
|
||||||
|
match: 'rest'
|
||||||
}
|
}
|
||||||
if (response.data.dist == 0) {
|
],
|
||||||
return interaction.editReply('Not a valid subreddit');
|
description: {
|
||||||
|
content: 'Send random images from the subreddit you choose',
|
||||||
|
usage: '[subreddit]',
|
||||||
|
examples: ['2meirl4meirl']
|
||||||
}
|
}
|
||||||
const i = Math.floor((Math.random() * response.data.children.length));
|
});
|
||||||
if (response.data.children[i].data.over_18 == true && !interaction.channel.nsfw) {
|
|
||||||
return interaction.editReply('No nsfw');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let description = response.data.children[i].data.selftext;
|
async exec(message, args) {
|
||||||
if (description === '') {
|
//let i = 0;
|
||||||
description = 'No description.';
|
//let a = 0;
|
||||||
}
|
if (!args.sub)
|
||||||
const redditEmbed = new EmbedBuilder()
|
return;
|
||||||
.setColor(interaction.member ? interaction.member.displayHexColor : 'Navy')
|
|
||||||
|
fetch('https://www.reddit.com/r/' + args.sub + '.json?limit=100').then((response) => {
|
||||||
|
return response.json();
|
||||||
|
}).then((response) => {
|
||||||
|
console.log(response);
|
||||||
|
if (response.error == 404)
|
||||||
|
return message.reply('Not a valid subreddit');
|
||||||
|
|
||||||
|
if (response.data.dist == 0)
|
||||||
|
return message.reply('Not a valid subreddit');
|
||||||
|
|
||||||
|
let i = Math.floor((Math.random() * response.data.children.length));
|
||||||
|
if (response.data.children[i].data.over_18 == true && !message.channel.nsfw)
|
||||||
|
return message.reply('No nsfw');
|
||||||
|
const redditEmbed = this.client.util.embed()
|
||||||
|
.setColor(message.member ? message.member.displayHexColor : 'NAVY')
|
||||||
.setTitle(response.data.children[i].data.title)
|
.setTitle(response.data.children[i].data.title)
|
||||||
.setDescription(description)
|
.setDescription(response.data.children[i].data.selftext)
|
||||||
.setURL('https://reddit.com' + response.data.children[i].data.permalink)
|
.setURL('https://reddit.com' + response.data.children[i].data.permalink)
|
||||||
.setFooter({ text: `/r/${response.data.children[i].data.subreddit} | ⬆ ${response.data.children[i].data.ups} 🗨 ${response.data.children[i].data.num_comments}` });
|
.setFooter(`/r/${response.data.children[i].data.subreddit} | ⬆ ${response.data.children[i].data.ups} 🗨 ${response.data.children[i].data.num_comments}`);
|
||||||
|
|
||||||
interaction.followUp({ embeds: [redditEmbed] });
|
message.reply(redditEmbed);
|
||||||
interaction.followUp(response.data.children[i].data.url);
|
message.reply(response.data.children[i].data.url);
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
module.exports = RedditCommand;
|
@ -0,0 +1,47 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const fs = require('fs');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
const os = require('os');
|
||||||
|
|
||||||
|
class spbCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('spb', {
|
||||||
|
aliases: ['spb'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'link',
|
||||||
|
type: 'url',
|
||||||
|
prompt: {
|
||||||
|
start: 'Need a shitpostbot5000 template link!',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Generate a meme from template you send with spb5k (ONLY WORK WITH TEMPLATES)',
|
||||||
|
usage: '',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
if (!args.link || !args.link.href.includes('shitpostbot.com/template/')) {
|
||||||
|
return message.reply('Need a Shitpostbot 5000 template link!\nYou can find them here! <https://www.shitpostbot.com/gallery/templates>');
|
||||||
|
}
|
||||||
|
|
||||||
|
let link = args.link.href.replace('template', 'preview');
|
||||||
|
|
||||||
|
fetch(link)
|
||||||
|
.then(res => {
|
||||||
|
const dest = fs.createWriteStream(`${os.tmpdir()}/${message.id}.jpg`);
|
||||||
|
res.body.pipe(dest);
|
||||||
|
dest.on('finish', () => {
|
||||||
|
return message.reply({files: [`${os.tmpdir()}/${message.id}.jpg`]});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = spbCommand;
|
@ -0,0 +1,59 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const { execFile } = require('child_process');
|
||||||
|
const rand = require('../../../rand.js');
|
||||||
|
|
||||||
|
class dectalkCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('dectalk', {
|
||||||
|
aliases: ['dectalk', 'dec'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'decMessage',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'Write something so i can say it back in dectalk',
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Send a wav of what you wrote into .wav with dectalk',
|
||||||
|
usage: '[text]',
|
||||||
|
examples: ['This command is very epic']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
args.decMessage = rand.random(args.decMessage, message);
|
||||||
|
let output = `${message.id}_dectalk.wav`;
|
||||||
|
let decMessage = '[:phoneme on]' + args.decMessage;
|
||||||
|
let loadingmsg = await message.channel.send('Processing ( this can take some time ) <a:loadingmin:527579785212329984>');
|
||||||
|
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
execFile('say.exe', ['-w', output, `${decMessage}`], {cwd: './dectalk/'}, (error, stdout, stderr) => {
|
||||||
|
sendMessage(output, error, stdout, stderr);
|
||||||
|
});
|
||||||
|
} else if (process.platform === 'linux' || process.platform === 'darwin') {
|
||||||
|
execFile('wine', ['say.exe', '-w', output, `${decMessage}`], {cwd: './dectalk/'}, (error, stdout, stderr) => {
|
||||||
|
sendMessage(`./dectalk/${output}`, error, stdout, stderr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendMessage(file, error, stdout, stderr) {
|
||||||
|
console.error(stdout);
|
||||||
|
loadingmsg.delete();
|
||||||
|
if (error) {
|
||||||
|
console.error(stderr);
|
||||||
|
console.error(error);
|
||||||
|
return message.channel.send('Oh no! an error has occurred!');
|
||||||
|
}
|
||||||
|
|
||||||
|
return message.channel.send({files: [file]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = dectalkCommand;
|
@ -0,0 +1,81 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const { execFile } = require('child_process');
|
||||||
|
const rand = require('../../../rand.js');
|
||||||
|
|
||||||
|
class dectalkvcCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('dectalkvc', {
|
||||||
|
aliases: ['dectalkvc', 'decvc'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SPEAK'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'decMessage',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'Write something so i can say it back in dectalk',
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Repeat what you sent in the voice chat you are currently in',
|
||||||
|
usage: '[text]',
|
||||||
|
examples: ['This command is very epic']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
args.decMessage = rand.random(args.decMessage, message);
|
||||||
|
let output = `${message.id}_dectalk.wav`;
|
||||||
|
let decMessage = '[:phoneme on] ' + args.decMessage;
|
||||||
|
let loadingmsg = await message.channel.send('Processing ( this can take some time ) <a:loadingmin:527579785212329984>');
|
||||||
|
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
execFile('say.exe', ['-w', output, `${decMessage}`], {cwd: './dectalk/'}, async (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
loadingmsg.delete();
|
||||||
|
console.error(stdout);
|
||||||
|
console.error(stderr);
|
||||||
|
console.error(error);
|
||||||
|
return message.channel.send('Oh no! an error has occurred!');
|
||||||
|
}
|
||||||
|
|
||||||
|
loadingmsg.delete();
|
||||||
|
playinVC(`./dectalk/${output}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
} else if (process.platform === 'linux' || process.platform === 'darwin') {
|
||||||
|
execFile('wine', ['say.exe', '-w', output, `${decMessage}`], {cwd: './dectalk/'}, async (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
loadingmsg.delete();
|
||||||
|
console.error(stdout);
|
||||||
|
console.error(stderr);
|
||||||
|
console.error(error);
|
||||||
|
return message.channel.send('Oh no! an error has occurred!');
|
||||||
|
}
|
||||||
|
|
||||||
|
loadingmsg.delete();
|
||||||
|
playinVC(`./dectalk/${output}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function playinVC(file) {
|
||||||
|
const voiceChannel = message.member.voice.channel;
|
||||||
|
if (!voiceChannel) return message.channel.send('Please enter a voice channel first.');
|
||||||
|
try {
|
||||||
|
const connection = await voiceChannel.join();
|
||||||
|
const dispatcher = connection.play(file);
|
||||||
|
dispatcher.once('finish', () => voiceChannel.leave());
|
||||||
|
dispatcher.once('error', () => voiceChannel.leave());
|
||||||
|
return null;
|
||||||
|
} catch (err) {
|
||||||
|
voiceChannel.leave();
|
||||||
|
return message.reply(`Oh no, an error occurred: \`${err.message}\`.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = dectalkvcCommand;
|
@ -0,0 +1,93 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const axios = require('axios');
|
||||||
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
|
const rand = require('../../../rand.js');
|
||||||
|
|
||||||
|
class samCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('sam', {
|
||||||
|
aliases: ['sam'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'samMessage',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'Write something so i can say it back in sam',
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Send a mp3 of what you wrote in Microsoft Sam tts, can change speed and pitch with [speed:a number] and [pitch:a number]',
|
||||||
|
usage: '[text]',
|
||||||
|
examples: ['Here comes the roflcopter soisoisoisoisoi']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
args.samMessage = rand.random(args.samMessage, message);
|
||||||
|
let pitch;
|
||||||
|
if (args.samMessage.includes('[pitch:')) {
|
||||||
|
pitch = args.samMessage.split(/(\[pitch:.*?])/);
|
||||||
|
for (let i = 0, l = pitch.length; i < l; i++) {
|
||||||
|
if (pitch[i].includes('[pitch:')) {
|
||||||
|
pitch = pitch[i].replace('[pitch:', '').slice(0, -1);
|
||||||
|
args.samMessage = args.samMessage.replace(/(\[pitch:.*?])/g, '');
|
||||||
|
i = pitch.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pitch > 200)
|
||||||
|
pitch = 200;
|
||||||
|
else if (pitch < 50)
|
||||||
|
pitch = 50;
|
||||||
|
} else {
|
||||||
|
pitch = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
let speed;
|
||||||
|
if (args.samMessage.includes('[speed:')) {
|
||||||
|
speed = args.samMessage.split(/(\[speed:.*?])/);
|
||||||
|
for (let i = 0, l = speed.length; i < l; i++) {
|
||||||
|
if (speed[i].includes('[speed:')) {
|
||||||
|
speed = speed[i].replace('[speed:', '').slice(0, -1);
|
||||||
|
args.samMessage = args.samMessage.replace(/(\[speed:.*?])/g, '');
|
||||||
|
i = speed.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (speed > 450)
|
||||||
|
speed = 450;
|
||||||
|
else if (speed < 30)
|
||||||
|
speed = 30;
|
||||||
|
} else {
|
||||||
|
speed = 150;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.samMessage = args.samMessage.replace('\n', ' ');
|
||||||
|
args.samMessage = encodeURI(args.samMessage);
|
||||||
|
|
||||||
|
return axios.request({
|
||||||
|
responseType: 'arraybuffer',
|
||||||
|
url: `https://tetyys.com/SAPI4/SAPI4?text=${args.samMessage}&voice=Sam&pitch=${pitch}&speed=${speed}`,
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'audio/mpeg',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
return message.channel.send(`Uh oh, an error has occurred! please try again later.\n${err}`);
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
const outputFilename = `${os.tmpdir}/${message.id}_sam.wav`;
|
||||||
|
fs.writeFileSync(outputFilename, result.data);
|
||||||
|
return message.channel.send({files: [outputFilename]});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = samCommand;
|
@ -0,0 +1,107 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const axios = require('axios');
|
||||||
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
|
const rand = require('../../../rand.js');
|
||||||
|
|
||||||
|
class samvcCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('samvc', {
|
||||||
|
aliases: ['samvc'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SPEAK'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'samMessage',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'Write something so i can say it back in sam',
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Repeat what you said in voice chat with Microsoft Sam tts, can change speed and pitch with [speed:a number] and [pitch:a]',
|
||||||
|
usage: '[text]',
|
||||||
|
examples: ['Here comes the roflcopter soisoisoisoisoi']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
args.samMessage = rand.random(args.samMessage, message);
|
||||||
|
let pitch;
|
||||||
|
if (args.samMessage.includes('[pitch:')) {
|
||||||
|
pitch = args.samMessage.split(/(\[pitch:.*?])/);
|
||||||
|
for (let i = 0, l = pitch.length; i < l; i++) {
|
||||||
|
if (pitch[i].includes('[pitch:')) {
|
||||||
|
pitch = pitch[i].replace('[pitch:', '').slice(0, -1);
|
||||||
|
args.samMessage = args.samMessage.replace(/(\[pitch:.*?])/g, '');
|
||||||
|
i = pitch.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pitch > 200)
|
||||||
|
pitch = 200;
|
||||||
|
else if (pitch < 50)
|
||||||
|
pitch = 50;
|
||||||
|
} else {
|
||||||
|
pitch = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
let speed;
|
||||||
|
if (args.samMessage.includes('[speed:')) {
|
||||||
|
speed = args.samMessage.split(/(\[speed:.*?])/);
|
||||||
|
for (let i = 0, l = speed.length; i < l; i++) {
|
||||||
|
if (speed[i].includes('[speed:')) {
|
||||||
|
speed = speed[i].replace('[speed:', '').slice(0, -1);
|
||||||
|
args.samMessage = args.samMessage.replace(/(\[speed:.*?])/g, '');
|
||||||
|
i = speed.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (speed > 450)
|
||||||
|
speed = 450;
|
||||||
|
else if (speed < 30)
|
||||||
|
speed = 30;
|
||||||
|
} else {
|
||||||
|
speed = 150;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.samMessage = args.samMessage.replace('\n', ' ');
|
||||||
|
args.samMessage = encodeURI(args.samMessage);
|
||||||
|
|
||||||
|
return axios.request({
|
||||||
|
responseType: 'arraybuffer',
|
||||||
|
url: `https://tetyys.com/SAPI4/SAPI4?text=${args.samMessage}&voice=Sam&pitch=${pitch}&speed=${speed}`,
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'audio/mpeg',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
return message.channel.send(`Uh oh, an error has occurred! please try again later.\n${err}`);
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(async (result) => {
|
||||||
|
const outputFilename = `${os.tmpdir}/${message.id}_sam.wav`;
|
||||||
|
|
||||||
|
fs.writeFile(outputFilename, result.data, async function(err) {
|
||||||
|
if (err) console.error(err);
|
||||||
|
const voiceChannel = message.member.voice.channel;
|
||||||
|
if (!voiceChannel) return message.channel.send('Please enter a voice channel first.');
|
||||||
|
try {
|
||||||
|
const connection = await voiceChannel.join();
|
||||||
|
const dispatcher = connection.play(outputFilename);
|
||||||
|
dispatcher.once('finish', () => voiceChannel.leave());
|
||||||
|
dispatcher.once('error', () => voiceChannel.leave());
|
||||||
|
return null;
|
||||||
|
} catch (err) {
|
||||||
|
voiceChannel.leave();
|
||||||
|
return message.reply(`Oh no, an error occurred: \`${err.message}\`.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = samvcCommand;
|
@ -0,0 +1,70 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const textToSpeech = require('@google-cloud/text-to-speech');
|
||||||
|
const rand = require('../../../rand.js');
|
||||||
|
const gclient = new textToSpeech.TextToSpeechClient();
|
||||||
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
|
|
||||||
|
class TtsCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('tts', {
|
||||||
|
aliases: ['tts'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'text',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'Write something so i can say it back in Google tts',
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Send a mp3 of what you wrote in tts',
|
||||||
|
usage: '[text]',
|
||||||
|
examples: ['hello']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let text = args.text;
|
||||||
|
let output = `${os.tmpdir()}/${message.id}_tts.mp3`;
|
||||||
|
|
||||||
|
text = rand.random(text, message);
|
||||||
|
|
||||||
|
// Construct the request
|
||||||
|
const request = {
|
||||||
|
input: { text: text },
|
||||||
|
// Select the language and SSML Voice Gender (optional)
|
||||||
|
voice: { languageCode: 'en-US', ssmlGender: 'NEUTRAL' },
|
||||||
|
// Select the type of audio encoding
|
||||||
|
audioConfig: { audioEncoding: 'MP3' },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Performs the Text-to-Speech request
|
||||||
|
gclient.synthesizeSpeech(request, (err, response) => {
|
||||||
|
if (err) {
|
||||||
|
|
||||||
|
console.error('ERROR:', err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the binary audio content to a local file
|
||||||
|
fs.writeFile(output, response.audioContent, 'binary', err => {
|
||||||
|
if (err) {
|
||||||
|
console.error('ERROR:', err);
|
||||||
|
message.channel.send('An error has occurred, the message is probably too long');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('Audio content written to file: tts.mp3');
|
||||||
|
message.channel.send({ files: [output] });
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = TtsCommand;
|
@ -0,0 +1,79 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const textToSpeech = require('@google-cloud/text-to-speech');
|
||||||
|
const rand = require('../../../rand.js');
|
||||||
|
const gclient = new textToSpeech.TextToSpeechClient();
|
||||||
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
|
|
||||||
|
class TtsvcCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('ttsvc', {
|
||||||
|
aliases: ['ttsvc'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SPEAK'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'text',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'Write something so i can say it back in Google tts',
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Say what you wrote in voice channel',
|
||||||
|
usage: '[text]',
|
||||||
|
examples: ['hello']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let text = args.text;
|
||||||
|
let output = `${os.tmpdir()}/${message.id}_tts.mp3`;
|
||||||
|
|
||||||
|
text = rand.random(text, message);
|
||||||
|
|
||||||
|
// Construct the request
|
||||||
|
const request = {
|
||||||
|
input: { text: text },
|
||||||
|
// Select the language and SSML Voice Gender (optional)
|
||||||
|
voice: { languageCode: 'en-US', ssmlGender: 'NEUTRAL' },
|
||||||
|
// Select the type of audio encoding
|
||||||
|
audioConfig: { audioEncoding: 'MP3' },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Performs the Text-to-Speech request
|
||||||
|
gclient.synthesizeSpeech(request, (err, response) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('ERROR:', err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the binary audio content to a local file
|
||||||
|
fs.writeFile(output, response.audioContent, 'binary', async err => {
|
||||||
|
if (err) {
|
||||||
|
console.error('ERROR:', err);
|
||||||
|
message.channel.send('An error has occurred, the message is probably too long');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const voiceChannel = message.member.voice.channel;
|
||||||
|
if (!voiceChannel) return message.channel.send('Please enter a voice channel first.');
|
||||||
|
try {
|
||||||
|
const connection = await voiceChannel.join();
|
||||||
|
const dispatcher = connection.play(output);
|
||||||
|
dispatcher.once('finish', () => voiceChannel.leave());
|
||||||
|
dispatcher.once('error', () => voiceChannel.leave());
|
||||||
|
return null;
|
||||||
|
} catch (err) {
|
||||||
|
voiceChannel.leave();
|
||||||
|
return message.reply(`Oh no, an error occurred: \`${err.message}\`.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = TtsvcCommand;
|
@ -0,0 +1,99 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const os = require('os');
|
||||||
|
const ffmpeg = require('fluent-ffmpeg');
|
||||||
|
const attachment = require('../../utils/attachment');
|
||||||
|
const downloader = require('../../utils/download');
|
||||||
|
|
||||||
|
class vidshittyfierCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('vidshittyfier', {
|
||||||
|
aliases: ['vidshittyfier', 'vs', 'shittyfier', 'vid2shit', 'v2s'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'link',
|
||||||
|
type: 'url',
|
||||||
|
unordered: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'compression',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
unordered: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Compress your videos and lower their quality!',
|
||||||
|
usage: '[link to video] [lighter compression (True or false)]',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let vid;
|
||||||
|
if (args.link)
|
||||||
|
vid = args.link.href;
|
||||||
|
else
|
||||||
|
vid = await attachment(message);
|
||||||
|
|
||||||
|
let output = `${os.tmpdir()}/tmp${message.id}.mp4`;
|
||||||
|
let output2 = `${os.tmpdir()}/Shittyfied${message.id}.mp4`;
|
||||||
|
|
||||||
|
let compression = '30k';
|
||||||
|
let audioCompression = '60k';
|
||||||
|
|
||||||
|
if (args.compression) {
|
||||||
|
compression = '50k';
|
||||||
|
audioCompression = '100k';
|
||||||
|
}
|
||||||
|
|
||||||
|
let loadingmsg = await message.channel.send('Processing <a:loadingmin:527579785212329984>');
|
||||||
|
|
||||||
|
downloader(vid, null, `${os.tmpdir()}/${message.id}.mp4`)
|
||||||
|
.on('error', async err => {
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.channel.send(err, { code: true });
|
||||||
|
})
|
||||||
|
.on('end', async downloadOutput => {
|
||||||
|
let ffmpegCommand = ffmpeg(downloadOutput);
|
||||||
|
|
||||||
|
ffmpegCommand.videoFilters('scale=iw/4:ih/4');
|
||||||
|
ffmpegCommand.output(output);
|
||||||
|
ffmpegCommand.run();
|
||||||
|
ffmpegCommand.on('error', (err, stdout, stderr) => {
|
||||||
|
loadingmsg.delete();
|
||||||
|
console.error(`${err}\n${stdout}\n${stderr}`);
|
||||||
|
return message.channel.send('Uh oh, an error has occurred!' + err);
|
||||||
|
});
|
||||||
|
ffmpegCommand.on('end', () => {
|
||||||
|
let ffmpegCommand = ffmpeg(downloadOutput);
|
||||||
|
|
||||||
|
ffmpegCommand.videoFilters('scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2');
|
||||||
|
ffmpegCommand.videoCodec('libx264');
|
||||||
|
ffmpegCommand.fps(15);
|
||||||
|
ffmpegCommand.videoBitrate(compression);
|
||||||
|
ffmpegCommand.audioBitrate(audioCompression);
|
||||||
|
ffmpegCommand.output(output2);
|
||||||
|
ffmpegCommand.run();
|
||||||
|
ffmpegCommand.on('error', (err, stdout, stderr) => {
|
||||||
|
loadingmsg.delete();
|
||||||
|
console.error(`${err}\n${stdout}\n${stderr}`);
|
||||||
|
return message.channel.send('Uh oh, an error has occurred!' + err);
|
||||||
|
});
|
||||||
|
ffmpegCommand.on('end', () => {
|
||||||
|
loadingmsg.delete();
|
||||||
|
message.delete();
|
||||||
|
return message.channel.send(`Shittyfied by ${message.author}`, {files: [output2]})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
return message.channel.send(`${err.name}: ${err.message} ${err.message === 'Request entity too large' ? 'The file size is too big' : ''}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = vidshittyfierCommand;
|
@ -0,0 +1,265 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const YTPGenerator = require('ytpplus-node');
|
||||||
|
const os = require('os');
|
||||||
|
const fs = require('fs');
|
||||||
|
const youtubedl = require('youtube-dl');
|
||||||
|
let queue = 0;
|
||||||
|
|
||||||
|
class ytpCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('ytp', {
|
||||||
|
aliases: ['ytp', 'ytpplus', 'ytp+'],
|
||||||
|
category: 'fun',
|
||||||
|
clientPermissions: ['ATTACH_FILES', 'SEND_MESSAGES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'add',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--add']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'pool',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--pool']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'force',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--force']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'randomSound',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--randomSound']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'randomSoundMute',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--randomSoundMute']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'reverse',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--reverse']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'chorus',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--chorus']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'vibrato',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--vibrato']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'highPitch',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--highPitch']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'lowPitch',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--lowPitch']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'speedUp',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--speedUp']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'slowDown',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--slowDown']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'dance',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--dance']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'squidward',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--squidward']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'debug',
|
||||||
|
match: 'flag',
|
||||||
|
flag: ['--debug']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'link',
|
||||||
|
type: 'string'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Generate random ytp | --add with a link or attachment to add a video to the pool, only .mp4 work | --pool to see how many vid there is currently in the pool | --force to make the command work outside of nsfw channel BE AWARE THAT IT WON\'T CHANGE THE FINAL RESULT SO NSFW CAN STILL HAPPEN',
|
||||||
|
usage: '',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
console.log(queue);
|
||||||
|
let prefix = this.client.commandHandler.prefix[0];
|
||||||
|
let MAX_CLIPS = 20;
|
||||||
|
|
||||||
|
if (args.pool) {
|
||||||
|
let mp4 = [];
|
||||||
|
fs.readdirSync('./asset/ytp/userVid/').forEach(file => {
|
||||||
|
if (file.endsWith('mp4')) {
|
||||||
|
mp4.push(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return message.channel.send(`There is currently ${mp4.length} videos, you can add yours by doing \`\`${prefix}ytp --add (link or attachment)\`\``);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.add) {
|
||||||
|
let loadingmsg = await message.channel.send('Downloading <a:loadingmin:527579785212329984>');
|
||||||
|
let Attachment = (message.attachments).array();
|
||||||
|
let url = args.link;
|
||||||
|
// Get attachment link
|
||||||
|
if (Attachment[0] && !args.link) {
|
||||||
|
url = Attachment[0].url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
return youtubedl.exec(url, ['--no-playlist','--max-filesize', '50m', '--format=mp4', '-o', `./asset/ytp/userVid/${message.id}.mp4`], {}, function(err, output) {
|
||||||
|
console.log(output);
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.channel.send('An error has occured, I can\'t download from the link you provided. Is it an mp4?');
|
||||||
|
} else {
|
||||||
|
if (output[2]) {
|
||||||
|
if (output[2].includes('File is larger than max-filesize')) {
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.channel.send(output[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mp4 = [];
|
||||||
|
fs.readdirSync('./asset/ytp/userVid/').forEach(file => {
|
||||||
|
if (file.endsWith('mp4')) {
|
||||||
|
mp4.push(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.reply(`Video sucessfully added to the pool! There is now ${mp4.length} videos`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.channel.send('You need a valid video link!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!message.channel.nsfw && !args.force) return message.channel.send(`Please execute this command in an NSFW channel ( Content might not be NSFW but since the video are user submitted better safe than sorry ) OR do \`\`${prefix}ytp --force\`\` to make the command work outside of nsfw channel BE AWARE THAT IT WON'T CHANGE THE FINAL RESULT SO NSFW CAN STILL HAPPEN`);
|
||||||
|
|
||||||
|
if (queue >= 1) {
|
||||||
|
let curQueue = queue;
|
||||||
|
message.channel.send(`The execution of this command has been placed in a queue, you are #${curQueue}/${queue} in the queue`);
|
||||||
|
|
||||||
|
let reminder = setInterval(() => {
|
||||||
|
message.channel.send(`The execution of this command has been placed in a queue, you are #${curQueue}/${queue} in the queue`);
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
|
let checkQueue = setInterval(() => {
|
||||||
|
console.log(queue);
|
||||||
|
console.log(curQueue);
|
||||||
|
if (curQueue < 1) {
|
||||||
|
clearInterval(checkQueue);
|
||||||
|
clearInterval(reminder);
|
||||||
|
makeYTP();
|
||||||
|
}
|
||||||
|
if (queue < curQueue) curQueue = queue;
|
||||||
|
}, 1000);
|
||||||
|
//queue++;
|
||||||
|
} else {
|
||||||
|
//queue++;
|
||||||
|
makeYTP();
|
||||||
|
}
|
||||||
|
|
||||||
|
queue++;
|
||||||
|
|
||||||
|
async function makeYTP() {
|
||||||
|
console.log('making ytp');
|
||||||
|
// Read userVid folder and select random vid and only take .mp4
|
||||||
|
let mp4 = [];
|
||||||
|
let asset = [];
|
||||||
|
let files = fs.readdirSync('./asset/ytp/userVid/');
|
||||||
|
// Count number of total vid
|
||||||
|
files.forEach(file => {
|
||||||
|
if (file.endsWith('mp4')) {
|
||||||
|
mp4.push(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Select random vid depending on the amount of MAX_CLIPS
|
||||||
|
for (let i = 0; i < MAX_CLIPS; i++) {
|
||||||
|
let random = Math.floor(Math.random() * files.length);
|
||||||
|
let vid = `./asset/ytp/userVid/${files[random]}`;
|
||||||
|
if (files[random].endsWith('mp4')) {
|
||||||
|
if (!asset.includes(vid)) {
|
||||||
|
asset.push(vid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let loadingmsg = await message.channel.send(`Processing, this can take a **long** time, i'll ping you when i finished <a:loadingmin:527579785212329984>\nSome info: There is currently ${mp4.length} videos, you can add yours by doing \`\`${prefix}ytp --add (link or attachment)\`\``);
|
||||||
|
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
debug: args.debug,
|
||||||
|
MAX_STREAM_DURATION: args.link ? args.link : Math.floor((Math.random() * 3) + 1), // Random duration of video clip
|
||||||
|
sources: './asset/ytp/sources/',
|
||||||
|
sounds: './asset/ytp/sounds/',
|
||||||
|
music: './asset/ytp/music/',
|
||||||
|
resources: './asset/ytp/resources/',
|
||||||
|
temp: os.tmpdir(),
|
||||||
|
sourceList: asset,
|
||||||
|
outro: './asset/ytp/outro.mp4', // Need an outro or it won't work
|
||||||
|
OUTPUT_FILE: `${os.tmpdir()}/${message.id}_YTP.mp4`,
|
||||||
|
MAX_CLIPS: MAX_CLIPS,
|
||||||
|
transitions: true,
|
||||||
|
effects: {
|
||||||
|
effect_RandomSound: args.randomSound,
|
||||||
|
effect_RandomSoundMute: args.randomSoundMute,
|
||||||
|
effect_Reverse: args.reverse,
|
||||||
|
effect_Chorus: args.chorus,
|
||||||
|
effect_Vibrato: args.vibrato,
|
||||||
|
effect_HighPitch: args.highPitch,
|
||||||
|
effect_LowPitch: args.lowPitch,
|
||||||
|
effect_SpeedUp: args.speedUp,
|
||||||
|
effect_SlowDown: args.slowDown,
|
||||||
|
effect_Dance: args.dance,
|
||||||
|
effect_Squidward: args.squidward
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
new YTPGenerator().configurateAndGo(options)
|
||||||
|
.then(() => {
|
||||||
|
queue--;
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.reply('Here is your YTP!', {files: [`${os.tmpdir()}/${message.id}_YTP.mp4`]})
|
||||||
|
.catch(() => {
|
||||||
|
return message.channel.send('Whoops, look like the vid might be too big for discord, my bad, please try again');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
queue--;
|
||||||
|
console.error(err);
|
||||||
|
loadingmsg.delete();
|
||||||
|
return message.reply('Oh no! An error has occured!');
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ytpCommand;
|
@ -0,0 +1,33 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
|
class AdviceCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('advice', {
|
||||||
|
aliases: ['advice'],
|
||||||
|
category: 'general',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'EMBED_LINKS'],
|
||||||
|
description: {
|
||||||
|
content: 'Send some random advices',
|
||||||
|
usage: '',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message) {
|
||||||
|
fetch('http://api.adviceslip.com/advice').then((response) => {
|
||||||
|
return response.json();
|
||||||
|
}).then((response) => {
|
||||||
|
const adviceEmbed = this.client.util.embed()
|
||||||
|
.setColor(message.member ? message.member.displayHexColor : 'NAVY')
|
||||||
|
.setTitle(response.slip.id)
|
||||||
|
.setDescription(response.slip.advice);
|
||||||
|
|
||||||
|
|
||||||
|
message.reply(adviceEmbed);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = AdviceCommand;
|
@ -0,0 +1,37 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const rand = require('../../rand.js');
|
||||||
|
class ClapCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('clap', {
|
||||||
|
aliases: ['clap'],
|
||||||
|
category: 'general',
|
||||||
|
clientPermissions: ['SEND_MESSAGES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'text',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'Write something so i can replace the space with 👏',
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'replace 👏 the 👏 spaces 👏 with 👏 clap 👏',
|
||||||
|
usage: '[text]',
|
||||||
|
examples: ['replace the spaces with clap']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
if (!args.text)
|
||||||
|
return;
|
||||||
|
args.text = rand.random(args.text, message);
|
||||||
|
|
||||||
|
let clap = args.text.replace(/ /g, ' 👏 ');
|
||||||
|
message.reply(`${clap} 👏`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ClapCommand;
|
@ -0,0 +1,44 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const emojiCharacters = require('../../emojiCharacters');
|
||||||
|
const rand = require('../../rand.js');
|
||||||
|
|
||||||
|
class EmotesayCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('emotesay', {
|
||||||
|
aliases: ['emotesay', 'esay'],
|
||||||
|
category: 'general',
|
||||||
|
clientPermissions: ['SEND_MESSAGES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'text',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'Write something so i can replace the space with dancing emote',
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Replace the text you send with dancing letters',
|
||||||
|
usage: '[text]',
|
||||||
|
examples: ['Hello']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let text = args.text;
|
||||||
|
if (!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
text = rand.random(text, message);
|
||||||
|
|
||||||
|
message.delete();
|
||||||
|
let emojiArray = [];
|
||||||
|
for (let i = 0; i < text.length; i++)
|
||||||
|
emojiArray[i] = emojiCharacters[text.toLowerCase().split('')[i]];
|
||||||
|
message.channel.send(emojiArray.join(''));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = EmotesayCommand;
|
@ -0,0 +1,66 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const Filter = require('bad-words');
|
||||||
|
let filter = new Filter();
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
const reload = require('auto-reload');
|
||||||
|
const rand = require('../../rand.js');
|
||||||
|
const { fbChannel, fbToken } = require('../../config.json');
|
||||||
|
|
||||||
|
class facebookCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('facebook', {
|
||||||
|
aliases: ['facebook', 'fb'],
|
||||||
|
category: 'general',
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'text',
|
||||||
|
type: 'string',
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Post your message to the bot facebook page',
|
||||||
|
usage: '[text]',
|
||||||
|
examples: ['epic']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let text = args.text;
|
||||||
|
|
||||||
|
let censor = reload('../../json/censor.json');
|
||||||
|
let uncensor = reload('../../json/uncensor.json');
|
||||||
|
filter.addWords(...censor);
|
||||||
|
filter.removeWords(...uncensor);
|
||||||
|
|
||||||
|
const blacklist = reload('../../json/Blacklist.json');
|
||||||
|
const channel = this.client.channels.get(fbChannel);
|
||||||
|
|
||||||
|
if (blacklist.includes(message.author.id)) {
|
||||||
|
return message.channel.send('You have been blacklisted from this command... be less naughty next time.');
|
||||||
|
}
|
||||||
|
|
||||||
|
//Filter out swear word
|
||||||
|
text = filter.clean(text);
|
||||||
|
|
||||||
|
text = rand.random(text, message);
|
||||||
|
text = encodeURI(text);
|
||||||
|
|
||||||
|
fetch(`https://graph.facebook.com/v3.2/1254967721332652/feed?message=${text}&access_token=${fbToken}`, {
|
||||||
|
method: 'post',
|
||||||
|
}).then((response) => {
|
||||||
|
return response.json();
|
||||||
|
}).then((response) => {
|
||||||
|
console.log(response);
|
||||||
|
let postID;
|
||||||
|
if (response.id) {
|
||||||
|
postID = response.id.slice(17);
|
||||||
|
}
|
||||||
|
message.channel.send(`Go see ur epic post https://www.facebook.com/HahaYesDiscord/posts/${postID}`);
|
||||||
|
channel.send(`AUTHOR: ${message.author.username} (${message.author.id}) Sent: ${args.text}\nhttps://www.facebook.com/HahaYesDiscord/posts/${postID}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = facebookCommand;
|
@ -0,0 +1,49 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
const { memerToken } = require('../../config.json');
|
||||||
|
|
||||||
|
class memerclubCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('memerclub', {
|
||||||
|
aliases: ['memerclub'],
|
||||||
|
category: 'general',
|
||||||
|
clientPermissions: ['SEND_MESSAGES', 'ATTACH_FILES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'text',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Post whatever you like on https://memerclub.gamingti.me ! ( no rules, go wild )',
|
||||||
|
usage: '',
|
||||||
|
examples: ['']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let Attachment = (message.attachments).array();
|
||||||
|
let img = '';
|
||||||
|
if (!Attachment[0] && !args.text) return message.channel.send('You need to input something for me to post!');
|
||||||
|
if (Attachment[0]) {
|
||||||
|
img = Attachment[0].url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.text)
|
||||||
|
if (args.text.includes('discord.gg')) return message.channel.send('No discord invite allowed.');
|
||||||
|
|
||||||
|
fetch(`https://memerclub.gamingti.me/api/post/?token=${memerToken}&text=${encodeURI(args.text)}&image=${img}`)
|
||||||
|
.then((response) => {
|
||||||
|
return response.json();
|
||||||
|
}).then((response) => {
|
||||||
|
console.log(response);
|
||||||
|
if (response.error) return message.channel.send(response.error);
|
||||||
|
message.channel.send(`Go check your epic post!\nhttps://memerclub.gamingti.me/post/${response.uuid}`)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = memerclubCommand;
|
@ -0,0 +1,34 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
|
||||||
|
class randomizerCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('randomizer', {
|
||||||
|
aliases: ['randomizer'],
|
||||||
|
category: 'general',
|
||||||
|
clientPermissions: ['SEND_MESSAGES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'text',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'Need words to randomize',
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Choose one random word',
|
||||||
|
usage: '[multiples words]',
|
||||||
|
examples: ['Hello bye']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let words = args.text.split(' ');
|
||||||
|
|
||||||
|
return message.reply(words[Math.floor((Math.random() * words.length))]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = randomizerCommand;
|
@ -0,0 +1,168 @@
|
|||||||
|
const { Command } = require('discord-akairo');
|
||||||
|
const { MessageEmbed } = require('discord.js');
|
||||||
|
const rand = require('../../rand.js');
|
||||||
|
|
||||||
|
class SayCommand extends Command {
|
||||||
|
constructor() {
|
||||||
|
super('say', {
|
||||||
|
aliases: ['say', 'sayd'],
|
||||||
|
category: 'general',
|
||||||
|
clientPermissions: ['SEND_MESSAGES'],
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
id: 'text',
|
||||||
|
type: 'string',
|
||||||
|
prompt: {
|
||||||
|
start: 'Write something so i can say it back',
|
||||||
|
},
|
||||||
|
match: 'rest'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: {
|
||||||
|
content: 'Repeat what you say, (Use sayd to delete your message) [Click here to see the complete list of "tag"](https://cdn.discordapp.com/attachments/502198809355354133/561043193949585418/unknown.png)',
|
||||||
|
usage: '[text]',
|
||||||
|
examples: ['[member] is a big [adverbs] [verbs]']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(message, args) {
|
||||||
|
let text = args.text;
|
||||||
|
if (!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
text = rand.random(text, message);
|
||||||
|
|
||||||
|
let attach = '';
|
||||||
|
|
||||||
|
if (text.includes('[attach:')) {
|
||||||
|
attach = text.split(/(\[attach:.*?])/);
|
||||||
|
for (let i = 0, l = attach.length; i < l; i++) {
|
||||||
|
if (attach[i].includes('[attach:')) {
|
||||||
|
attach = attach[i].replace('[attach:', '').slice(0, -1);
|
||||||
|
i = attach.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
text = text.replace(/(\[attach:.*?])/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS SECTION IS VERY VERY BAD MUST CHANGE
|
||||||
|
if (text.includes('[embed]')) {
|
||||||
|
text = text.replace(/\[embed\]/, ' ');
|
||||||
|
|
||||||
|
let title = '';
|
||||||
|
let desc = '';
|
||||||
|
let image;
|
||||||
|
let thumbnail;
|
||||||
|
let footer = '';
|
||||||
|
let color;
|
||||||
|
|
||||||
|
if (text.includes('[embedImage:')) {
|
||||||
|
image = text.split(/(\[embedImage:.*?])/);
|
||||||
|
|
||||||
|
for (let i = 0, l = image.length; i < l; i++) {
|
||||||
|
if (image[i].includes('[embedImage:')) {
|
||||||
|
image = image[i].replace('[embedImage:', '').slice(0, -1);
|
||||||
|
text = text.replace(/(\[embedimage:.*?])/g, '');
|
||||||
|
i = image.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.includes('[embedThumbnail:')) {
|
||||||
|
thumbnail = text.split(/(\[embedThumbnail:.*?])/);
|
||||||
|
|
||||||
|
for (let i = 0, l = thumbnail.length; i < l; i++) {
|
||||||
|
if (thumbnail[i].includes('[embedThumbnail:')) {
|
||||||
|
thumbnail = thumbnail[i].replace('[embedThumbnail:', '').slice(0, -1);
|
||||||
|
text = text.replace(/(\[embedThumbnail:.*?])/g, '');
|
||||||
|
i = thumbnail.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.includes('[embedColor:')) {
|
||||||
|
color = text.split(/(\[embedColor:.*?])/);
|
||||||
|
for (let i = 0, l = color.length; i < l; i++) {
|
||||||
|
if (color[i].includes('[embedColor:')) {
|
||||||
|
color = color[i].replace('[embedColor:', '').slice(0, -1);
|
||||||
|
text = text.replace(/(\[embedColor:.*?])/g, '');
|
||||||
|
i = color.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (text.includes('[embedTitle:')) {
|
||||||
|
title = text.split(/(\[embedTitle:.*?])/);
|
||||||
|
for (let i = 0, l = title.length; i < l; i++) {
|
||||||
|
if (title[i].includes('[embedTitle:')) {
|
||||||
|
title = title[i].replace('[embedTitle:', '').slice(0, -1);
|
||||||
|
text = text.replace(/(\[embedTitle:.*?])/g, '');
|
||||||
|
i = title.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.includes('[embedFooter:')) {
|
||||||
|
footer = text.split(/(\[embedFooter:.*?])/);
|
||||||
|
for (let i = 0, l = footer.length; i < l; i++) {
|
||||||
|
if (footer[i].includes('[embedFooter:')) {
|
||||||
|
footer = footer[i].replace('[embedFooter:', '').slice(0, -1);
|
||||||
|
text = text.replace(/(\[embedFooter:.*?])/g, '');
|
||||||
|
i = footer.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.includes('[embedDesc:')) {
|
||||||
|
desc = text.split(/(\[embedDesc:.*?])/);
|
||||||
|
for (let i = 0, l = desc.length; i < l; i++) {
|
||||||
|
if (desc[i].includes('[embedDesc:')) {
|
||||||
|
desc = desc[i].replace('[embedDesc:', '').slice(0, -1);
|
||||||
|
i = desc.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = new MessageEmbed()
|
||||||
|
.setColor(color)
|
||||||
|
.setTitle(title)
|
||||||
|
.setImage(image)
|
||||||
|
.setThumbnail(thumbnail)
|
||||||
|
.setDescription(desc)
|
||||||
|
.setFooter(footer)
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
if (attach) {
|
||||||
|
if (args.delete)
|
||||||
|
message.delete();
|
||||||
|
return message.channel.send(embed, {files: [attach]});
|
||||||
|
} else {
|
||||||
|
if (args.delete)
|
||||||
|
message.delete();
|
||||||
|
return message.channel.send(embed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the final text
|
||||||
|
if (attach) {
|
||||||
|
if (message.util.parsed.alias == 'sayd')
|
||||||
|
if (message.channel.permissionsFor(this.client.user).has('MANAGE_MESSAGES'))
|
||||||
|
message.delete();
|
||||||
|
else
|
||||||
|
message.channel.send('Im missing he `MANAGE_MESSAGES` perm to delete your message!');
|
||||||
|
|
||||||
|
return message.channel.send(text, {files: [attach]});
|
||||||
|
} else {
|
||||||
|
if (message.util.parsed.alias == 'sayd')
|
||||||
|
if (message.channel.permissionsFor(this.client.user).has('MANAGE_MESSAGES'))
|
||||||
|
message.delete();
|
||||||
|
else
|
||||||
|
message.channel.send('Im missing he `MANAGE_MESSAGES` perm to delete your message!');
|
||||||
|
return message.channel.send(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = SayCommand;
|