welcome message js errpr - discord

from this code im getting the error /home/container/welcome.js:9
message.channel.send(message)
^
TypeError: Cannot read property 'send' of undefined
const channelId = "812458294085550121";
bot.on("guildMemberAdd", (member) => {
console.log(member);
const message = [`Welcome <#${member.id}> to our server`]
const channel = member.guild.channels.cache.get(channelId)
message.channel.send(message)
})
}```

the problem you seem to have is, that channel can not be found. Hence the can not find property 'send' of undefined.
Try this:
const channelId = "812458294085550121";
bot.on("guildMemberAdd", (member) => {
console.log(member);
const welcomeMessage = `Welcome <#${member.id}> to our server`;
const channel = client.channels.cache.get(channelId);
channel.send(welcomeMessage);
});
}

You defined 'message' in your code to receive the channel while you have 'message' defined as a message to send and not as an object. Also you made your message in an array what is a bit confusing, so what you also would need to do is access the message in the array with an index position. This should work:
const channelId = "812458294085550121"; // Define the channel id
bot.on("guildMemberAdd", (member) => { // Event listener when someone joined a server
console.log(member); // Sends the member object in the console
const message = [`Welcome <#${member.id}> to our server`] // Message in an array
const channel = member.guild.channels.cache.get(channelId) // Find the channel
if(!channel) return console.log(`Channel doesn't exists`); // If the channel doesn't exists
channel.send(message[0]); // Send the message in the channel
});

Related

discord.js modal giving error something went wrong

Whenever i submit the modal it gives me error something went wrong try again..
this is my code -
const { Events, EmbedBuilder, AttachmentBuilder, ModalBuilder, TextInputBuilder, TextInputStyle, ActionRowBuilder, ButtonBuilder, ButtonStyle, InteractionType} = require('discord.js');
const { Verification } = require('../models/verificationSchema')
const { Captcha } = require('captcha-canvas')
module.exports = {
name: Events.InteractionCreate,
async execute(interaction, client) {
if (interaction.isButton()){
if (interaction.customId === 'verify') {
await interaction.deferReply({ephemeral: true});
const member = await interaction.guild.members.cache.get(interaction.member.user.id) || await interaction.guild.members.fetch(interaction.member.user.id).catch(err => {});
const captcha = new Captcha();
captcha.async = true;
captcha.addDecoy();
captcha.drawTrace();
captcha.drawCaptcha();
const captchaAnswer = captcha.text;
const captchaImage = new AttachmentBuilder()
.setFile(await captcha.png)
.setName('captcha.png')
const captchaEmbed = new EmbedBuilder()
.setTitle('Verification Captcha')
.setColor('Yellow')
.setImage('attachment://captcha.png')
.setDescription(`Please enter the captcha text`)
const captchaRow = new ActionRowBuilder()
.addComponents([
new ButtonBuilder()
.setLabel('Answer')
.setCustomId('answer')
.setStyle(ButtonStyle.Success)
])
await interaction.editReply({embeds: [captchaEmbed], files: [captchaImage], components: [captchaRow]});
}
}
if (interaction.customId === 'answer') {
const modal = new ModalBuilder()
.setCustomId('verificationModal')
.setTitle('Verification Input')
.addComponents([
new ActionRowBuilder().addComponents([
new TextInputBuilder()
.setCustomId('captchaInput')
.setLabel("Enter the Captcha.")
.setStyle(TextInputStyle.Short),
])
]);
interaction.showModal(modal);
}
if (interaction.isModalSubmit()) {
console.log(interaction)
if (interaction.customId === 'verificationModel') {
const response = interaction.fields.getTextInputValue('captchaInput');
console.log(response)
}
}
}
}
I am trying to make a verification command in discord i ask the user for captcha text via the modal but it gives me error. i don't know how to fix this error i just want to get the user input in modal whenever the modal is submitted..
there is no error in the terminal.
thanks in advance :)
error image
The modal is showing that because Discord expected a response to the modal interaction. If you don't want to send a message to the user when they submit the modal (e.g. by using interaction.reply()) then you can simply defer an update to the interaction using the ModalSubmitInteraction.deferUpdate() method. Example:
if (interaction.isModalSubmit()) {
interaction.deferUpdate()
// all the other stuff you want to do with the modal submission here
}
What should happen here is that when the user clicks the submit button on your modal, Discord sends their submission to your bot, you respond that you simply want to defer the interaction, and then Discord closes the modal for the user without showing an error message.

Extract Select Menu values from modal [discord.js]

I'm currently making a modal based ordering system and extracting the TextInput works fine, however I can't seem to figure out how to extract the SelectMenu data, as the current code only returns an error
TypeError: interaction.fields.getSelectMenuValue is not a function
client.on('interactionCreate', async interaction => {
if (!interaction.isModalSubmit() || !interaction.customId === 'tankform') return;
await interaction.reply({ content: 'Your order was received successfully!', ephemeral: true });
const IGN = interaction.fields.getTextInputValue('minecraft_ign');
const Weapon = interaction.fields.getSelectMenuValue('weapon_type');
const ownedWeapon = interaction.fields.getSelectMenuValue('owned_weapon');
const ownedTanks = interaction.fields.getSelectMenuValue('owned_tanks');
const wantedTanks = interaction.fields.getSelectMenuValue('wanted_tanks');
console.log({IGN, Weapon, ownedWeapon, ownedTanks, wantedTanks})
});
Your code looks fine. The problem is that discord.js doesn't support recieving select menus from modals yet. I suggest you use discord-modals. It works for me personally.
This bit
if (!interaction.isModalSubmit() || !interaction.customId === 'tankform') return;
the 2nd comparison is incorrect, you want
if (!interaction.isModalSubmit() || interaction.customId !== 'tankform') return;
instead
Try:
else if (interaction.type === InteractionType.ModalSubmit) // fixed
{
if(interaction.customId === 'yourId') {
const IGN = interaction.fields.getTextInputValue('minecraft_ign');
const Weapon = interaction.fields.getSelectMenuValue('weapon_type');
const ownedWeapon = interaction.fields.getSelectMenuValue('owned_weapon');
const ownedTanks = interaction.fields.getSelectMenuValue('owned_tanks');
const wantedTanks = interaction.fields.getSelectMenuValue('wanted_tanks');
console.log({IGN, Weapon, ownedWeapon, ownedTanks, wantedTanks})
}

React State Fails To Update with UseEffect

When attempting to update an array via React state management, the state array is populated, but the user interface fails to update. The user interface only updates after I click on the navbar, and reroute to the current page (in which case useEffect does not run again, but the UI is updated).
State Code
const[isFetched, setIsFetched] = useState(false);
const[balances, setBalances] = useState<IBalance[]>([]);
const[num, setNum] = useState(0);
useEffect(() => {
console.log(balances);
// LOGS A POPULATED ARRAY
console.log(balances.length);
// LOGS 0
}, [balances]);
useEffect(() => {
const fetchBalances = async() =>{
let bals:IBalance[] = await kryptikService.getBalanceAllNetworks(kryptikWallet);
console.log("RECIEVED BALANCES:");
console.log(bals);
console.log(bals.length);
setBalances(bals);
setIsFetched(true);
}
fetchBalances();
}, []);
UI Code
<h2>Your Balances</h2>
<Divider/>
{
!isFetched?<p>Loading Balances.</p>:
<ul role="list" className="divide-y divide-gray-200 dark:divide-gray-700">
{balances.map((balance:IBalance) => (
<ListItem title={balance.fullName} imgSrc={balance.iconPath} subtitle={balance.ticker} amount={balance.amountCrypto}/>
))}
</ul>
}
</div>
Fetch Handler (called in UseEffect)
getBalanceAllNetworks = async(walletUser:IWallet):Promise<IBalance[]> =>{
let networksFromDb = this.getSupportedNetworkDbs();
// initialize return array
let balances:IBalance[] = [];
networksFromDb.forEach(async nw => {
let network:Network = new Network(nw.fullName, nw.ticker);
let kryptikProvider:KryptikProvider = await this.getKryptikProviderForNetworkDb(nw);
if(network.getNetworkfamily()==NetworkFamily.EVM){
if(!kryptikProvider.ethProvider) throw Error(`No ethereum provider set up for ${network.fullName}.`);
let ethNetworkProvider:JsonRpcProvider = kryptikProvider.ethProvider;
console.log("Processing Network:")
console.log(nw.fullName);
// gets all addresses for network
let allAddys:string[] = await walletUser.seedLoop.getAddresses(network);
// gets first address for network
let firstAddy:string = allAddys[0];
console.log(`${nw.fullName} Addy:`);
console.log(firstAddy);
console.log(`Getting balance for ${nw.fullName}...`);
// get provider for network
let networkBalance = await ethNetworkProvider.getBalance(firstAddy);
console.log(`${nw.fullName} Balance:`);
console.log(networkBalance);
// prettify ether balance
let networkBalanceAdjusted:Number = BigNumber.from(networkBalance)
.div(BigNumber.from("10000000000000000"))
.toNumber() / 100;
let networkBalanceString = networkBalanceAdjusted.toString();
let newBalanceObj:IBalance = {fullName:nw.fullName, ticker:nw.ticker, iconPath:nw.iconPath,
amountCrypto:networkBalanceString}
// add adjusted balance to balances return object
balances.push(newBalanceObj);
}
});
return balances;
}
Note: The array is a different reference, so there should be no issue with shallow equality checks. Also, the updated balances array contains objects, but the length is logged as zero as shown in the first code snippet. Any help will be much apreciated!
Issue
The issue is that you are iterating the networksFromDb array in a forEach loop with an asynchronous callback. The asynchronous callback ins't the issue, it is that Array.protptype.forEach is synchronous, the the getBalanceAllNetworks callback can't wait for the loop callbacks to resolve. It returns the empty balances array to the caller before the array is populate.
The array is still populated however, and the clicking the link is enough to trigger a React rerender and expose the mutated balances state array.
Solution
Instead of using a .forEach loop for the asynchronous callback, map networksFromDb to an array of Promises and use Promise.all and wait for them all to resolve before returning the populated balances array.
Example:
const getBalanceAllNetworks = async (
walletUser: IWallet
): Promise<IBalance[]> => {
const networksFromDb = this.getSupportedNetworkDbs();
const asyncCallbacks = networksFromDb
.filter((nw) => {
const network: Network = new Network(nw.fullName, nw.ticker);
return network.getNetworkfamily() == NetworkFamily.EVM;
})
.map(async (nw) => {
const kryptikProvider: KryptikProvider = await this.getKryptikProviderForNetworkDb(
nw
);
if (!kryptikProvider.ethProvider) {
throw Error(`No ethereum provider set up for ${network.fullName}.`);
}
const ethNetworkProvider: JsonRpcProvider = kryptikProvider.ethProvider;
// gets all addresses for network
const allAddys: string[] = await walletUser.seedLoop.getAddresses(
network
);
// gets first address for network
const firstAddy: string = allAddys[0];
// get provider for network
const networkBalance = await ethNetworkProvider.getBalance(firstAddy);
// prettify ether balance
const networkBalanceAdjusted: Number =
BigNumber.from(networkBalance)
.div(BigNumber.from("10000000000000000"))
.toNumber() / 100;
const networkBalanceString = networkBalanceAdjusted.toString();
const newBalanceObj: IBalance = {
fullName: nw.fullName,
ticker: nw.ticker,
iconPath: nw.iconPath,
amountCrypto: networkBalanceString
};
// add adjusted balance to balances return object
return newBalanceObj;
});
const balances: IBalance[] = await Promise.all(asyncCallbacks);
return balances;
};
You are mutating balances instead of updating it.
Change balances.push to setBalances(prevState => [...prevState, newBalance])

TypeError: Cannot read properties of undefined (reading 'cache') when trying to get a random users avatar Discord.js

This code gets displays a random user's avatar when you type !avatar, but it does not work and only returns TypeError: Cannot read properties of undefined (reading 'cache')
const { MessageEmbed } = require('discord.js');
module.exports = {
name: 'avatar',
/**
*
* #param {Client} client
* #param {Message} message
*/
description: "Get avatar",
async execute(client, args, message,){
const user = client.users.cache.random()
message.channel.send(
new MessageEmbed()
.setColor("RANDOM")
.setImage(user.displayAvatarURL())
)
}
}
I changed module.exports to module.exports.execute
You can try changing this code line:
const user = client.users.cache.random()
to:
const user = message.guild.members.cache.random()
because you only need to cache on your main server or whenever the bot gets in

fp-ts: Filter out certain left values, and error on right

I'd like to ignore certain errors using fp-ts (if they happen, it means everything went well, i.e. missing account during signup process).
I have the following code:
export const handleSignup = async (server: FastifyInstance): Promise<void> => {
server.post('/signup', async (req, res) => {
const {email} = req.body as SignupPostData
const {redirectUri} = req.query as Record<'redirectUri', string>
return pipe(
withDb(lookupAccountByEmail)(email),
TE.chain(() => flow(generateMagicLinkToken, TE.fromEither)(email)),
TE.chain(sendSignupEmail(email, redirectUri))
)().then(foldReply<SignupApiResponse>(res))
})
}
The lookupAccountByEmail function will either return an Account, or will return an error object.
If an account is returned, I need to return an error with code 'account-exists'. If an error object with the code 'account-not-found' is returned, I'd like everything to continue as if there were no problem. If an error object with any other code is returned, it should still error.
What's the best way to handle this in fp-ts?
You can use TE.fold.
const doSignup = pipe(
generateMagicLinkToken(email),
TE.fromEither,
TE.chain(sendSignupEmail(email, redirectUri))
)
return pipe(
email,
withDb(lookupAccountByEmail),
TE.fold(
left => left.error === 'account-not-found' ? doSignup : TE.left(left)
right => TE.left({error: 'account-exits'})
),
T.map(foldReply<SignupApiResponse>(res))
)()

Resources