How to get active member count Discord JS - discord

I have a function which counts all active members on active server
I've tried to get into client.guilds.cache then filter users by their presence.status to check if the user is online. As far as I am aware what's happening .size should return a number of active members on the server, but instead it returns 0, no matter what I try.
Here's the code I've tried
I call function in client.on here and pass client as an argument
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMembers],
});
client.on("ready", () => {
activeMembersCounter(client)
});
Then in activeMembersCounter.ts
function activeMembersCounter(client: Client<boolean>): void {
const guild = client.guilds.cache.get(config.GUILD_ID);
const onlineMembers = guild.members.cache.filter((m) => m.presence?.status === "online"&& !member.user.bot).size;
console.log(onlineMembers) // logs 0
}
I've also tried async version with fetch
async function activeMembersCounter(client: Client<boolean>): Promise<void> {
const guild = client.guilds.cache.get(config.GUILD_ID);
const onlineMembers = (await guild.members.fetch()).filter((member) => member.presence?.status === "online" && !member.user.bot);
console.log(onlineMembers.size);
}
I'm not 100% sure if my approach is correct here. I would love to get some advice :)

Two things you need to change.
Use the GatewayIntentBits.GuildPresences flag, m.presence returns null if you don't use it.
member is undefined in your online members variable. Use m.user.bot instead of member.user.bot.
Working code:
const { GatewayIntentBits, Client} = require('discord.js');
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildPresences],
});
function activeMembersCounter(c) {
const guild = c.guilds.cache.get("GUILD_ID");
console.log(guild);
const onlineMembers = guild.members.cache.filter((m) => m.presence?.status == "online" && !m.user.bot).size;
console.log(onlineMembers);
}
client.once('ready', () => {
activeMembersCounter(client);
})
Edit: If you're looking for active members, this could include DND members and Idle members. You might want to consider using m.presence?.status != "offline" instead of m.presence?.status == "online" to include these other statuses in your count.

Related

Filter function for Array of Objects

I'm following this tutorial and made a few changes to typescript for learning purposes but got stuck when creating a filter function from react context script.
I have a working function called getCampaigns where it maps all the object from the blockchain like below:
const getCampaigns = useCallback(async () => {
const signer = accountProvider?.getSigner();
const contractWithSigner = contract?.connect(signer);
const campaigns = await contractWithSigner?.getCampaigns();
const parsedCampaigns = campaigns.map((campaign, i) => ({
owner: campaign.owner,
title: campaign.title,
description: campaign.description,
target: ethers.utils.formatEther(campaign.target.toString()),
deadline: campaign.deadline.toNumber(),
amountCollected: ethers.utils.formatEther(
campaign.amountCollected.toString()
),
image: campaign.image,
pId: i,
}));
return parsedCampaigns;
}, [contract, accountProvider]);
This is working as it should and manage to see the content like below:
[{…}]
0:
amountCollected:"0.0"
deadline:1673049600000
description: "I want to build a Robot"
image:"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAA
owner:"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
pId:0
target:"3.0"
title:"Build a Robot"
As my new function, I wanted to filter from the getCampaigns function only to display all of the owner's post and display it on a Profile page like below:
const getUserCampaigns = async () => {
const allCampaigns = await getCampaigns();
const filteredCampaigns = allCampaigns.filter(
campaign => campaign.owner === account
);
return filteredCampaigns;
};
So when I console.log filteredCampaigns, it doesnt show any result. Is there anything that I missed here? The typeof account is string and it is working if I put it like this
const filteredCampaigns = allCampaigns.filter(
campaign => campaign.owner === "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
);
Update:
So far I have been playing around with the syntax and console.log the following:
const filteredCampaigns = allCampaigns.filter(campaign => {
console.log(campaign.owner);
return campaign.owner === account;
});
it's managed to fetch the same data and the typeof campaign.owner is in fact a string (same as typeof account). But when I run it like this
const filteredCampaigns = allCampaigns.filter(campaign => {
console.log(campaign.owner === account.toString());
return campaign.owner === account;
});
It's still come out as false
It is working if I hard coded like this
console.log(campaign.owner === "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266")
filteredCampaign is empty, because the content of account doesn't match any content of campaign.owner.
Check the content of account.
allCampaign.filter(elementOfArray => condition)
return element only if condition is true.
The logic of your getUserCampaign, looks right for what you want to do.
Not sure if this is the case, but may have sense, to have a field/global var/state where you keep all your campaigns.
In this way when you want to filter, you can do something like
const filteredCampaign = (account: string) => {
return allCampaigns.filter(campaign => campaign.owner === account);
}
filteredCampaign is not anymore async call, because doesn't have to await and receive the
account

DiscordJs v14 create a message error includes

I don't understand why i have this error i want create a bot for add role if a people write link in description but the code don't want get my includes
`
const { Client, GatewayIntentBits, Collection } = require('discord.js');
const config = require('./config');
const bot = new Client({
intents: [3276799]
});
bot.commands = new Collection()
require('./src/Structure//Handler/Event')(bot);
require('./src/Structure//Handler/Command')(bot);
bot.on('presenceUpdate', async (oldPresence, newPresence) => {
const role = newPresence.guild.roles.cache.get("1048286446345261137");
const member = newPresence.member
const activities = newPresence.activities[0];
if (activities && (activities.state.includes(".gg/slayde" ) || activities.state.includes(".gg/slayde"))) {
return newPresence.member.roles.add(role)
} else {
if(member.roles.cache.get(role.id)) {
newPresence.member.roles.remove(role)
}
}
})
bot.login(config.clients.token);
`
The error
TypeError: Cannot read properties of null (reading 'includes')
I try to fix but i'm blocked
According to the docs, the state property of Activity is optional (?string), which means it doesn't always have a value. You have to make sure it exists before you call includes() on it.
if (activities && activities.state && (activities.state.includes(".gg/slayde" ) || activities.state.includes(".gg/slayde"))) {
// etc
}

How to make Discord Bot Automatically Role Someone when they have certain word in status

trying to make it so if someone for example put my discord servers invite in their status ".gg/testing" it would give them a role and if they removed it would take their role away heres the code i have got right now off a similar stack overflow post heres my code right now but it doesnt give the user there role when they have .gg/testing in their status any tips?
const { Client, Intents } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
const roleID = "972823139119685712";
client.on("presenceUpdate", async (_, newPresence) => {
const role = newPresence.guild.roles.cache.get(roleID);
const status = ".gg/testing";
const member = newPresence.member;
if (member.presence.activities[0].state?.includes(status)) {
return newPresence.member.roles.add(role);
} else {
if (member.roles.cache.has(role)) {
newPresence.member.roles.remove(role);
}
}
});
client.login("");
This is the code you're looking for. Credit to HellCatVN whose code I edited a tiny bit to make this work.
client.on('presenceUpdate', async (oldPresence, newPresence) => {
const role = newPresence.guild.roles.cache.get("941814488917766145");
const member = newPresence.member
const activities = member.presence.activities[0];
if (activities && (activities.state.includes( ".gg/testing" ) || activities.state.includes("discord.gg/testing" ))) {
return newPresence.member.roles.add(role)
} else {
if(member.roles.cache.get(role.id)) {
newPresence.member.roles.remove(role)
}
}
})
The role will be gone if the user turns on invisible status too.

How do I use #discordjs/voice AudioPlayer methods across modules?

I am adding a music-playing feature to my bot using #discordjs/voice, following the voice guide on discordjs.guide. My slash commands are all stored on different files. I want to use the pause method of the AudioPlayer class outside of play.js.
The relevant parts of play.js are:
const { SlashCommandBuilder } = require('#discordjs/builders');
const { StreamType, createAudioPlayer, createAudioResource, joinVoiceChannel } = require('#discordjs/voice');
module.exports = {
data: new SlashCommandBuilder()
.setName('play')
.setDescription('An example of the play command.'),
async execute(interaction) {
const connection = joinVoiceChannel({ channelId: interaction.member.voice.channel.id, guildId: interaction.guild.id, adapterCreator: interaction.guild.voiceAdapterCreator });
const stream = ytdl('https://www.youtube.com/watch?v=jNQXAC9IVRw', { filter: 'audioonly' });
const resource = createAudioResource(stream, { inputType: StreamType.Arbitrary });
const player = createAudioPlayer();
player.play(resource);
connection.subscribe(player);
await interaction.reply('Playing.');
},
};
and of pause.js are:
const { SlashCommandBuilder } = require('#discordjs/builders');
module.exports = {
data: new SlashCommandBuilder()
.setName('pause')
.setDescription('An example of the pause command.'),
async execute(interaction) {
player.pause();
await interaction.reply('Paused.');
},
};
My console got the following error when I ran the /pause command after I tried to export player from player.js and require it in pause.js:
TypeError: Cannot read properties of undefined (reading 'pause')
What do I need to do to use player.pause() outside of play.js?
You should take a look at this part of the Discord.js guide, in the Access part. The getVoiceConnection method serves this purpose.
It allows you to use the connection created in play.js anywhere in your code. Then, you just need to change the state of the player with connection.state.subscription.player.pause().
I did my pause.js by checking whether the member using the pause command is in a channel and if he is, whether the bot is in it or not:
if (!interaction.member.voice.channelId) {
return interaction.reply('not in a channel.');
}
const connection = getVoiceConnection(interaction.member.voice.channel.guildId);
if (!connection || (connection.joinConfig.channelId != interaction.member.voice.channelId)) {
return interaction.reply('The bot is not in this channel.');
}
connection.state.subscription.player.pause();
await interaction.reply('Paused.');
discord.js

Want a code that detects custom status and gives the person a role on discord

I am trying to make a code that searches a custom status for the phrase ".gg/RoundTable" and will then give the person a certain role I have in my server.
Here is my code so far , the code runs with no errors but it will not assign the role.
const Discord = require("discord.js")
const client = new Discord.Client()
const mySecret = process.env['TOKEN']
client.login(mySecret)
const roleID = 865801753462702090
client.on('presenceUpdate', async (oldPresence, newPresence) => {
const role = newPresence.guild.roles.cache.find(role => role.name === 'Pic Perms (.gg/RoundTable)');
const status = ".gg/RoundTable"
const member = newPresence.member
console.log(member.user.presence.activities[0].state)
if(member.presence.activities[0].state.includes(status)){
return newPresence.member.roles.add(roleID)
} else {
if(member.roles.cache.has(roleID)) {
newPresence.member.roles.remove(roleID)
}
}
})
Try this:
const Discord = require("discord.js");
const client = new Discord.Client();
const roleID = "851563088314105867";
client.on("presenceUpdate", async (_, newPresence) => {
const role = newPresence.guild.roles.cache.get(roleID);
const status = ".gg/RoundTable";
const member = newPresence.member;
if (member.presence.activities[0].state?.includes(status)) {
return newPresence.member.roles.add(role);
} else {
if (member.roles.cache.has(role)) {
newPresence.member.roles.remove(role);
}
}
});
client.login("your-token");
I'd recommend finding your role in the RoleManager.cache using get() as you already have the roleID and then actually assign that role instead of the roleID. Note I added an optional chaining operator since if a user does not have a custom status .state will be null.

Resources