From 40285510521962ae29d31c0e0205bf39f5250918 Mon Sep 17 00:00:00 2001 From: carlos3g Date: Wed, 21 Jul 2021 17:49:21 -0300 Subject: [PATCH 1/3] [DOCS] documents some files in the 'auth' folder --- src/auth/index.js | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/auth/index.js b/src/auth/index.js index 9db142a..079872b 100644 --- a/src/auth/index.js +++ b/src/auth/index.js @@ -1,11 +1,17 @@ -const whatsapp = require('whatsapp-web.js'); +const { Client } = require('whatsapp-web.js'); const qrcode = require('qrcode-terminal'); const fs = require('fs'); const path = require('path'); const FILE_NAME = 'session.json'; -class Session extends whatsapp.Client { +/** + * Starting point for interacting with the WhatsApp Web API. + * @param {string} SESSION_FILE_PATH - Path to `session.json` file. + * @see https://docs.wwebjs.dev/Client.html + * @extends {Client} + */ +class Session extends Client { constructor() { super({ puppeteer: { @@ -16,10 +22,17 @@ class Session extends whatsapp.Client { this.SESSION_FILE_PATH = path.join(__dirname, FILE_NAME); } + /** + * Checks if the `session.json` file already exists. + * @returns {boolean} - `True` if exists, `False` if not. + */ get exists() { return fs.existsSync(this.SESSION_FILE_PATH); } + /** + * Throws the QR-Code to authenticate the session. When the QR-Code is read, the session file is written. + */ create() { this.on('qr', (qr) => { qrcode.generate(qr, { small: true }); @@ -27,11 +40,18 @@ class Session extends whatsapp.Client { this.on('authenticated', this.save); } + /** + * Writes the session in a .json file (`this.SESSION_FILE_PATH`) + * @param {object} session - The session file returned in the authentication. + */ save(session) { fs.writeFileSync(this.SESSION_FILE_PATH, JSON.stringify(session)); console.log('⚠ The current session has been saved ⚠'); } + /** + * Loads the saved session file. + */ load() { if (!this.exists) { throw Error(`session data does not exist in ${this.SESSION_FILE_PATH}`); @@ -44,6 +64,9 @@ class Session extends whatsapp.Client { console.log('⚠ The previous session was loaded ⚠'); } + /** + * Starts the session. + */ start() { this.on('ready', () => { console.log('Client is ready!'); From b8a2e768191e5643578ee65e87e7c28be4ec2e33 Mon Sep 17 00:00:00 2001 From: carlos3g Date: Wed, 21 Jul 2021 17:49:34 -0300 Subject: [PATCH 2/3] [DOCS] documents some files in the 'build' folder --- src/build/Commands.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/build/Commands.js b/src/build/Commands.js index 9d4af11..821b173 100644 --- a/src/build/Commands.js +++ b/src/build/Commands.js @@ -2,11 +2,21 @@ function isFunction(object) { return typeof object === 'function'; } +/** + * Commands wrapper + * @param {object} commands - Object that contains the commands. + * @param {object} commands.* - A command. The key and value must be, respectively, the command name and a callback function for the command. + */ class Commands { constructor() { this.commands = {}; } + /** + * Sets a command in Commands instance. + * @param {string} name - Command's name. + * @param {function} callback - Callback to command. + */ set(name, callback) { if (!isFunction(callback)) { throw new Error(`${callback} must be a function`); @@ -15,11 +25,29 @@ class Commands { this.commands[name] = callback; } + /** + * Checks if a command is set in Commands instance. + * @param {string} cmd - The command's name. + * @returns {boolean} `True` if the command is set in Commands instance, `False` if not. + */ has(cmd) { const availableCommands = Object.keys(this.commands); return availableCommands.includes(cmd); } + /** + * Calls (executes) a command. + * @param {string} cmd - The command's name to be called. + * @param {object} data - The data extracted from the message that called the command. + * @param {string} data.command - The command's name extracted from the message. + * @param {string[]} data.args - The args extracted from the message. + * @param {object} data.kwargs - The kwargs extracted from the message. + * @param {string} data.text - The text extracted from the message. This text NOT includes command's name, args and kwargs. + * @param {Message} message - The message that called the command. + * @param {Session} client - The whatsapp web session. + * @see https://docs.wwebjs.dev/Message.html + * @see https://docs.wwebjs.dev/Client.html + */ async call(cmd, data, message, client) { if (!this.has(cmd)) { throw new Error(`${cmd} is not registered`); From 2c4c36ce5f7f0a81a5096efcc6f9c0afc4580edc Mon Sep 17 00:00:00 2001 From: carlos3g Date: Wed, 21 Jul 2021 17:49:45 -0300 Subject: [PATCH 3/3] [DOCS] documents some files in the 'utils' folder --- src/utils/Parse.js | 35 ++++++++++++++++++++++++++++++++++ src/utils/chattools.js | 43 +++++++++++++++++++++++++----------------- src/utils/search.js | 9 ++++++++- src/utils/time.js | 23 +++++++++++++++++----- 4 files changed, 87 insertions(+), 23 deletions(-) diff --git a/src/utils/Parse.js b/src/utils/Parse.js index b82b927..848981d 100644 --- a/src/utils/Parse.js +++ b/src/utils/Parse.js @@ -1,6 +1,25 @@ +/** + * Extract useful data from a given string (usually the content of a message). + * @example + * const messageContent = '!command --arg1 --kwarg=1 any text here' + * const data = new Parse(messageContent) + * data.command // command + * data.args // ['arg1'] + * data.kwargs // { kwarg: 1 } + * data.text // 'any text here' + * @param {string} text - Text to be parsed. + */ class Parse { constructor(text) { + /** The original text. */ this.rawText = text.trim(); + + /** + * A collection of regular expressions used in the extraction of data from the `this.rawText`. + * @property {string} REGEXP.command - Regular expression for commands. Ex: !command + * @property {string[]} REGEXP.args - Regular expression for args. Ex: --arg1 + * @property {object} REGEXP.kwargs - Regular expression for kwargs. Ex: --kwarg=1 + */ this.REGEXP = { command: /^!([^\s]+)/, args: /--([\S]+)(?=\s|$)/g, @@ -8,11 +27,19 @@ class Parse { }; } + /** + * Gets the command extracted from the `this.rawText`. + * @returns {string} + */ get command() { const matches = this.rawText.match(this.REGEXP.command); return matches ? matches[1] : ''; } + /** + * Gets the args extracted from `this.rawText`. + * @returns {string[]} + */ get args() { const matchesIter = this.rawText.matchAll(this.REGEXP.args); const matchesArray = [...matchesIter]; @@ -20,6 +47,10 @@ class Parse { return matches; } + /** + * Gets the kwargs extracted from `this.rawText`. + * @returns {object} + */ get kwargs() { const obj = {}; const matchesIter = this.rawText.matchAll(this.REGEXP.kwargs); @@ -32,6 +63,10 @@ class Parse { return obj; } + /** + * Gets the text extracted from `this.rawText`. + * @returns {string} + */ get text() { return this.rawText .replace(this.REGEXP.command, '') diff --git a/src/utils/chattools.js b/src/utils/chattools.js index ce255f0..e28c12d 100644 --- a/src/utils/chattools.js +++ b/src/utils/chattools.js @@ -1,18 +1,20 @@ /** - * Get serialized number - * @param {Array} idList - An array containing objects about user identification. - * @return {Array} - Contains serialized phone numbers + * Get serialized phone number from a given array of users. + * @param {Contact[]} users - Whatsapp users. + * @see https://docs.wwebjs.dev/Contact.html + * @returns {string[]} - Serialized phone numbers. */ -function getSerialList(idList) { +function getSerialList(users) { // eslint-disable-next-line no-underscore-dangle - const serialList = idList.map((id) => id.id._serialized); + const serialList = users.map((u) => u.id._serialized); return serialList; } /** - * Get serialized number of all members in group - * @param {Object} chat - Object that represents the current chat - * @return {Array} - Contains serialized phone numbers of all members + * Get serialized phone number of all members from a given group. + * @param {Chat} chat - A whatsapp chat. + * @see https://docs.wwebjs.dev/Chat.html + * @returns {string[]} - Serialized phone numbers of all members. */ async function getMembersList(chat) { const members = await chat.participants; @@ -21,9 +23,10 @@ async function getMembersList(chat) { } /** - * Get serialized number of all administrators in group - * @param {Object} chat - Object that represents the current chat - * @return {Array} - Contains serialized phone numbers of all administrators + * Get serialized phone number of all administrators from a given group. + * @param {Chat} chat - A whatsapp chat. + * @see https://docs.wwebjs.dev/Chat.html + * @returns {string[]} - Serialized phone numbers of all administrators. */ async function getAdmsList(chat) { const members = await chat.participants; @@ -33,9 +36,10 @@ async function getAdmsList(chat) { } /** - * Check if a message if from an adm - * @param {Object} message - Object that represents the current message - * @return {Boolean} + * Checks if a message is from an ADM. + * @param {Message} message - Message to check if is from an ADM. + * @see https://docs.wwebjs.dev/Message.html + * @returns {boolean} */ async function isAdm(message) { const chat = await message.getChat(); @@ -44,12 +48,17 @@ async function isAdm(message) { return admList.includes(author); } -function userID(targetNumber) { - if (typeof targetNumber !== 'string') { +/** + * Get a whatsapp user id for a given phone number. + * @param {string} phoneNumber + * @returns {string} + */ +function userID(phoneNumber) { + if (typeof phoneNumber !== 'string') { throw new Error('you must pass the number as a string'); } - const target = targetNumber.replace(/\D/g, ''); + const target = phoneNumber.replace(/\D/g, ''); const regexp = /\d+/; const matches = target.match(regexp); const pattern = matches[0]; diff --git a/src/utils/search.js b/src/utils/search.js index 41cf766..d906bb3 100644 --- a/src/utils/search.js +++ b/src/utils/search.js @@ -1,6 +1,13 @@ const googleIt = require('google-it'); -async function google(query, target = '', limit = null) { +/** + * Searchs for a given string in google. + * @param {string} query Text that must be searched. + * @param {string} [target=''] Target site to search in. + * @param {number} [limit=0] Max number of results that must be returned. + * @returns {object[]} Array of results found. + */ +async function google(query, target = '', limit = 0) { const result = await googleIt({ query, includeSites: target, diff --git a/src/utils/time.js b/src/utils/time.js index e45cd56..00d1009 100644 --- a/src/utils/time.js +++ b/src/utils/time.js @@ -1,12 +1,25 @@ +/** + * Suspends (waits) execution of the current thread for a given number of seconds. + * @param {number} seconds + * @returns {Promise} + */ function sleep(seconds) { return new Promise((resolve) => setTimeout(resolve, seconds * 1000)); } -function timer(sec = 0, min = 0, hour = 0, day = 0) { - const secsInMS = sec * 1000; - const minsInMS = min * 60 * 1000; - const hoursInMS = hour * 60 * 60 * 1000; - const daysInMS = day * 24 * 60 * 60 * 1000; +/** + * Converts a given set of seconds, minutes, hours and days in miliseconds. + * @param {number} [secs=0] + * @param {number} [mins=0] + * @param {number} [hours=0] + * @param {number} [days=0] + * @returns {number} Total time in miliseconds. + */ +function timer(secs = 0, mins = 0, hours = 0, days = 0) { + const secsInMS = secs * 1000; + const minsInMS = mins * 60 * 1000; + const hoursInMS = hours * 60 * 60 * 1000; + const daysInMS = days * 24 * 60 * 60 * 1000; const timeInMS = secsInMS + minsInMS + hoursInMS + daysInMS; return timeInMS; }