Skip to content

Commit 3f8be3f

Browse files
authored
Merge pull request #54 from BeelanMX/develop
Add CFE BOT
2 parents 065cf34 + bce62c3 commit 3f8be3f

19 files changed

+1336
-2010
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,5 @@ dist
104104
.tern-port
105105

106106

107-
pictures/
107+
assets/*
108+
!assets/.gitkeep

CFEScraping/index.js

-30
This file was deleted.

Procfile

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
worker: node index.js

README.md

+36
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,47 @@ $ yarn install
1616
# Run the app
1717
$ yarn start
1818
```
19+
## How to use Discord Bot
20+
21+
### Requirements
22+
23+
1. Discord Bot Token **[Guide](https://discordjs.guide/preparations/setting-up-a-bot-application.html#creating-your-bot)**
24+
2. Discord.js v12.0.0
25+
3. Node.js v14.0.0 or newer
26+
27+
Follow the provided guide to create your own bot aplication from the page **[Discord Developer Portal](https://discord.com/developers/applications)**.
28+
After you cloned this repository and installed all the necessary dependecies, you'll need to create an `.env` file in the root of repository using the structure shown in the env.sample of this repository.
29+
You can use the prefix that you like the most.
30+
31+
(⚠️ **Note: Never commit or share your token or api keys publicly** ⚠️)
32+
33+
34+
```sh
35+
36+
#To run the bot
37+
$ node index.js
38+
39+
```
40+
1941

2042
## Node
2143

2244
This application is created using [Node14](https://nodejs.org/dist/latest-v14.x/docs/api/)
2345

46+
## Puppeteer with Node & linux
47+
48+
We are using the library [Puppeteer v10.1.0](https://pptr.dev/#?product=Puppeteer&version=v10.1.0)
49+
To run in linux or WSL2 need install chromium-browser
50+
51+
```
52+
#!/bin/bash
53+
$ sudo apt-get update
54+
$ sudo apt-get install chromium-browser
55+
$ sudo apt-get install -y libgbm-dev
56+
```
57+
58+
if there is some issues there are some reference [here](https://stackoverflow.com/a/65497048/7351895), [here](https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#chrome-is-downloaded-but-fails-to-launch-on-nodejs-14)
59+
2460
### VsCode Extensions
2561

2662
Name: [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)

assets/.gitkeep

Whitespace-only changes.

commands/cfe.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use strict';
2+
3+
const Validation = require('../utils/validator');
4+
const myValidator = new Validation();
5+
const sendMessage = require('../utils/sendTableMessage');
6+
const Scrapper = require('../webScraping/cfeScrapper');
7+
8+
/**
9+
* Main function of the command
10+
* @param { Message } message Channel to send the data
11+
* @arg { searchItems } args Searching parameters
12+
* @return { void }
13+
*/
14+
async function execute(message, args) {
15+
if (!args || args.length === 0) {
16+
return message.channel.send('The command needs a searching parameter.');
17+
}
18+
const route = `./assets/cfe_${args.join('').toLowerCase()}.json`;
19+
args = args.join(' ');
20+
const executeScrapper = myValidator.isFileLastUpdateIn(route);
21+
if (!executeScrapper) {
22+
message.reply('Is needed execute the scrapper, executing...');
23+
24+
try {
25+
const cfeScrapper = new Scrapper(args);
26+
// Show how many data has been obtained
27+
cfeScrapper.printPercentage = (percentage) => {
28+
message.reply(`Loading data ${percentage.toString()} %`);
29+
};
30+
const scrap = await cfeScrapper.doScraping(route);
31+
if (scrap === false) {
32+
// There's no data available
33+
message.reply(`There's no data available with ${args}`);
34+
return;
35+
}
36+
} catch (error) {
37+
message.reply(`An error in the execution...${error}`);
38+
}
39+
} else {
40+
// If the file exists and was created in the lasts 20hr
41+
message.reply('Is not needed execute the scrapper');
42+
}
43+
44+
// Send a message with the data obtained
45+
const tableMessage = sendMessage.jsonToEmbedMessage(route);
46+
for (let i = 0; i < tableMessage.length; i++) {
47+
message.reply(tableMessage[i]);
48+
}
49+
message.reply('That is all the data I found');
50+
}
51+
52+
module.exports = {
53+
name: 'cfe',
54+
description: 'Get searching parameters from the user.',
55+
cooldown: 3,
56+
execute,
57+
};

commands/help.js

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* eslint-disable indent */
2+
const prefix = process.env.PREFIX;
3+
4+
module.exports = {
5+
name: 'help',
6+
description: 'List all of my commands or info about a specific command.',
7+
aliases: ['commands'],
8+
usage: '[command name]',
9+
cooldown: 5,
10+
execute(message, args) {
11+
const data = [];
12+
// eslint-disable-next-line object-curly-spacing
13+
const { commands } = message.client;
14+
15+
if (!args.length) {
16+
// eslint-disable-next-line quotes
17+
data.push("Here's a list of all my commands:");
18+
data.push(commands.map((command) => command.name).join(', '));
19+
data.push(
20+
// eslint-disable-next-line max-len
21+
`\nYou can send \`${prefix}help [command name]\` to get info on a specific command.`,
22+
);
23+
24+
// eslint-disable-next-line object-curly-spacing
25+
return message.channel.send(data, { split: true });
26+
}
27+
28+
const name = args[0].toLowerCase();
29+
const command =
30+
commands.get(name) ||
31+
commands.find((c) => c.aliases && c.aliases.includes(name));
32+
33+
if (!command) {
34+
// eslint-disable-next-line quotes
35+
return message.reply("That's not a valid command.");
36+
}
37+
38+
data.push(`**Name:** ${command.name}`);
39+
40+
if (command.aliases) {
41+
data.push(`**Aliases:** ${command.aliases.join(', ')}`);
42+
}
43+
if (command.description) {
44+
data.push(`**Description:** ${command.description}`);
45+
}
46+
if (command.usage) {
47+
data.push(`**Usage:** ${prefix}${command.name} ${command.usage}`);
48+
}
49+
50+
data.push(`**Cooldown:** ${command.cooldown || 3} second(s)`);
51+
52+
// eslint-disable-next-line object-curly-spacing
53+
message.channel.send(data, { split: true });
54+
},
55+
};

env.sample

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
TOKEN=
2+
PREFIX=

index.js

+93-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,96 @@
1-
try {
2-
const OpenBrowser = require('./cfeScraping/index.js');
1+
/* eslint-disable indent */
2+
'use strict';
3+
// we're gonna use strict mode in all
34

4-
'use strict';
5-
// we're gonna use strict mode in all
5+
require('dotenv').config();
66

7-
console.log('Hello Message');
8-
OpenBrowser.OpenBrowser();
7+
const fs = require('fs');
8+
const Discord = require('discord.js');
9+
const cooldowns = new Map();
10+
// eslint-disable-next-line object-curly-spacing
11+
const { Client, Collection, Intents } = require('discord.js');
12+
const client = new Client({
13+
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES],
14+
});
15+
// Assign the value "!" to the constant prefix, which you will use as the
16+
// bot prefix.
17+
const prefix = process.env.PREFIX;
918

10-
} catch (err) {
11-
console.error('An error have been occurred:', err);
12-
}
19+
client.commands = new Collection();
20+
21+
const commandFiles = fs
22+
.readdirSync('./commands')
23+
.filter((file) => file.endsWith('.js'));
24+
25+
for (const file of commandFiles) {
26+
const command = require(`./commands/${file}`);
27+
// Set a new item in the Collection
28+
// With the key as the command name and the value as the exported module
29+
client.commands.set(command.name, command);
30+
}
31+
32+
client.on('ready', readyDiscord);
33+
34+
/**
35+
* Verify if the bot is connected
36+
*/
37+
function readyDiscord() {
38+
console.log('Ready');
39+
}
40+
41+
// Check if the content of the message that the bot is processing starts with
42+
// the prefix you set and if it doesn't stop processing
43+
// eslint-disable-next-line space-before-function-paren
44+
client.on('message', function (message) {
45+
if (message.author.bot) return;
46+
if (!message.content.startsWith(prefix)) return;
47+
48+
// Convert the rest of the message to a command name and any arguments that
49+
// may exist in the message.
50+
const args = message.content.slice(prefix.length).trim().split(/ +/);
51+
const commandName = args.shift().toLowerCase();
52+
53+
if (!client.commands.has(commandName)) return;
54+
const command = client.commands.get(commandName);
55+
56+
// If cooldowns map doesn't have a command.name key then create one.
57+
if (!cooldowns.has(command.name)) {
58+
cooldowns.set(command.name, new Discord.Collection());
59+
}
60+
61+
const currentTime = Date.now();
62+
const timeStamps = cooldowns.get(command.name);
63+
const cooldownAmount = command.cooldowns * 1000;
64+
65+
// If time_stamps has a key with the author's id then check the
66+
// expiration time to send a message to a user.
67+
if (timeStamps.has(message.author.id)) {
68+
const expirationTime = timeStamps.get(message.author.id) + cooldownAmount;
69+
70+
if (currentTime < expirationTime) {
71+
const timeLeft = (expirationTime - currentTime) / 1000;
72+
73+
return message.reply(
74+
`Please wait ${timeLeft.toFixed(1)} more seconds before using ${
75+
command.name
76+
// eslint-disable-next-line comma-dangle
77+
}`
78+
);
79+
}
80+
}
81+
82+
// If the author's id is not in timeStamps then add them with the current
83+
// time.
84+
timeStamps.set(message.author.id, currentTime);
85+
// Delete the user's id once the cooldown is over.
86+
setTimeout(() => timeStamps.delete(message.author.id), cooldownAmount);
87+
88+
try {
89+
command.execute(message, args);
90+
} catch (error) {
91+
console.error(error);
92+
message.reply('Error trying to execute that command.');
93+
}
94+
});
95+
96+
client.login(process.env.TOKEN);

0 commit comments

Comments
 (0)