Related
Code:
const { EmbedBuilder, ActionRowBuilder, SelectMenuBuilder } = require("discord.js");
const { readdirSync } = require("fs");
const client = require("../../index");
const config = require("../../botconfig");
const create_menu = require("../../models/helpMenu.js");
const prefixSchema = require("../../models/prefix");
module.exports = {
name: "help",
description: "Displays all available command categories!",
aliases: [],
usage: "<command> or <category>",
run: async (client, interaction, message, args, db) => {
//try {
const data = await prefixSchema.findOne({ Guild: message.guildId });
if (data) {
let categories = [];
let cots = [];
if (!args[0]) {
let ignored = ["Giveaway", "Owner"];
const emoji = {
Action: "🤗",
Admin: "🔑",
Birthday: "🎂",
Fun: "🎮",
Giveaway: "🎉",
Image: "🖼️",
Minigame: "🎲",
Miscellaneous: "⚙️",
Moderation: "🛡️",
Owner: "👑",
Ticket: "🎫",
};
let cmdCategory = [];
readdirSync("./commands/").forEach((dir) => {
if (ignored.includes(dir)) return;
const commands = readdirSync(`./commands/${dir}/`).filter((file) => file.endsWith(".js"));
if (ignored.includes(dir)) return;
const name = `${emoji[dir]} - ${dir}`;
let categoryName = dir;
let categoryDir = new Object();
categoryDir = {
name: name,
value: "",
inline: true,
};
categories.push(categoryDir);
cmdCategory.push(categoryName);
});
const embed = new EmbedBuilder()
.setTitle("__Crimson's Help Menu__")
.setDescription(`>>> Default Prefix: \`${config.defaultPrefix}\`\nServer Prefix: \`${data.Prefix}\``)
.setThumbnail(client.user.displayAvatarURL())
.addFields(categories)
.setColor("#EE1C25")
.setFooter({ text: "Navigate through the embeds using the provided menu below.", iconURL: message.author.displayAvatarURL() })
.setTimestamp();
let menus = create_menu(cmdCategory);
return message.reply({ embeds: [embed], components: menus.smenu, allowedMentions: { repliedUser: true } }).then((msg) => {
const menuID = menus.sid;
const select = async (interaction) => {
if (interaction.customId != menuID) return;
let { values } = interaction;
let value = values[0];
let commands2 = [];
readdirSync("./commands/").forEach((dir) => {
if (dir.toLowerCase() !== value.toLowerCase()) return;
const commands = readdirSync(`./commands/${dir}/`).filter((file) => file.endsWith(".js"));
const cmds = commands.map((command) => {
let file = require(`../../commands/${dir}/${command}`);
if (!file.name) return "No command name.";
let name = file.name.replace(".js", "");
if (client.commands.get(name).hidden) return;
let emoji = client.commands.get(name).emoji;
let emoji2 = emoji ? `${emoji} ` : "• ";
let obj = { cname: `${emoji2}\`${name}\`` };
return obj;
});
let dota = new Object();
cmds.map((co) => {
if (co == undefined) return;
dota = {
name: `${cmds.length === 0 ? "Processing..." : co.cname}`,
value: "",
inline: false,
};
commands2.push(dota);
});
cots.push(dir.toLowerCase());
});
if (cots.includes(value.toLowerCase())) {
const cmdEmbed = new EmbedBuilder()
.setTitle(`__${value.charAt(0) + value.slice(1)} Commands__`)
.addFields(commands2)
.setColor("#EE1C25");
await interaction.deferUpdate();
return interaction.message.edit({ embeds: [cmdEmbed], components: menus.smenu, allowedMentions: { repliedUser: true } });
}
};
const filter = (interaction) => {
if (interaction.user.id === message.author.id) return true;
return interaction.reply({ content: "<:CL_VoteCross:781265541804720148> You cannot use this menu.", ephemeral: true });
};
const collector = msg.createMessageComponentCollector({ filter, componentType: "SelectMenu" });
collector.on("collect", select);
collector.on("end", () => null);
});
} else {
let commands2 = [];
readdirSync("./commands/").forEach((dir) => {
if (dir.toLowerCase() !== args[0].toLowerCase()) return;
const commands = readdirSync(`./commands/${dir}/`).filter((file) => file.endsWith(".js"));
const cmds = commands.map((command) => {
let file = require(`../../commands/${dir}/${command}`);
if (!file.name) return "I was unable to fetch the requested command.";
let name = file.name.replace(".js", "");
if (client.commands.get(name).hidden) return;
let emoji = client.commands.get(name).emoji;
let emoji2 = emoji ? `${emoji} ` : "";
let obj = { cname: `${emoji2}\`${name}\`` };
return obj;
});
let dota = new Object();
cmds.map((co) => {
if (co == undefined) return;
dota = {
name: `${cmds.length === 0 ? "In progress..." : "• " + co.cname}`,
value: "",
inline: true,
};
commands2.push(dota);
});
cots.push(dir.toLowerCase());
});
const command = client.commands.get(args[0].toLowerCase()) || client.commands.find((c) => c.aliases && c.aliases.includes(args[0].toLowerCase()));
if (cots.includes(args[0].toLowerCase())) {
const cmdEmbed = new EmbedBuilder()
.setTitle(`__${args[0].charAt(0) + args[0].slice(1)} commands__`)
.addFields(commands2)
.setColor("#EE1C25");
return message.reply({ embeds: [cmdEmbed], allowedMentions: { repliedUser: true } });
}
if (!command) {
const noCmdEmbed = new EmbedBuilder()
.setTitle("Unknown Command/Category")
.setDescription(`The command or category you are trying to find is not in our database, if you think this is a mistake.. please let us know!\n\n\n**Options**\n\`\`\`${config.defaultPrefix}help <category name>\`\`\` \`\`\`${config.defaultPrefix}help <command name>\`\`\``)
.setFooter({ text: `Command Requested by ${message.author.tag}`, iconURL: message.author.displayAvatarURL({ dynamic: true }) })
.setTimestamp()
.setColor("#EE1C25");
return await message.reply({ embeds: [noCmdEmbed], allowedMentions: { repliedUser: true } });
}
const cmdDetailsEmbed = new EmbedBuilder()
.setThumbnail(client.user.displayAvatarURL())
.setDescription(`**Command:** \`${command.name}\``)
.addFields(
{
name: "Usage",
value: command.usage
? `\`\`\`${config.defaultPrefix}${command.name} ${command.usage}\`\`\``
: "`No usage for this command`",
},
{
name: "Description",
value: command.description
? `\`\`\`${command.description}\`\`\``
: "`No description for this command`",
},
{
name: "Aliases",
value: command.aliases
? `\`\`\`${command.aliases.join(", ")}\`\`\``
: "`No aliases for this command`",
}
)
.setFooter({ text: `Command Requested by ${message.author.tag}`, iconURL: message.author.displayAvatarURL({ dynamic: true }) })
.setTimestamp()
.setColor("#EE1C25");
return await message.reply({ embeds: [cmdDetailsEmbed], allowedMentions: { repliedUser: true } });
}
} else if (!data) {
let categories = [];
let cots = [];
if (!args[0]) {
let ignored = ["Giveaway", "Owner"];
const emoji = {
Action: "🤗",
Admin: "🔑",
Birthday: "🎂",
Fun: "🎮",
Giveaway: "🎉",
Image: "🖼️",
Minigame: "🎲",
Miscellaneous: "⚙️",
Moderation: "🛡️",
Owner: "👑",
Ticket: "🎫",
};
let cmdCategory = [];
readdirSync("./commands/").forEach((dir) => {
if (ignored.includes(dir)) return;
const commands = readdirSync(`./commands/${dir}/`).filter((file) => file.endsWith(".js"));
if (ignored.includes(dir)) return;
const name = `${emoji[dir]} - ${dir}`;
let categoryName = dir;
let categoryDir = new Object();
categoryDir = {
name: name,
value: "",
inline: true, //true
};
categories.push(categoryDir);
cmdCategory.push(categoryName);
});
const embed = new EmbedBuilder()
.setTitle("__Crimson's Help Menu__")
.setDescription(`>>> Default Prefix: \`${config.defaultPrefix}\`\nServer Prefix: \`none\``)
.setThumbnail(client.user.displayAvatarURL())
.addFields(categories)
.setColor("#EE1C25")
.setFooter({ text: "Navigate through the embeds using the provided menu below.", iconURL: message.author.displayAvatarURL() })
.setTimestamp();
let menus = create_menu(cmdCategory);
return message.reply({ embeds: [embed], components: menus.smenu, allowedMentions: { repliedUser: true } }).then((msg) => {
const menuID = menus.sid;
const select = async (interaction) => {
if (interaction.customId != menuID) return;
let { values } = interaction;
let value = values[0];
let commands2 = [];
readdirSync("./commands/").forEach((dir) => {
if (dir.toLowerCase() !== value.toLowerCase()) return;
const commands = readdirSync(`./commands/${dir}/`).filter((file) => file.endsWith(".js"));
const cmds = commands.map((command) => {
let file = require(`../../commands/${dir}/${command}`);
if (!file.name) return "No command name.";
let name = file.name.replace(".js", "");
if (client.commands.get(name).hidden) return;
let emoji = client.commands.get(name).emoji;
let emoji2 = emoji ? `${emoji} ` : "• ";
let obj = { cname: `${emoji2}\`${name}\`` };
return obj;
});
let dota = new Object();
cmds.map((co) => {
if (co == undefined) return;
dota = {
name: `${cmds.length === 0 ? "Processing..." : co.cname}`,
value: "",
inline: false, //true
};
commands2.push(dota);
});
cots.push(dir.toLowerCase());
});
if (cots.includes(value.toLowerCase())) {
const cmdEmbed = new EmbedBuilder()
.setTitle(`__${value.charAt(0) + value.slice(1)} Commands__`)
.addFields(commands2)
.setColor("#EE1C25");
await interaction.deferUpdate();
return interaction.message.edit({ embeds: [cmdEmbed], components: menus.smenu, allowedMentions: { repliedUser: true } });
}
};
const filter = (interaction) => {
if (interaction.user.id === message.author.id) return true;
return interaction.reply({ content: "<:CL_VoteCross:781265541804720148> This menu is not for you.", ephemeral: true });
};
const collector = msg.createMessageComponentCollector({ filter, componentType: "SelectMenu" });
collector.on("collect", select);
collector.on("end", () => null);
});
} else {
let commands2 = [];
readdirSync("./commands/").forEach((dir) => {
if (dir.toLowerCase() !== args[0].toLowerCase()) return;
const commands = readdirSync(`./commands/${dir}/`).filter((file) => file.endsWith(".js"));
const cmds = commands.map((command) => {
let file = require(`../../commands/${dir}/${command}`);
if (!file.name) return "I was unable to fetch the requested command.";
let name = file.name.replace(".js", "");
if (client.commands.get(name).hidden) return;
let emoji = client.commands.get(name).emoji;
let emoji2 = emoji ? `${emoji} ` : "";
let obj = { cname: `${emoji2}\`${name}\`` };
return obj;
});
let dota = new Object();
cmds.map((co) => {
if (co == undefined) return;
dota = {
name: `${cmds.length === 0 ? "In progress..." : "• " + co.cname}`,
value: "",
inline: false, //true
};
commands2.push(dota);
});
cots.push(dir.toLowerCase());
});
const command = client.commands.get(args[0].toLowerCase()) || client.commands.find((c) => c.aliases && c.aliases.includes(args[0].toLowerCase()));
if (cots.includes(args[0].toLowerCase())) {
const cmdEmbed = new EmbedBuilder()
.setTitle(`__${args[0].charAt(0) + args[0].slice(1)} commands__`)
.addFields(commands2)
.setColor("#EE1C25");
return message.reply({ embeds: [cmdEmbed], allowedMentions: { repliedUser: true } });
}
if (!command) {
const noCmdEmbed = new EmbedBuilder()
.setTitle("Unknown Command/Category")
.setDescription(`The command or category you are trying to find is not in our database, if you think this is a mistake.. please let us know!\n\n\n**Options**\n\`\`\`${config.defaultPrefix}help <category name>\`\`\` \`\`\`${config.defaultPrefix}help <command name>\`\`\``)
.setFooter({ text: `Command Requested by ${message.author.tag}`, iconURL: message.author.displayAvatarURL({ dynamic: true }) })
.setTimestamp()
.setColor("#EE1C25");
return await message.reply({ embeds: [noCmdEmbed], allowedMentions: { repliedUser: true } });
}
const cmdDetailsEmbed = new EmbedBuilder()
.setThumbnail(client.user.displayAvatarURL())
.setDescription(`**Command:** \`${command.name}\``)
.addFields(
{
name: "Usage",
value: command.usage
? `\`\`\`${config.defaultPrefix}${command.name} ${command.usage}\`\`\``
: "`No usage for this command`",
},
{
name: "Description",
value: command.description
? `\`\`\`${command.description}\`\`\``
: "`No description for this command`",
},
{
name: "Aliases",
value: command.aliases
? `\`\`\`${command.aliases.join(", ")}\`\`\``
: "`No aliases for this command`",
})
.setFooter({ text: `Command Requested by ${message.author.tag}`, iconURL: message.author.displayAvatarURL({ dynamic: true }) })
.setTimestamp()
.setColor("#EE1C25");
return await message.reply({ embeds: [cmdDetailsEmbed], allowedMentions: { repliedUser: true } });
}
}
//} catch (err) {
//console.log(err)
//return await message.reply(`\`${err}\``);
//}
},
};
Error:
/app/commands/Miscellaneous/help.js:234
if (!args[0]) {
^
TypeError: Cannot read properties of undefined (reading '0')
I’m still changing stuff over to v14 of discord, and I appear to keep breaking/not understanding half the errors that I keep getting and some past one such as the one below about message.guild.id.
Other Error:
const data = await prefixSchema.findOne({ Guild: message.guild.id });
TypeError: Cannot read properties of undefined (reading 'id')
Any assistance would be greatly appreciated!
index.js
/*Discord V14 Setup*/
const { Client, Routes, GatewayIntentBits, Partials, Collection, EmbedBuilder, MessageAttachment, ActionRowBuilder, ButtonBuilder } = require('discord.js'),
botconfig = require('./botconfig.js'),
ownerID = botconfig.ownerID,
client = new Client({ allowedMentions: { parse: ['roles', 'everyone', 'users'], repliedUser: false }, partials: [Partials.Message, Partials.Channel, Partials.Reaction], intents: [GatewayIntentBits.MessageContent, GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildBans, GatewayIntentBits.GuildIntegrations, GatewayIntentBits.GuildWebhooks, GatewayIntentBits.GuildInvites, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildPresences, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessageReactions, GatewayIntentBits.GuildMessageTyping, GatewayIntentBits.DirectMessages, GatewayIntentBits.DirectMessageReactions, GatewayIntentBits.DirectMessageTyping] });
/*End of Discord V14 Setup*/
/*Slash Commands*/
const { REST } = require('#discordjs/rest');
const fs = require('fs');
/*End of Slash Commands*/
/*Packages*/
const { DiscordTogether } = require('discord-together');
const { Captcha } = require('captcha-canvas');
const { readdirSync } = require('fs');
const ascii = require('ascii-table');
const Canvacord = require('canvacord');
const chalk = require('chalk');
const quick = require('quick.db');
/*End of Packages*/
/*Models for Client*/
const { events } = require('./handlers/events');
//const { slashCommands } = require('./handlers/slash');
const leaveSchema = require('./models/leaveLogs');
const loggerHandler = require('./handlers/logger.js');
const modlogsSchema = require('./models/modLogs');
const prefixSchema = require('./models/prefix');
const welcomeSchema = require('./models/joinLogs');
/*End of Models for Client*/
/*Configurations*/
module.exports = client;
client.aliases = new Collection();
client.botconfig = botconfig;
client.commands = new Collection();
client.db = quick.db;
client.discordTogether = new DiscordTogether(client);
client.embed = new EmbedBuilder();
client.logger = new loggerHandler();
client.slash = new Collection();
client.snipes = new Collection();
/*End of Configurations*/
/*Client categories*/
client.categories = fs.readdirSync('./commands/');
['command'].forEach(handler => {
require(`./handlers/${handler}`)(client);
});
/*End of Client categories*/
/*MongoDB Setup*/
const mongoose = require('mongoose');
mongoose.connect(botconfig.db_uri, { useUnifiedTopology: true, useNewUrlParser: true }).then(client.logger.log('READY', 'Crimson has successfully connected to MongoDB!'));
/*End of MongoDB Setup*/
/*reaction-roles*/
client.on('messageReactionAdd', async (reaction, member, guild, message) => {
if (reaction.message.partial) await reaction.message.fetch();
if (reaction.partial) await reaction.fetch();
if (member.bot) return;
if (!reaction.message.guild) return;
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '📣') {
await reaction.message.guild.members.cache.get(member.id).roles.add('746023960201920523');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '🤖') {
await reaction.message.guild.members.cache.get(member.id).roles.add('857984203346018305');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '❗') {
await reaction.message.guild.members.cache.get(member.id).roles.add('858546783823462430');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '🏅') {
await reaction.message.guild.members.cache.get(member.id).roles.add('889927145206468669');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '📊') {
await reaction.message.guild.members.cache.get(member.id).roles.add('746024349135405199');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '🎉') {
await reaction.message.guild.members.cache.get(member.id).roles.add('746024204989759632');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '🗓️') {
await reaction.message.guild.members.cache.get(member.id).roles.add('889927622774124574');
}
}
if (reaction.message.id === '924001444980478012') {
if (reaction.emoji.name === '<a:CL_CheckMark:858853559940808724>');
await reaction.users.remove(member.id);
const captcha = new Captcha();
captcha.async = true;
captcha.addDecoy();
captcha.drawTrace();
captcha.drawCaptcha();
const captchaAttachment = new MessageAttachment(await captcha.png, 'CrimsonCaptcha.png');
const captchaEmbed = new EmbedBuilder()
.setTitle('Crimson\'s Lounge - Checkpoint 📍')
.setDescription('Solve the captcha code to gain access to `Crimson\'s Lounge`')
.setImage('attachment://CrimsonCaptcha.png')
.setColor('EE1C25')
.setFooter('This code will expire in 5 minutes')
.setTimestamp();
const msg = await member.send({ embeds: [captchaEmbed], files: [captchaAttachment] }).catch(() => null);
const filter = message => {
if (message.author.id !== member.id) return;
if (message.content === captcha.text) return true;
else member.send('Incorrect Captcha, Please try again.');
};
try {
const response = await msg.channel.awaitMessages({ filter, max: 1, time: 300000, errors: ['time'] });
if (response) {
const completeCaptchaEmbed = new EmbedBuilder()
.setTitle('<:CL_VoteTick:781265299609223188> Verification Complete') //✅
.setDescription('You have successfully gained access to `Crimson\'s Lounge`.')
.setColor('GREEN')
.setTimestamp();
member.send({ embeds: [completeCaptchaEmbed] });
await reaction.message.guild.members.cache.get(member.id).roles.add('828466951201751071');
await reaction.message.guild.members.cache.get(member.id).roles.remove('903403824818028555');
}
if (response === false) {
const failedCaptchaEmbed = new EmbedBuilder()
.setTitle('<:CL_VoteCross:781265541804720148> Verification Failed') //❌
.setDescription('> You did not complete the captcha in the given time (5 mins)\n\n`You were kicked from `Crimson\'s Lounge`, feel free to join us again with the click of the magical button below!`')
.setColor('RED')
.setFooter('If you are having trouble verifying, let our support team know.')
.setTimestamp();
member.kick();
let failedBtn = new MessageButton()
.setStyle('LINK')
.setURL('https://discord.gg/DFZv2Zh')
.setLabel('Support');
let row = new MessageActionRow().addComponents([failedBtn]);
const targetMember = await member.send({ embeds: [failedCaptchaEmbed], components: [row] });
const filter = button => button.clicker.user.id === member.user.id;
const collector = targetMember.createMessageComponentCollector(filter);
}
} catch (err) {
console.log(err);
}
}
});
client.on('messageReactionRemove', async (reaction, user) => {
if (reaction.message.partial) await reaction.message.fetch();
if (reaction.partial) await reaction.fetch();
if (user.bot) return;
if (!reaction.message.guild) return;
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '📣') {
await reaction.message.guild.members.cache.get(user.id).roles.remove('746023960201920523');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '🤖') {
await reaction.message.guild.members.cache.get(user.id).roles.remove('857984203346018305');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '❗') {
await reaction.message.guild.members.cache.get(user.id).roles.remove('858546783823462430');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '🏅') {
await reaction.message.guild.members.cache.get(user.id).roles.add('889927145206468669');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '📊') {
await reaction.message.guild.members.cache.get(user.id).roles.remove('746024349135405199');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '🎉') {
await reaction.message.guild.members.cache.get(user.id).roles.remove('746024204989759632');
}
}
if (reaction.message.id === '931609070501265408') {
if (reaction.emoji.name === '🗓️') {
await reaction.message.guild.members.cache.get(user.id).roles.remove('889927622774124574');
}
}
});
/*End of Reaction Roles*/
/*Welcome System*/
client.on('guildMemberAdd', async (member, guild) => {
welcomeSchema.findOne({ Guild: member.guild.id }, async (err, data) => {
if (!data) return;
const user = member.user;
const channel = member.guild.channels.cache.get(data.Channel);
var welcomeMessage = [`**${user.username}** Just landed.`, `Yay you made it, **${user.username}**!`, `Good to see you, **${user.username}**.`, `**${user.username}** just slid into the server.`, `**${user.username}** joined the party.`, `Welcome, **${user.username}**. We hope you brought pizza.`, `**${user.username}** hopped into the server.`, `**${user.username}** just showed up!`, `Glad you're here, **${user.username}**.`, `Everyone welcome **${user.username}**!`, `**${user.username}** is here.`, `A wild **${user.username}** appeared.`];
const welcomeEmbed = new EmbedBuilder()
.setAuthor(`${user.tag}`, user.displayAvatarURL())
.setThumbnail(user.displayAvatarURL())
.setDescription(`<:CL_JoinArrow:781262371514875904> ${welcomeMessage[Math.floor(Math.random() * welcomeMessage.length)]}`)
.setFooter(`Member #${member.guild.memberCount}`, member.guild.iconURL())
.setColor('GREEN');
channel.send({ embeds: [welcomeEmbed] });
if (member.guild.id == '705344500507345017') {
const role = member.guild.roles.cache.get('903403824818028555');
await member.roles.add(role.id);
}
});
});
client.on('guildMemberRemove', async (member, guild) => {
leaveSchema.findOne({ Guild: member.guild.id }, async (err, data) => {
if (!data) return;
const user = member.user;
const channel = member.guild.channels.cache.get(data.Channel);
var leaveMessage = [`**${user.username}**, It's sad to see you go.`, `Come back soon, **${user.username}**.`, `It appears that **${user.username}** has parted ways.`, `**${user.username}** just took the leap of faith.`, `**${user.username}** left the party.`, `Goodbye, **${user.username}**.`, `**${user.username}** took the easy way out.`, `**${user.username}** has left us.`, `Glad you're here, **${user.username}**.`, `**${user.username}**, come back.. we already miss you :(`, `**${user.username}** has disappeared into the dark.`, `A wild **${user.username}** has disappeared.`];
const leaveEmbed = new EmbedBuilder()
.setAuthor(`${user.tag}`, user.displayAvatarURL())
.setThumbnail(user.displayAvatarURL())
.setDescription(`<:CL_LeaveArrow:781262397662167090> ${leaveMessage[Math.floor(Math.random() * leaveMessage.length)]}`)
.setFooter(`That leaves us with #${member.guild.memberCount} members`, member.guild.iconURL())
.setTimestamp()
.setColor('RED');
channel.send({ embeds: [leaveEmbed] });
});
});
/*End of welcome System*/
client.login(botconfig.token);
I'm making a bot for the betting platform: blaze.com
who sends betting signals to telegram
but it's giving an error in the token, even though I put the token in the .env, it's not working! who can help me?
.env.example
PORT = 3000
TOKEN = #####################
CHANNEL_NAME = -1772325150
DATABASE_URL="mysql://userDatabase:password#localhost:port/nameDatabase"
CreateBot.ts
import { Telegraf } from "telegraf"
import { ConfigsController } from "../useCases/configs/ConfigsController"
import { ConfigsUseCase } from "../useCases/configs/ConfigsUseCase"
import { CountsUseCase } from "../useCases/counts/CountsUseCase"
interface IMessage {
countGreen?: number
countRed?: number
color?: string
message: string
}
interface IDataCount {
id: string
countWhite: number
countGreen: number
countRed: number
countGale1: number
countGale2: number
totalWin?: number
totalSent?: number
percentageWin?: number
}
class Bot {
start: string
bots: Telegraf
constructor() {
this.start = "Bot On! 🟢"
this.bots = new Telegraf (process.env.TOKEN)
}
public async inital() {
try {
this.bots.launch();
process.once("SIGINT", () => this.bots.stop("SIGINT"));
process.once("SIGTERM", () => this.bots.stop("SIGTERM"));
} catch (error) {
console.log("Error in connection of API!")
}
}
async sendMessage({ countGreen, countRed, color, message }: IMessage) {
try {
const messageId = await this.bots.telegram.sendMessage(process.env.CHANNEL_NAME, message, { parse_mode: 'HTML' })
return messageId.message_id
} catch (error) {
console.log("Error send message!")
}
}
async deleteMessageWithID(messageID: any) {
try {
await this.bots.telegram.deleteMessage(process.env.CHANNEL_NAME, messageID)
} catch (error) {
console.log("Error in delete message!")
}
}
async commandBot() {
this.bots.start(async (ctx) => {
await ctx.reply(`🤖 Bem vindo ao ${ctx.botInfo.first_name} 📣\n\n/padrao Ver as configurações do Bot.\n\n/config Cadastrar e alterar as configs do Bot.\n\n/resultado Envia relatório no canal.\n<i>Você pode passar uma data\nExemplo: '24/01/2022', se não vai\nser enviado com a data do dia.</i>\n\n/help Ajuda.`, { parse_mode: 'HTML' })
})
this.bots.help(async (ctx) => {
await ctx.reply(`🤖 Bot Comandos 📣\n\n/padrao Ver as configurações do Bot.\n\n/config Cadastrar e alterar as configs do Bot.\n\n/resultado Envia relatório no canal.\n<i>Você pode passar uma data\nExemplo: '24/01/2022', se não vai\nser enviado com a data do dia.</i>`, { parse_mode: 'HTML' })
})
this.bots.command("padrao", async (ctx) => {
const configUseCase = new ConfigsUseCase()
const configs = await configUseCase.show()
if (configs !== null) {
const { activo, standard } = await configUseCase.show()
await ctx.reply(`🤖 Bot Configs ⚙️\n\n<b>Bot:</b> ${activo ? "Ativado" : "Desativado"}\n<b>Padrão:</b> ${Number(standard)}`, { parse_mode: 'HTML' })
return
}
await ctx.reply(`Você precisa configurar seu bot\n\n/config`, { parse_mode: 'HTML' })
})
this.bots.command("resultado", async (ctx) => {
const [command, date] = ctx.message.text.split(" ")
const countUseCase = new CountsUseCase()
const data = await countUseCase.getCounts(date)
if (data.length === 0) {
console.log("Sem registro")
await ctx.reply(`📊 Resultados até agora! 📈\n\n⛔<b>Sem registro</b>\n\n✅Acertos: <b>0</b>\n❌Não Bateu: <b>0</b>\n\n🥇Primeira Entrada: <b>0</b>\n1️⃣Primeira Gale: <b>0</b>\n2️⃣Segunda Gale: <b>0</b>\n⚪Winn Branco: <b>0</b>\n\n <b>0% de aproveitamento!</b>`, { parse_mode: 'HTML' })
return
}
const { greenWhite, green, red, gale1, gale2, totalWin, totalSent, percentageWin } = await this.calculateCounts(data)
const message = `📊 Resultados até agora! 📈\n\n✅Acertos: <b>${totalWin}</b>\n❌Não Bateu: <b>${red}</b>\n\n🥇Primeira Entrada: <b>${green}</b>\n1️⃣Primeira Gale: <b>${gale1}</b>\n2️⃣Segunda Gale: <b>${gale2}</b>\n⚪Winn Branco: <b>${greenWhite}</b>\n\n <b>${Math.round(100 - percentageWin)}% de aproveitamento!</b>`
await this.sendMessage({ message })
await ctx.replyWithHTML(`📨 <b>Relatório enviado!</b>`)
return
})
this.bots.command("config", async (ctx) => {
const configUseCase = new ConfigsUseCase()
const configs = await configUseCase.show()
const configsController = new ConfigsController()
const respone = ctx.message.text.split(" ")
const [_, botName, password, newDefault, activo] = ctx.message.text.split(" ")
const newActivo = activo === "ativado" ? true : false
if (respone.length !== 5) {
await ctx.reply("⚠️ <b>Parametros Errados!</b>\n\nEnviar da seguinte maneira:\n\n<b>Comando:</b> /config\n<b>Bot:</b> nome do seu bot\n<b>Senha:</b> senha de acesso\n<b>Padrão:</b> número do seu padrão, ex. 3\n<b>Ativo:</b> ativado ou desativado\n\n<b>Exemplo:</b> /config blaze-bot abc123 4 ativado", { parse_mode: 'HTML' })
return
}
switch (activo) {
case "ativado":
case "desativado":
if (configs === null) {
await configsController.create({ name: botName, standard: Number(newDefault), activo: newActivo, password: password.toString() })
await ctx.reply(`⚠️ Atenção ⚠️\n\nCadastro realizado!`, { parse_mode: 'HTML' })
return
}
if (configs.password === password && configs.name === botName) {
await configsController.create({ name: botName, standard: Number(newDefault), activo: newActivo, password: password.toString() })
await ctx.reply(`⚠️ Atenção ⚠️\n\nParâmetros Alterados\n\n<b>Bot:</b> ${newActivo ? "Ativado" : "Desativado"}\n<b>Padrão:</b> ${Number(newDefault)}`, { parse_mode: 'HTML' })
return
}
await ctx.reply(`⚠️ Atenção ⚠️\n\nNome do Bot ou Senha errada!`, { parse_mode: 'HTML' })
break;
default:
await ctx.reply("⚠️ Atenção ⚠️\n\nInforme se o BOT está \n<b>ativado</b> ou <b>desativado</b>", { parse_mode: 'HTML' })
break;
}
})
}
async calculateCounts(data: Array<IDataCount>) {
let greenWhite = null
let green = null
let red = null
let gale1 = null
let gale2 = null
data.forEach(async counts => {
greenWhite = greenWhite + counts.countWhite
green = green + counts.countGreen
red = red + counts.countRed
gale1 = gale1 + counts.countGale1
gale2 = gale2 + counts.countGale2
})
let totalWin = green + greenWhite + gale1 + gale2
let totalSent = totalWin + red
let percentageWin = Math.round((red * 100) / totalSent)
return {
greenWhite,
green,
red,
gale1,
gale2,
totalWin,
totalSent,
percentageWin
}
}
}
export { Bot }
I already changed the bot token and it still won't:
Maybe you don't need the answer anymore, but anyway
To make .env work, you have to install something like dotenv https://github.com/motdotla/dotenv
npm install dotenv --save
require('dotenv').config()
// or
import * as dotenv from 'dotenv' // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import
dotenv.config()
It loads environment variables from an .env file into process.env, so in your case,
this.bots = new Telegraf (process.env.TOKEN)
doesn't work, because it can't get data from process.env
im over here frying my brain to death trying to figure out how to prevent users from using someone elses selection menu, and i can't seem to fix that issue.. so here i am asking for some help smh.
i know it has something to do with the collector, but im not sure what it is.
I have asked around all over discord, but havent really had a straight forward answer on how to solve this issue because it gets annoying when you try to use a selection menu and then someone else comes along and it able to use the same frickin menu that you are trying to use, so i had enough of that crap and im just trying to find a way to prevent others from using each others menus and so on.
any help will be appreciated, just want it to ignore them or respond to them saying its not their menu or whatever.
const { MessageEmbed, Message, Client } = require("discord.js");
const { readdirSync } = require("fs");
const client = require("../../index");
const config = require("../../botconfig");
const create_menu = require("../../models/helpMenu.js");
module.exports = {
name: "help",
description: "Displays all available command categories!",
aliases: ["h"],
usage: "<command> or <category>",
run: async (client, message, args, db) => {
let categories = [];
let cots = [];
if (!args[0]) {
let ignored = ["Giveaway", "Economy", "Owner"];
const emoji = {
Action: "🤗",
Admin: "🔑",
Birthday: "🎂",
Economy: "💰",
Fun: "🎮",
Giveaway: "🎉",
Image: "🖼️",
Minigame: "🎲",
Miscellaneous: "⚙️",
Moderation: "🛡️",
Owner: "👑",
Ticket: "🎫",
};
let cmdCategory = [];
readdirSync("./commands/").forEach((dir) => {
if (ignored.includes(dir)) return;
const commands = readdirSync(`./commands/${dir}/`).filter((file) => file.endsWith(".js"));
if (ignored.includes(dir)) return;
const name = `${emoji[dir]} - ${dir}`;
let categoryName = dir;
let categoryDir = new Object();
categoryDir = {
name: name,
value: "",
inline: true,
};
categories.push(categoryDir);
cmdCategory.push(categoryName);
});
const embed = new MessageEmbed()
.setTitle("__Crimson's Help Menu__")
.setDescription(`>>> Default Prefix: \`${config.defaultPrefix}\`\nServer Prefix: \`Soon\``)
.setThumbnail(client.user.displayAvatarURL())
.addFields(categories)
.setColor("#EE1C25")
.setFooter("Navigate through the embeds using the provided menu below", message.author.displayAvatarURL())
.setTimestamp();
let menus = create_menu(cmdCategory);
return message
.reply({ embeds: [embed], components: menus.smenu, allowedMentions: { repliedUser: true } })
.then((msg) => {
const menuID = menus.sid;
const select = async (interaction) => {
if (interaction.customId != menuID) return;
let { values } = interaction;
let value = values[0];
let commands2 = [];
readdirSync("./commands/").forEach((dir) => {
if (dir.toLowerCase() !== value.toLowerCase()) return;
const commands = readdirSync(`./commands/${dir}/`).filter((file) => file.endsWith(".js"));
const cmds = commands.map((command) => {
let file = require(`../../commands/${dir}/${command}`);
if (!file.name) return "No command name.";
let name = file.name.replace(".js", "");
if (client.commands.get(name).hidden) return;
let emoji = client.commands.get(name).emoji;
let emoji2 = emoji ? `${emoji} ` : "• ";
let obj = { cname: `${emoji2}\`${name}\`` };
return obj;
});
let dota = new Object();
cmds.map((co) => {
if (co == undefined) return;
dota = {
name: `${cmds.length === 0 ? "Processing..." : co.cname}`,
value: "",
inline: true,
};
commands2.push(dota);
});
cots.push(dir.toLowerCase());
});
if (cots.includes(value.toLowerCase())) {
const cmdEmbed = new MessageEmbed()
.setTitle(`__${value.charAt(0) + value.slice(1)} Commands__`)
.addFields(commands2)
.setColor("#EE1C25");
await interaction.deferUpdate();
return interaction.message.edit({ embeds: [cmdEmbed], components: menus.smenu, allowedMentions: { repliedUser: true } });
}
};
const filter = (interaction) => {
return (!interaction.user.bot && interaction.user.id == message.author.id);
};
const collector = msg.createMessageComponentCollector({ filter, componentType: "SELECT_MENU" });
collector.on("collect", select);
collector.on("end", () => null);
});
} else {
let commands2 = [];
readdirSync("./commands/").forEach((dir) => {
if (dir.toLowerCase() !== args[0].toLowerCase()) return;
const commands = readdirSync(`./commands/${dir}/`).filter((file) => file.endsWith(".js"));
const cmds = commands.map((command) => {
let file = require(`../../commands/${dir}/${command}`);
if (!file.name) return "Unable to find requested command";
let name = file.name.replace(".js", "");
if (client.commands.get(name).hidden) return;
let emoji = client.commands.get(name).emoji;
let emoji2 = emoji ? `${emoji} ` : "";
let obj = { cname: `${emoji2}\`${name}\`` };
return obj;
});
let dota = new Object();
cmds.map((co) => {
if (co == undefined) return;
dota = {
name: `${cmds.length === 0 ? "In progress..." : "• " + co.cname}`,
value: "",
inline: true,
};
commands2.push(dota);
});
cots.push(dir.toLowerCase());
});
const command =
client.commands.get(args[0].toLowerCase()) ||
client.commands.find((c) => c.aliases && c.aliases.includes(args[0].toLowerCase()));
if (cots.includes(args[0].toLowerCase())) {
const cmdEmbed = new MessageEmbed()
.setTitle(`__${args[0].charAt(0) + args[0].slice(1)} commands__`)
.addFields(commands2)
.setColor("#EE1C25");
return message.reply({ embeds: [cmdEmbed], allowedMentions: { repliedUser: true } });
}
if (!command) {
const noCmdEmbed = new MessageEmbed()
.setTitle("Unknown Command/Category")
.setDescription(`The command or category you are trying to find is not in our database, if you think this is a mistake.. please let us know!\n\n\n**Options**\n\`\`\`${config.defaultPrefix}help <category name>\`\`\` \`\`\`${config.defaultPrefix}help <command name>\`\`\``)
.setFooter(`Command Requested by ${message.author.tag}`, message.author.displayAvatarURL({ dynamic: true }))
.setTimestamp()
.setColor("#EE1C25");
return await message.reply({ embeds: [noCmdEmbed], allowedMentions: { repliedUser: true } });
}
const cmdDetailsEmbed = new MessageEmbed()
.setThumbnail(client.user.displayAvatarURL())
.setDescription(`**Command:** \`${command.name}\``)
.addFields(
{
name: "Usage",
value: command.usage
? `\`\`\`${config.defaultPrefix}${command.name} ${command.usage}\`\`\``
: "`No usage for this command`",
},
{
name: "Description",
value: command.description
? `\`\`\`${command.description}\`\`\``
: "`No description for this command`",
},
{
name: "Aliases",
value: command.aliases
? `\`\`\`${command.aliases.join(", ")}\`\`\``
: "`No aliases for this command`",
}
)
.setFooter(`Command Requested by ${message.author.tag}`, message.author.displayAvatarURL({ dynamic: true }))
.setTimestamp()
.setColor("#EE1C25");
return await message.reply({ embeds: [cmdDetailsEmbed], allowedMentions: { repliedUser: true } });
}
},
};
Hi you can do that by adding
if(interaction.author !== message.author) return;
This means that if message.author is not the interaction member it will return nothing.
i want collect news from different channels and echo them in a second channel, with the code i can read channels(not all but most).
I stuck now on the echo problem and have no clue about how i can do this, mtproto is completely new to me, thanks.
Im using the following code i have from another stackoverflow question.
const { MTProto, getSRPParams } = require('#mtproto/core');
const prompts = require('prompts');
const api_id = 'xxxxx';
const api_hash = 'xxxxx';
async function getPhone() {
return (await prompts({
type: 'text',
name: 'phone',
message: 'Enter your phone number:'
})).phone
}
async function getCode() {
// you can implement your code fetching strategy here
return (await prompts({
type: 'text',
name: 'code',
message: 'Enter the code sent:',
})).code
}
async function getPassword() {
return (await prompts({
type: 'text',
name: 'password',
message: 'Enter Password:',
})).password
}
const mtproto = new MTProto({
api_id,
api_hash,
});
function startListener() {
console.log('[+] starting listener')
mtproto.updates.on('updates', ({ updates }) => {
const newChannelMessages = updates.filter((update) => update._ === 'updateNewChannelMessage').map(({ message }) => message) // filter `updateNewChannelMessage` types only and extract the 'message' object
for (const message of newChannelMessages) {
// printing new channel messages
console.log(`[${message.to_id.channel_id}] ${message.message}`)
}
});
}
// checking authentication status
mtproto
.call('users.getFullUser', {
id: {
_: 'inputUserSelf',
},
})
.then(startListener) // means the user is logged in -> so start the listener
.catch(async error => {
// The user is not logged in
console.log('[+] You must log in')
const phone_number = await getPhone()
mtproto.call('auth.sendCode', {
phone_number: phone_number,
settings: {
_: 'codeSettings',
},
})
.catch(error => {
if (error.error_message.includes('_MIGRATE_')) {
const [type, nextDcId] = error.error_message.split('_MIGRATE_');
mtproto.setDefaultDc(+nextDcId);
return sendCode(phone_number);
}
})
.then(async result => {
return mtproto.call('auth.signIn', {
phone_code: await getCode(),
phone_number: phone_number,
phone_code_hash: result.phone_code_hash,
});
})
.catch(error => {
if (error.error_message === 'SESSION_PASSWORD_NEEDED') {
return mtproto.call('account.getPassword').then(async result => {
const { srp_id, current_algo, srp_B } = result;
const { salt1, salt2, g, p } = current_algo;
const { A, M1 } = await getSRPParams({
g,
p,
salt1,
salt2,
gB: srp_B,
password: await getPassword(),
});
return mtproto.call('auth.checkPassword', {
password: {
_: 'inputCheckPasswordSRP',
srp_id,
A,
M1,
},
});
});
}
})
.then(result => {
console.log('[+] successfully authenticated');
// start listener since the user has logged in now
startListener()
});
})
So i'm building a site backend for a project using strapi. A requirement for the site backend is there has to be a e-commerce component included since the client wants to do order processing, and process credit card transactions using stripe. With the that being said I decided to write a custom controller for user accounts that are created under the user-permissions plugin for strapi. This way I could link the user accounts from strapi to corresponding customer accounts on stripe's end.
However, i'm running into one problem in particular. The custom user controller methods I have written for creating and updating users seem to work as intended. Though whenever I delete users strapi doesn't seem to use the custom method I have written for deleting users at all. I even included a console.log call but nothing pops up.
I'm not really sure on how to go about fixing this issue since I can't see any of the log calls, and strapi doesn't seem to be spitting out any errors either when this occurs. Any advice on how to go about resolving this issue is appreciated.
Here's the custom controller i'm working on.
<project_dir>/extensions/user-permissions/controllers/User.js
'use strict';
/**
* A set of functions called "actions" for `user`
*/
const _ = require('lodash'),
{ sanitizeEntity } = require('strapi-utils'),
stripe = require('stripe')('<SK_HERE>'),
sanitizeUser = (user) => sanitizeEntity(user, {model: strapi.query('user', 'users-permissions').model}),
formatError = (error) => [{ messages: [{ id: error.id, message: error.message, field: error.field }] }];
module.exports = {
async create(ctx) {
const advanced = await strapi.store({
environment: '',
type: 'plugin',
name: 'users-permissions',
key: 'advanced'
}).get();
const { email, username, firstName, lastName, password, role } = ctx.request.body;
if (!email) return ctx.badRequest('missing.email');
if (!username) return ctx.badRequest('missing.username');
if (!password) return ctx.badRequest('missing.password');
if (!firstName) return ctx.badRequest('missing.firstName');
if (!lastName) return ctx.badRequest('missing.lastName');
const userWithSameUsername = await strapi
.query('user', 'users-permissions')
.findOne({ username });
if (userWithSameUsername) {
return ctx.badRequest(
null,
formatError({
id: 'Auth.form.error.username.taken',
message: 'Username already taken.',
field: ['username'],
})
);
}
if (advanced.unique_email) {
const userWithSameEmail = await strapi
.query('user', 'users-permissions')
.findOne({ email: email.toLowerCase() });
if (userWithSameEmail) {
return ctx.badRequest(
null,
formatError({
id: 'Auth.form.error.email.taken',
message: 'Email already taken.',
field: ['email'],
})
);
}
}
const user = {
...ctx.request.body,
provider: 'local',
};
user.email = user.email.toLowerCase();
if (!role) {
const defaultRole = await strapi
.query('role', 'users-permissions')
.findOne({ type: advanced.default_role }, []);
user.role = defaultRole.id;
}
try {
const customer = await stripe.customers.create({name: `${firstName} ${lastName}`, email: email});
user.stripeId = customer.id;
const data = await strapi.plugins['users-permissions'].services.user.add(user);
ctx.created(sanitizeUser(data));
} catch (error) {
ctx.badRequest(null, formatError(error));
}
},
async update(ctx) {
const advancedConfigs = await strapi.store({
environment: '',
type: 'plugin',
name: 'users-permissions',
key: 'advanced',
}).get();
const { id } = ctx.params;
const { email, username, password, firstName, lastName} = ctx.request.body;
const user = await strapi.plugins['users-permissions'].services.user.fetch({id});
if (_.has(ctx.request.body, 'email') && !email) {
return ctx.badRequest('email.notNull');
}
if (_.has(ctx.request.body, 'username') && !username) {
return ctx.badRequest('username.notNull');
}
if (_.has(ctx.request.body, 'firstName') && !firstName) {
return ctx.badRequest('firstName.notNull');
}
if (_.has(ctx.request.body, 'lastName') && !lastName) {
return ctx.badRequest('lastName.notNull');
}
if (_.has(ctx.request.body, 'password') && !password && user.provider === 'local') {
return ctx.badRequest('password.notNull');
}
if (_.has(ctx.request.body, 'username')) {
const userWithSameUsername = await strapi
.query('user', 'users-permissions')
.findOne({ username });
if (userWithSameUsername && userWithSameUsername.id != id) {
return ctx.badRequest(
null,
formatError({
id: 'Auth.form.error.username.taken',
message: 'username.alreadyTaken.',
field: ['username'],
})
);
}
}
if (_.has(ctx.request.body, 'email') && advancedConfigs.unique_email) {
const userWithSameEmail = await strapi
.query('user', 'users-permissions')
.findOne({ email: email.toLowerCase() });
if (userWithSameEmail && userWithSameEmail.id != id) {
return ctx.badRequest(
null,
formatError({
id: 'Auth.form.error.email.taken',
message: 'Email already taken',
field: ['email'],
})
);
}
ctx.request.body.email = ctx.request.body.email.toLowerCase();
}
let updateData = {
...ctx.request.body,
};
if (_.has(ctx.request.body, 'password') && password === user.password) {
delete updateData.password;
}
if(email != null || firstName != null || lastName != null) {
let stripeUpdate = {};
if(email != null && (email !== user.email)) stripeUpdate = {...stripeUpdate, email: email};
if((firstName != null && (firstName !== user.firstName)) || (lastName != null && (lastName !== user.lastName))) stripeUpdate = {
...stripeUpdate,
name: `${firstName != null && (firstName !== user.firstName) ? firstName : user.firstName} ${lastName != null && (lastName !== user.lastName) ? lastName : user.lastName}`
};
if(Object.keys(stripeUpdate).length > 0) {
const customerUpdate = await stripe.customers.update(user.stripeId, stripeUpdate);
}
}
const data = await strapi.plugins['users-permissions'].services.user.edit({ id }, updateData);
ctx.send(sanitizeUser(data));
},
async destroy(ctx) {
console.log('test...');
const { id } = ctx.params,
user = await strapi.plugins['users-permissions'].services.user.fetch({id}),
customerDelete = await stripe.customers.del(user.stripeId),
data = await strapi.plugins['users-permissions'].services.user.remove({id});
ctx.send(sanitizeUser(data));
}
};
Did you activate the destroy action in user-permissions?
I've tested it with this simple User.js in <project_dir>/extensions/user-permissions/controllers/:
module.exports = {
async find(ctx) {
console.log('find!!!');
return [];
},
async destroy(ctx) {
console.log('destroy!!!');
return [];
},
}
console.log('destroy!!!') is called when I send a DELETE request to http://localhost:1337/users/1234