How to fetch messages from array of channel objects - discord.js

I've written this code that's supposed to find the messages of each channel, make sure they're not undefined, fetch 10 of them, and then send the contents of them. However, when running it, it outputs nothing, not even giving an error to work with.
filtered_channel_ids.forEach(element => {
if (typeof element.messages !== 'undefined'){
client.channels.element.messages.fetch({limit: 10})
.then(message => console.log(message.content))
}
})

element is not a property of the client or client.channels object. It is a stand-alone string.
filtered_channel_ids.forEach((element) => {
const channel = client.channels.cache.get(element); // get the channel
if (channel.messages) {
channel.messages
.fetch({ limit: 10 }) // fetch the messages
.then((
messages // also, it returns 10 messages, not just one message
) => messages.forEach((message) => console.log(message.content)));
}
});

Related

Stop Multiple returns from Server after query with Apollo and Angular

Bellow is an example on code I am using to submit data to a server and the return I receive and save
this.apollo.mutate( { mutation: XXXXXXXX, variables: { instance_string: X,
accesstoken: X } })
.subscribe({
next: (data: any ) => {
console.log("data returned from Server", data);
// This data can be sent from the Server in a loop on occassion
this.SaveData(data);
},
error: (err) => {
this.presentToastFail(err);
}
});
On occasion the Server returns the data in a loop. I have no control of the Server and it appears this will be a reoccurring bug for quite a while. Is there a way that I can can insure the next: only runs once and ignores the Loop of data returns the Server can send.
It looks like you have to use two pipeable operators like take(), filter():
.pipe(
filter(resp => resp !== undefined && resp !== null),
take(1) // <--- It will only take one successful valid response
)
.subscribe(...)
It looks like u can also use takeuntil
Takeuntil reference document
const example = evenSource.pipe(
//also give me the current even number count for display
withLatestFrom(evenNumberCount),
map(([val, count]) => `Even number (${count}) : ${val}`),
//when five even numbers have been emitted, complete source observable
takeUntil(1)//this will take 1st response
);

CHROME EXTENSIONS: Message passing - chrome.runtime.sendMessage or onMessage not working

I am working on google extensions. I am trying to process message passing between my popup.tsx and background.ts
Before sending message from my background.ts, I print the data. Data exist. However, in my popup.tsx chrome.runtime.onMessage not triggered. I dont understand which function not working and what is the problem. I examine lots of example but result still the same. What is the problem? I am adding my message passing codes..
Here is my background.ts runtime.sendMessage func. this function is inside another function that is called 'collectData'. When I open new tab or update the tab, this function triggered and works. Everytime this data works stable. I can see the data in every page.
chrome.runtime.sendMessage({
msg: 'url_data',
data: data,
})
Then, I am trying to receive the data in my popup.tsx with runtime.onMessage. When I reset the extension, it works sometimes just once, then that onMessage func not working at all :
const [requestData, setRequestData] = useState<string>()
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log(' popup runtime on message req', request)
if (request.msg === 'url_data') {
checkWebsite(request.data).then((res) => {
console.log('popup data alındı')
console.log('popu res', res)
setRequestData(res)
// chrome.runtime.sendMessage({
// msg: 'res_length',
// data: res.matches.length,
// })
// console.log('popup data res length gönderildi')
// res.matches.length === 0 ? setIsSecure(true) : setIsSecure(false)
setHost(request.data.hostname)
})
sendResponse({ message: 'res length sended' })
console.log('res length response send')
}
})
Everytime, I change request data state. If it changes, I want to update popup with useEffect.
useEffect(() => {
console.log('useeffect', requestData)
}, [requestData])
As a result, for the first the main problem is message passing. Why it is not working?

How to use the awaitMessages function in discord.js

I have some code for discord.js that sends a user a DM when they join the server. They then have to enter the password given to them, and it will then give them a role that allows them access to channels.
const Discord = require('discord.js');
const client = new Discord.Client();
client.once('ready', () => {
console.log('Ready!');
});
client.on('guildMemberAdd', guildMember => {
console.log("Joined");
guildMember.send("Welcome to the server! Please enter the password given to you to gain access to the server:")
.then(function(){
guildMember.awaitMessages(response => message.content, {
max: 1,
time: 300000000,
errors: ['time'],
})
.then((collected) => {
if(response.content === "Pass"){
guildMember.send("Correct password! You now have access to the server.");
}
else{
guildMember.send("Incorrect password! Please try again.");
}
})
.catch(function(){
guildMember.send('You didnt input the password in time.');
});
});
});
client.login("token");
The thing is, I don't really know how to use the awaitResponses function. I do not know how to call it, because all the tutorials I find use it with message.member.
When I run my code, I get these three errors:
UnhandledPromiseRejectionWarning: TypeError: guildMember.awaitMessages is not a function
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.
I do not know what lines these are referring to, so I am very confused.
Here's a quick rundown on how awaitMessages works:
First of all, the .awaitMessages() function extends GuildChannel, meaning you had already messed up a little bit by extending the GuildMember object instead. - You could easily fetch a channel using
const channelObject = guildMember.guild.channels.cache.get('Channel ID Here'); // Gets a channel object based on it's ID
const channelObject = guildMember.guild.channels.cache.find(ch => ch.name === 'channel name here') // Gets a channel object based on it's name
awaitMessages() also gives you the ability to add a filter for a certain condition an input must have.
Let's take the freshly new member as an example. We could simply tell the client to only accept input from members who have the same id as the guildMember object, so basically only the new Member.
const filter = m => m.author.id === guildMember.id
Now, finally, after we've gathered all of the resources needed, this should be our final code to await Messages.
const channelObject = guildMember.guild.channels.cache.get('Channel ID Here');
const filter = m => m.author.id === guildMember.id
channelObject.awaitMessages(filter, {
max: 1, // Requires only one message input
time: 300000000, // Maximum amount of time the bot will await messages for
errors: 'time' // would give us the error incase time runs out.
})
To read more about awaitMessages(), click here!

Discord.js message collector in a loop for tic tac toe

So i started to make a discord bot using discord.js which has a command for tic tac toe.
I tried using a message collector, like this in a while loop. After it enters the loop nothing happens. I added a console.log to see if the totalRouds variable is modifying and it was, so the loop somehow passed over the message collector code and executed just the last line.
while(numberOfrounds < 9){
const filter = m => m.author.id === message.author.id;
message.reply('Enter a position:');
message.channel.awaitMessages(filter, {max: 1, time: 3000, errors: ['time']}).then(collected => {
// code for drawing a canvas
}).catch(err => {
console.log(err);
});
console.log(totalRouds);
numberOfrounds ++;
}
.awaitMessages() returns a Promise that resolves into your collected message data asynchronously. That means that while your last log statement runs immediately after you start collecting messages, the collected messages are only available and thus processed at a later time.
To illustrate that, let me tidy your code a little and add some logs in the order that your code would normally run:
while (numberOfrounds < 9) {
console.log("1");
const filter = m => m.author.id === message.author.id;
message.reply('Enter a position:');
console.log("2");
message.channel.awaitMessages(
filter,
{ max: 1, time: 3000, errors: ['time'] }
).then(collected => {
console.log("5, after resolving, the collected data is only now avaiable");
}).catch(err => {
console.log(err);
});
console.log("3");
console.log(totalRouds);
numberOfrounds++;
console.log("4, immediately starts the next loop, back to #1 again");
}
I presume that your totalRouds variable is defined within the callback function passed into .then(). So other than the typo (let's fix that), your variable would be defined in the wrong scope and thus totalRounds would always remain undefined, even after the Promise resolves with your collected messages, you process those messages, you set totalRounds within the callback function etc. So here is our updated snippet:
while (numberOfrounds < 9) {
const filter = m => m.author.id === message.author.id;
message.reply('Enter a position:');
message.channel.awaitMessages(
filter,
{ max: 1, time: 3000, errors: ['time'] }
).then(collected => {
let totalRounds = 1 // Do your processing here
console.log(totalRounds); // This should log as expected
}).catch(err => {
console.log(err);
});
numberOfrounds++;
}
But this is still probably not the behaviour you are looking for. Why? Your bot will attempt to send all 9 replies (assuming your numberOfRounds starts at 0 earlier) at once, at which point Discord.js will automatically send them in batches to avoid spamming the API, and all message collectors would be waiting concurrently. You probably intend to "pause" or suspend processing until the Promise returned by .awaitMessages() resolves and you have finished processing the returned data, causing synchronous behaviour whilst using an asynchronous method call (therefore you say "the loop somehow passed over the message collector code and executed just the last line"). To do this, we can use async-await:
/*
You have not provided your full code,
so what you need to do is mark your message event's
callback function as async.
Refer to the linked article on MDN.
*/
while (numberOfrounds < 9) {
const filter = m => m.author.id === message.author.id;
message.reply('Enter a position:');
/*
Then, wait for the Promise returned by
this promise chain to resolve
before resuming operation
and moving on to the next iteration.
*/
await message.channel.awaitMessages(
filter,
{ max: 1, time: 3000, errors: ['time'] }
).then(collected => {
let totalRounds = 1
console.log(totalRounds);
}).catch(err => {
console.log(err);
});
numberOfrounds++;
}
My terminology may not be 100% correct, but this is my understanding. Feel free to comment if improvements can be made.

Switching a prefix for a command in discord.js

First post on this site so my bad if I don't format something correctly. I've been trying to make a change prefix command and I don't know how to check next message content for a variable to use instead of the old prefix.
msg.reply("Which prefix do you want?");
const collector = new Discord.MessageCollector(msg.channel, m => m.author.id === msg.author.id, { time: 5000 });
console.log(collector)
collector.on('collect', msg => {
newprefix=collector.content();
msg.reply('Prefix succesfully changed!');
});
I strongly advise using the awaitMessages method. First you need to define a filter, a delegate function that returns true if the reaction is one you want. Typically in a command/response setting, you want a filter that indicates the original command invoker replied.
const filter = (reaction, user) => {
return user.id === msg.author.id;
};
You can then define options for your awaitMessages. (It's quite common to do this in-line with the awaitMessages method, that's fine if that is more clear to you)
const options = {
max: 1,
time: 30000,
errors: ['time']
}
The above example accepts 1 message, if given in 30 seconds, otherwise it throws an exception.
Finally, you are ready to begin...
msg.reply("Which prefix do you want?").then(() => {
msg.channel.awaitMessages(filter, options)
.then(collected => {
newprefix = collected.first();
// Record newprefix to a persistent config here
msg.reply('Prefix successfully changed!');
})
.catch(collected => {
msg.reply("You didn't respond fast enough.");
});
}
Keep in mind, this occurs asynchronously, so if you need to write newprefix somewhere, a JSON config file for example, you should do from within the scope of the .then

Resources