I am trying to do manual mock for the custom module ->help.js
I have created manual mock
|-models
| |-mocks
|-help.js
|help.js
|test.js
mocked the functions like help.js
jest.mock('./help', () => {
return {
add: jest.fn(() => jest.fn()),
delete: jest.fn(() => jest.fn()),
toggle: jest.fn(() => jest.fn())
};
and I am trying to using mocking module in test.js like
jest.mock('./_mocks_/help');
const help =require()
test('add',()=>{
expect(help.add).toHaveBeenCalledWith({
type: 'test',
});
})
again it is calling main implementation module instead of mock module.
please help me on this.I am new to jest
Thanks in advance
`
const { MessageEmbed } = require("discord.js");
const { readdirSync } = require("fs");
const db = require('quick.db');
const { stripIndents } = require("common-tags");
const { cyan } = require("../../JSON/colours.json");
const { PREFIX } = require('../../config');
module.exports = {
config: {
name: "help",
aliases: ["h"],
usage: "[command name] (optional)",
category: "info",
description: "Displays all commands that the bot has.",
accessableby: "everyone"
},
run: async (bot, message, args) => {
let prefix;
let fetched = await db.fetch(`prefix_${message.guild.id}`);
if (fetched === null) {
prefix = PREFIX
} else {
prefix = fetched
}
const embed = new MessageEmbed()
.setColor(cyan)
.setAuthor(`${message.guild.me.displayName} Help`, message.guild.iconURL())
.setThumbnail(bot.user.displayAvatarURL())
if (!args[0]) {
const sembed = new MessageEmbed()
.setAuthor(`${message.guild.me.displayName}`, message.guild.iconURL())
.setColor("GREEN")
.setDescription('**Message Has Been Sent to You In DMs!**')
message.channel.send(sembed).then(msg => {
msg.delete({ timeout: 10000 });
})
const categories = readdirSync("./commands/")
embed.setDescription(`**These Are the Available Commands For ${message.guild.me.displayName}\nBot's Global Prefix Is \`${PREFIX}\`\nServer Prefix Is \`${prefix}\`\n\nFor Help Related To A Particular Command Type -\n\`${prefix}help [command name | alias]\`**`)
embed.setFooter(`${message.guild.me.displayName} | Total Commands - ${bot.commands.size - 1}`, bot.user.displayAvatarURL());
categories.forEach(category => {
const dir = bot.commands.filter(c => c.config.category === category)
const capitalise = category.slice(0, 1).toUpperCase() + category.slice(1)
try {
embed.addField(` ${capitalise} [${dir.size}] - `, dir.map(c => `\`${c.config.name}\``).join(" "))
} catch (e) {
console.log(e)
}
})
return message.author.send(embed)
} else {
let command = bot.commands.get(bot.aliases.get(args[0].toLowerCase()) || args[0].toLowerCase())
if (!command) return message.channel.send(embed.setTitle("**Invalid Command!**").setDescription(`**Do \`${prefix}help\` For the List Of the Commands!**`))
command = command.config
embed.setDescription(stripIndents`**The Bot's Global Prefix Is \`${PREFIX}\`**\n
**Server Prefix Is \`${prefix}\`**\n
** Command -** ${command.name.slice(0, 1).toUpperCase() + command.name.slice(1)}\n
** Description -** ${command.description || "No Description provided."}\n
**Category -** ${command.category}\n
** Usage -** ${command.usage ? `\`${prefix}${command.name} ${command.usage}\`` : "No Usage"}\n
** Accessible by -** ${command.accessableby || "everyone"}\n
** Aliases -** ${command.aliases ? command.aliases.join(", ") : "None."}`)
embed.setFooter(message.guild.name, message.guild.iconURL())
return message.channel.send(embed)
}
}
}; `
Related
So anytime I send an incorrect command like !pong (where!ping is the correct one) the bot returns with the following error:
(if(command.permissions.length){
^
TypeError: Cannot read property 'permissions' of undefined
even if I remove the whole permissions code it then gives me a
TypeError: Cannot read property 'users' of undefined
and it's only when I have a wrong command of that of !pong when there is no command or !me anything with the prefix that isn't a actual command. below is the code im using
Message.js
require('dotenv').config();
const cooldowns = new Map();
module.exports = (Discord, client, message) =>{
const prefix = process.env.PREFIX;
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const cmd = args.shift().toLowerCase();
const command = client.commands.get(cmd) || client.commands.find(a => a.aliases && a.aliases.includes(cmd));
const validPermissions = [
"CREATE_INSTANT_INVITE",
"KICK_MEMBERS",
"BAN_MEMBERS",
"ADMINISTRATOR",
"MANAGE_CHANNELS",
"MANAGE_GUILD",
"ADD_REACTIONS",
"VIEW_AUDIT_LOG",
"PRIORITY_SPEAKER",
"STREAM",
"VIEW_CHANNEL",
"SEND_MESSAGES",
"SEND_TTS_MESSAGES",
"MANAGE_MESSAGES",
"EMBED_LINKS",
"ATTACH_FILES",
"READ_MESSAGE_HISTORY",
"MENTION_EVERYONE",
"USE_EXTERNAL_EMOJIS",
"VIEW_GUILD_INSIGHTS",
"CONNECT",
"SPEAK",
"MUTE_MEMBERS",
"DEAFEN_MEMBERS",
"MOVE_MEMBERS",
"USE_VAD",
"CHANGE_NICKNAME",
"MANAGE_NICKNAMES",
"MANAGE_ROLES",
"MANAGE_WEBHOOKS",
"MANAGE_EMOJIS",
]
if(command.permissions.length){
let invalidPerms = []
for(const perm of command.permissions){
if(!validPermissions.includes(perm)){
return console.log(`Invalid Permissions ${perm}`);
}
if(!message.member.hasPermission(perm)){
invalidPerms.push(perm);
}
}
if (invalidPerms.length){
return message.channel.send(`Missing Permissions: \`${invalidPerms}\``);
}
}
if(!cooldowns.has(command.name)){
cooldowns.set(command.name, new Discord.Collection());
}
const current_time = Date.now();
const time_stamps = cooldowns.get(command.name);
const cooldown_ammount = (command.cooldown) * 1000;
if(time_stamps.has(message.author.id)){
const expiration_time = time_stamps.get(message.author.id) + cooldown_ammount;
if(current_time < expiration_time){
const time_left = (expiration_time - current_time) / 1000;
return message.reply(`Please wait ${time_left.toFixed(1)} more seconds before using ${command.name}`)
}
}
time_stamps.set(message.author.id, current_time);
setTimeout(() => time_stamps.delete(message.author.id), cooldown_ammount);
try{
command.execute(message,args, cmd, client, Discord);
} catch (err){
message.reply("There was an error trying to execute this command!");
console.log(err);
}
}
ping.js
module.exports = {
name: 'ping',
cooldown: 10,
permissions: ["SEND_MESSAGES",],
description: "this is a ping command!",
execute(client, message, args, cmd, Discord){
message.channel.send('pong!');
} }
In your message.js, after the declaration of command, you need to check if it’s undefined or null
const command = client.commands.get(cmd) || client.commands.find(a => a.aliases && a.aliases.includes(cmd));
if(!command) return;
Edit: your error comes from here:
command.execute(message,args, cmd, client, Discord);
//^^how you execute
execute(client, message, args, cmd, Discord){ message.channel.send('pong!'); }
//^^how you define it
So as you can see, you put them in the wrong order.
I am making a Type racing minigame with my discord bot, the code works... but I want to change the messages it sends to embeds, im new to Commando and it wont let me use the discord.js functions im used to using
I need to change all the bots responses to embeds, and make it so when it sends a new embed it just edits the old one so it isnt spamming messages. Here is my code:
const Commando = require('discord.js-commando')
const { words } = require('../../util/fast-type-words')
const example = {
channelId: {
message: 'message object',
stage: 'string',
counter: 'number',
currentWord: 'string',
remainingWords: ['words here'],
points: {
userId: 'points',
},
},
}
const games = {}
const stages = {
STARTING: (counter) => {
return `A new "fast type" game is starting in ${counter}s!`
},
IN_GAME: (word) => {
let spacedWord = ''
for (const character of [...word]) {
spacedWord += character
spacedWord += ' '
}
return `The new word is **${spacedWord}**!`
},
ENDING: (points) => {
const sorted = Object.keys(points).sort((a, b) => {
return points[b] - points[a]
})
let results = ''
for (const key of sorted) {
const amount = points[key]
results += `<#${key}> had ${amount} point${amount === 1 ? '' : 's'}\n`
}
return `The game is now over Here's how everyone did:\n\n${results}------------------`
},
}
const selectWord = (game) => {
game.currentWord =
game.remainingWords[Math.floor(Math.random() * game.remainingWords.length)]
const index = game.remainingWords.indexOf(game.currentWord)
game.remainingWords.splice(index, 1)
}
const gameLoop = () => {
for (const key in games) {
const game = games[key]
const { message, stage } = game
if (stage === 'STARTING') {
let string = stages[stage](game.counter)
message.edit(string)
if (game.counter <= 0) {
game.stage = 'IN_GAME'
game.counter = 15
selectWord(game)
string = stages[game.stage](game.currentWord)
message.edit(string)
}
} else if (stage === 'IN_GAME') {
if (game.counter <= 0) {
game.stage = 'ENDING'
const string = stages[game.stage](game.points)
message.edit(string)
// Delete the game
delete games[key]
continue
}
}
--game.counter
}
setTimeout(gameLoop, 1000)
}
module.exports = class FastTypeGame extends Commando.Command {
constructor(client) {
super(client, {
name: 'fasttype',
group: 'games',
memberName: 'fasttype',
description: 'Starts a fast type game',
userPermissions: ['ADMINISTRATOR'],
})
client.on('message', (message) => {
const { channel, content, member } = message
const { id } = channel
const game = games[id]
if (game && game.currentWord && !member.user.bot) {
message.delete()
if (
game.stage === 'IN_GAME' &&
content.toLowerCase() === game.currentWord.toLowerCase()
) {
game.currentWord = null
const seconds = 2
const { points } = game
points[member.id] = points[member.id] || 0
message
.reply(`You won! +1 point (${++points[member.id]} total)`)
.then((newMessage) => {
newMessage.delete({
timeout: 1000 * seconds,
})
})
setTimeout(() => {
if (game.stage === 'IN_GAME') {
selectWord(game)
const string = stages[game.stage](game.currentWord)
game.message.edit(string)
}
}, 1000 * seconds)
}
}
})
gameLoop()
}
async run(message) {
const { channel } = message
message.delete()
channel.send('Preparing game...').then((message) => {
games[channel.id] = {
message,
stage: 'STARTING',
counter: 5,
remainingWords: [...words],
points: {
'719805930547445772': 4,
'723819104045105172': 1,
},
}
})
}
}
First change embeded content is not related to discord.js-commando to change the content of sended embeded message you need to get Message Object then using edit() method to pass the new embed content to it:
-Bonus: You can also edit text message into embed message.
Docs for edit method: https://discord.js.org/#/docs/main/stable/class/Message?scrollTo=edit
Example code:
let youCurrentMessage = await channel.send(embedContent);
yourCurrentMessage.edit(newEmbedContent);
yourCurrentMessage.edit(newEmbedContent2);
// If you edit message in other command , session.You need message id
let yourCurrentMessage = await msg.channel.messages.fetch(editMessageId);
yourCurrentMessage.edit(newEmbedContent);
I'm trying to run Document OCR from Google with a Node js app.
So i used the client library for Node js #google-cloud/documentai
I did everything like in documentation sample
There is my code
const projectId = '*******';
const location = 'eu'; // Format is 'us' or 'eu'
const processor = '******'; // Create processor in Cloud Console
const keyFilename = './secret/******.json';
const { DocumentProcessorServiceClient } = require('#google-cloud/documentai').v1beta3;
const client = new DocumentProcessorServiceClient({projectId, keyFilename});
async function start(encodedImage) {
console.log("Google AI Started")
const name = `projects/${projectId}/locations/${location}/processors/${processor}`;
const request = {
name,
document: {
content: encodedImage,
mimeType: 'application/pdf',
},
}
try {
const [result] = await client.processDocument(request);
const { document } = result;
const { text } = document;
const getText = textAnchor => {
if (!textAnchor.textSegments || textAnchor.textSegments.length === 0) {
return '';
}
// First shard in document doesn't have startIndex property
const startIndex = textAnchor.textSegments[0].startIndex || 0;
const endIndex = textAnchor.textSegments[0].endIndex;
return text.substring(startIndex, endIndex);
};
const [page1] = document;
const { paragraphs } = page1;
for (const paragraph of paragraphs) {
const paragraphText = getText(paragraph.layout.textAnchor);
console.log(`Paragraph text:\n${paragraphText}`);
}
return paragraphs;
}
catch (error) {
console.error(error);
}
}
module.exports = {
start
}
Image encoding is here
const {start: google} = require('./document-ai/index')
if (mimeType === 'application/pdf') {
pdf = true;
encoded = Buffer.from(file).toString('base64');
}
await google(encoded);
In result i get this error
Google AI Started
Error: 3 INVALID_ARGUMENT: Request contains an invalid argument.
at Object.callErrorFromStatus (C:\Users\NIKIGAN\WebstormProjects\papper-project\server\node_modules\google-gax\node_modules\#grpc\grpc-js\build\src\call.js:31:26)
at Object.onReceiveStatus (C:\Users\NIKIGAN\WebstormProjects\papper-project\server\node_modules\google-gax\node_modules\#grpc\grpc-js\build\src\client.js:176:52)
at Object.onReceiveStatus (C:\Users\NIKIGAN\WebstormProjects\papper-project\server\node_modules\google-gax\node_modules\#grpc\grpc-js\build\src\client-interceptors.js:342:141)
at Object.onReceiveStatus (C:\Users\NIKIGAN\WebstormProjects\papper-project\server\node_modules\google-gax\node_modules\#grpc\grpc-js\build\src\client-interceptors.js:305:181)
at C:\Users\NIKIGAN\WebstormProjects\papper-project\server\node_modules\google-gax\node_modules\#grpc\grpc-js\build\src\call-stream.js:124:78
at processTicksAndRejections (internal/process/task_queues.js:79:11) {
code: 3,
details: 'Request contains an invalid argument.',
metadata: Metadata {
internalRepr: Map { 'grpc-server-stats-bin' => [Array] },
options: {}
},
note: 'Exception occurred in retry method that was not classified as transient'
}
What invalid arguments do I have in my request?
Environment details
OS: Windows 10
Node.js version: 12.18.3
npm version: 6.14.8
#google-cloud/documentai version: 2.2.1
I've strugglid with this as well and the solution is quite simple as it turns out: you have to set the parameter apiEndpoint when your location is not "us".
Here's an example for location "eu":
const client = new DocumentProcessorServiceClient({
keyFilename,
apiEndpoint: 'eu-documentai.googleapis.com'
});
More information here: GitHub: googleapis /
nodejs-document-ai
How can i check user permission ,client permission , add throttling and define args in exports like commando does
my message event looks like this
client.on('message', async (message) => {
if (message.author.bot) return;
if (!message.guild) return;
let prefix
await db.collection('guilds').doc(message.guild.id).get().then((q) => {
if (q.exists) {
prefix = q.data().prefix || config1.prefix_mention;
} else {
prefix = "." || config1.prefix_mention;
}
})
const prefixRegex = new RegExp(`^(<#!?${client.user.id}>|${escapeRegex(prefix)})\\s*`);
if (!prefixRegex.test(message.content)) return;
const [ matchedPrefix ] = message.content.match(prefixRegex);
const args = message.content.slice(matchedPrefix.length).trim().split(/ +/g);
const cmd = args.shift().toLowerCase();
if (cmd.length === 0) return;
let command = client.commands.get(cmd);
if (!command) command = client.commands.get(client.aliases.get(cmd));
if (!message.channel.permissionsFor(client.user).has("SEND_MESSAGES")) return;
if (command)
command.run(client, message, args, db);
})
how can i check other permission like example
name: 'osu',
group: 'search',
memberName: 'osu',
description: 'Responds with information on an osu! user.',
clientPermissions: ["EMBED_LINKS","SEND_MESSAGES"],
userPermissions:['VIEW_CHANNEL'],
args: [
{
key: 'user',
prompt: 'What user would you like to get information on?',
type: 'string'
}
],
async run(client ,message ,args) {
//some code here
}
You can get client.user permissions and message.member permissions for message.channel and then check it with has.
About throttling , you can use cooldowns. This is the nice guide how to use it.
const { Permissions } = require('discord.js');
if(command.clientPermissions.length > 0) {
let clientChannelPermissions = message.channel.permissionsFor(message.guild.me);
clientChannelPermissions = new Permissions(clientChannelPermissions.bitfield);
if(!clientChannelPermissions.has(command.clientPermissions)) {
let missingPermissions = command.clientPermissions.filter(perm => clientChannelPermissions.has(perm) === false).join(', ')
return message.reply(`I can`t execute this command, missing permissions for ${missingPermissions}`)
}
}
if(command.userPermissions.length > 0) {
let memberChannelPermissions = message.channel.permissionsFor(message.member);
memberChannelPermissions = new Permissions(memberChannelPermissions.bitfield);
if(!memberChannelPermissions.has(command.clientPermissions)) {
let missingPermissions = command.clientPermissions.filter(perm => memberChannelPermissions.has(perm) === false).join(', ')
return message.reply(`I can`t execute this command, you missing permissions for ${missingPermissions}`)
}
}
Im getting a unexpected token, but I'm not sure what I'm doing wrong.
I tried to delete all modules and then renstall them but that didnt help
import { Client } from 'discord.js';
const client = new Client();
var GphApiClient = require('giphy-js-sdk-core')
client = GphApiClient("MyAPIkey");
client.once('ready', () => {
console.log('Ready!');
});
client.on('message', message => {
if (message.content.startsWith(`${prefix}!send`)) {
giphy.search('gifs', {"q": "cats"})
.then((response) => {
var totalResponses = response.data.length;
var responseIndex = Math.floor((Math.random() * 10) + 1) %
totalResponses;
var responseFinal = response.data[responseIndex];
message.channel.send("Kapo on teel", {
files: [responseFinal.images.fixed_height.url]
})
})
};
})
This is the error I was getting:
SyntaxError: Unexpected token {
at Module._compile (internal/modules/cjs/loader.js:811:22)
I think your syntax error is because you were trying to use ES6 modules (eg: import/export) without using something to transpile (eg: babel). There's more on that here if you're interested. In other words, I don't think you can use import. You have to use require. I also fixed the issues with client being defined multiple times. However, this code below still won't work because prefix was never defined anywhere.
const { Client } = require('discord.js');
var GphApiClient = require('giphy-js-sdk-core')
const discordClient = new Client();
giphyClient = GphApiClient('MyAPIkey');
discordClient.once('ready', () => {
console.log('Ready!');
});
discordClient.on('message', message => {
if (message.content.startsWith(`${prefix}!send`)) {
giphyClient.search('gifs', { "q": "cats" })
.then((response) => {
const totalResponses = response.data.length;
const responseIndex = Math.floor((Math.random() * 10) + 1) % totalResponses;
const responseFinal = response.data[responseIndex];
message.channel.send("Kapo on teel", {
files: [responseFinal.images.fixed_height.url]
});
})
} else {
console.log(`message doesn't start with ${prefix}!send`)
}
});