Cannot get channels moving event in Discord audit log - discord

I'm trying to log the Discord event when someone is moving any channel.
The channelUpdate event works almost like a charm and returning 2 events (two, because of when you moving one channel the rawPosition property is changing in the target's channel and in the channel you swiped the place). Except strange cases when you moved one channel and getting tone of events as if you moved all the server channels at ones. Weird thing, yep.
The problem is the "channelUpdate" event returns only oldChannel and newChannel but not the executor data (who and when).
I've tried to use guild.fetchAuditLogs({ type: 14, limit: 1 }) but looks like it's not returning changing position events. One gets the feeling Discord's log engine is not logging this event OR I'm looking in wrong place. Also tried type 11 and even NULL with no luck on finding rawPosition prop changing.
Please, help me to find the way how to log WHO is changing the channels position or tell me it's not possible at the time.
Some code here:
const Discord = require('discord.js');
const client = new Discord.Client({ shards: 'auto'});
const { prefix, token, witaitoken , guildID, DBUser, DBPass } = require('./config.json');
client.on('ready', async () => {
console.log(`Logged in as ${client.user.tag}!`);
client.user.setActivity(`Star Citizen`, { type: 'PLAYING' });
});
client.on('channelUpdate', (oldChannel, newChannel) => {
if (oldChannel.rawPosition !== newChannel.rawPosition) {
oldChannel.guild.fetchAuditLogs({ limit: 10 })
.then( (audit) => {
const log = audit.entries;
if (!log) return;
fs = require('fs');
fs.appendFile('audit.txt', JSON.stringify(log), function (err) {
if (err) return console.log(err);
});
})
}
});
client.login(token);
client.on("error", (e) => console.error(e));
client.on("warn", (e) => console.warn(e));
client.on("debug", (e) => console.info(e));

Related

Can't fetch right data on the button click from fireStore

I am doing my first bigger react project, where I am biulding web app for barbershop.
Idea is this. When I want to make reservation, I need to choose service type (regular haircut, beard trim or both) and then I need to choose barber. Depending which barber I choosed I fetch data from firestore. Barbers name is actually firebase collection name of the barber where is his schedule when there is free apointment.
Problem is this. When I choose service and then choose barber John, nothing happens, but if I then click on barber Carl I get John's schedule.
In the picture there is my component and how it is set up.
Here is the code of my function which is not working right.
I tried many things, it is not working even with timeOut.
useEffect(() => {
if (!service || !barber) {
return;
}
if (fetching) {
setTimeout(async () => {
try {
const barbers_name = barber;
const freeTimeRef = collection(db, `${barbers_name}`);
const q = query(freeTimeRef);
const querySnap = await getDocs(q);
let freeTimeArr = [];
querySnap.forEach((doc) => {
freeTimeArr.push(doc.data().radno_vrijeme);
return freeTimeArr;
});
setSchedule(freeTimeArr);
} catch (error) {
toast.error(error);
} finally {
setLoading(false);
setFetching(false);
}
}, 100); // delay the call by 100 milliseconds
}
}, [fetching, barber]);
setFetching is being used in this function, and this function changes state of the button from the picture, to the barbers name or service type.
const HandleChangeBarber = (e) => {
setBarber(e.currentTarget.textContent);
setFetching(true);
};

Making discord.js send a message to channel on command

I am trying to make my bot send a message to a channel in all servers that it is in when updated. My idea is that I will trigger this manually whenever I update my bot. For example, I would like to have it send a message such as "Updated bot to version 2.03. Update log: (changes made in the update)". This is the code I currently have:
const Discord = require('discord.js');
const client = new Discord.Client();
var Long = require("long");
const getChannel = (guild) => {
// get "original" default channel
if(guild.channels.cache.has(guild.id))
return guild.channels.cache.get(guild.id)
const jimmyChannel = guild.channels.cache.find(channel => channel.name === "jimmybot");
if (jimmyChannel)
return jimmyChannel;
return guild.channels.cache
.filter(c => c.type === "text" &&
c.permissionsFor(guild.client.user).has("SEND_MESSAGES"))
.sort((a, b) => a.position - b.position ||
Long.fromString(a.id).sub(Long.fromString(b.id)).toNumber())
.first();
}
// I found this as an example but I'm not sure if it will work
client.on("guildMemberAdd", member => {
const channel = getChannel(member.guild);
channel.send(`text`);
});
client.login('token');
My question is how do I call this manually instead of it sending the message whenever a user joins the server?
If I'm understanding this properly...
Client is actually just a variation of a Node.js EventEmitter, as stated here.
This means that you can trigger the events of your own accord, and so here you could do your own 'custom' EventEmitter and trigger it of your own accord.
Ex code paired with message event emitter. I know that it's generally frowned upon to put an event emitter inside of another, but it was the only solution I could find.
const Discord = require('discord.js');
const client = new Discord.Client();
token = 'XXX'
client.once('ready', () => {
console.log('Fully functional and initialized!');
});
// Attach a listener function
client.on('test', console.log);
client.on('message', msg => {
if (msg.author.bot) return;
if (msg.content === 'emit event') {
// Emit the event
client.emit('test', 'This will be printed on the console');
}
})
client.login(token);

discord.js - Issues with audio and playing in more than one server

async function play(message, correct, channel, mp3) {
const connection = await channel.join();
await new Promise(done => setTimeout(done, 1000));
let readStream = await fs.createReadStream(mp3);
await timerEventEmitter.emit("update", correct);
const dispatcher = await connection.play(readStream)
.on('end', () => {
console.log('Stream ended!');
})
.on('finish', () => {
console.log('Stream finished!');
})
.on('error', error => {
console.error(error);
});
timerEventEmitter.on('end', (time) => {
dispatcher.destroy();
})
}
This might be a big or small issue, I hope it's the latter but it's most likely the former. My bot is supposed to play audio in a voice chat and it works perfectly fine in one server.
However, when I try playing audio at the same time in two different servers, the audio does some weird stuff. The audio cuts out and ends in one server while playing the other audio in the other server.
Below is the code from above that I use to play the audio. I'm not really getting an error but I do need maybe an explanation or a solution if I want to add this bot to multiple servers. I'm sure there's a good explanation; hopefully it doesn't require a rework.
Also, it's not a bad connection issue either as I tried it on localhost and replit, and they both had that same issue.
let readStream = await fs.createReadStream(mp3);
const dispatcher = await connection.play(readStream);

Ways to login to multiple bot accounts with one script?

The ways I've tried.
Loop through tokens, this is fine but not much room to customise what bot does what. Example having each bot type in a specific channel, with this I've realised the bots type in the same location right after each other.
const auth = require('./tokens.json')
const Discord = require('discord.js')
for (const token of auth.Tokens) {
const client = new Discord.Client()
client.on('ready', () => {
console.log('I am ready !')
console.log(client.user.id)
})
client.login(token)
}
Also by creating multiple instances of a discord.client
const Discord = require('discord.js');
const client1 = new Discord.Client();
const client2 = new Discord.Client();
ect...
client1.once('ready',() => {
})
client1.on('message', async(message) => {
})
client2.once('ready',() => {
})
client2.on('message', async(message) => {
})
client1.login(CONFIG.Token1);
client2.login(CONFIG.Token2);
I am just wondering if there is other ways of doing this, lets say I have 5-6 bots and I do the 2nd method the code will get quite long depending on what i want to add into it.
I did think about adding a loop something like this.
for(var i = 0; i < token.length; i++)
And having a channel id linked to a specific number as the i++ is increasing it. So each bot would get its own number and channel id, but I'm not sure if that's even a thing that would work or if it would be good enough to use.
Any suggestions would be greatly appreciated and thank you for reading.
I think your second method:
creating multiple instances of a discord.client
Would be the best way to do it.
The easiest way to give the bots specific channels is to change their discord permissions and physically assigning them the channels.
Another way could be something like:
client.channelID = <ID of channel you want the bot in>
client2.channelID = <ID of channel you want the bot in>
// ... code
client.on('message', message => {
if (message channel.id !== client.channelID) return;
// ...
I was able to run multiple bots from the same script using this code:
const auth = ['TOKEN1', 'TOKEN2']
const Discord = require('discord.js')
for (const token of auth) {
const client = new Discord.Client()
client.on('ready', () => {
console.log('I am ready !')
console.log(client.user.id)
});
client.on('message', (msg) => {
if (msg.content === '!ping') {msg.reply('pong!')}
});
client.login(token);
}

Is there a way to react to every message ever sent with discord.js

I wanna use an bot to react to every single message in an channel using discord.js f.e. i got an emoji contest channel and i wanna ad an ✅ and an ✖ reaction on every post in there
ofc, all the unnecesary messages are cleaned up so that there are like 50 messages
Fetch the messages already sent in a channel with TextChannel.fetchMessages().
Iterate through the Collection.
Add reactions with Message.react().
When a new message is sent in the channel, you should also add the reactions.
const emojiChannelID = 'ChannelIDHere';
client.on('ready', async () => {
try {
const channel = client.channels.get(emojiChannelID);
if (!channel) return console.error('Invalid ID or missing channel.');
const messages = await channel.fetchMessages({ limit: 100 });
for (const [id, message] of messages) {
await message.react('✅');
await message.react('✖');
}
} catch(err) {
console.error(err);
}
});
client.on('message', async message => {
if (message.channel.id === emojiChannelID) {
try {
await message.react('✅');
await message.react('✖');
} catch(err) {
console.error(err);
}
}
});
In this code, you'll notice I'm using a for...of loop rather than Map.forEach(). The reasoning behind this is that the latter will simply call the methods and move on. This would cause any rejected promises not to be caught. I've also used async/await style rather than then() chains which could easily get messy.
According to https://discord.js.org/#/docs/main/stable/class/TextChannel
you can use fetchMessages
to get all messages from a specific channel, which then returns a collection of Message
Then you can use .react function to apply your reactions to this collection of message by iterating over it and calling .react on each.
Edit:
channelToFetch.fetchMessages()
.then(messages => {
messages.tap(message => {
message.react(`CHARACTER CODE OR EMOJI CODE`).then(() => {
// Do what ever or use async/await syntax if you don't care
about Promise handling
})
})
})

Resources