I am trying to let a bot play a youtube video but only sound in a voice channel if you type a command. I already have a command that lets the bot connect to a voice channel
client.on("ready", () => {
const channel = client.channels.cache.get("922159751759011910");
if(!channel) return console.error("Channel non-existent");
channel.join().then(connection => {
console.log("Connected");
}).catch(e => {
console.error(e)
})
})
But I don't know how to let it play a youtube video. How do I do this?
You could try using discord-player. It has some links to example projects using it, if you want to see how they implement this functionality.
Related
I'm trying to code a Discord bot that would read embed messages sent by another bot and ping a specific role if the embed contains '(FREE)' in the title, as displayed here:
https://i.stack.imgur.com/kPsR1.png
Unfortunately, my code produces nothing. I don't run into any error, the bot simply doesn't post a message when conditions are matched to do so — yet it is online and has the permissions to post messages in the channel.
Any help would be really appreciated. I went through all the questions related to this topic on SO, but I couldn't find a working solution to my issue. I'd like to mention that I'm a beginner in JS.
Thank you so much.
const Discord = require('discord.js');
const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES", "GUILD_WEBHOOKS"] })
client.on('ready', () => {
console.log(`Logged in...`);
});
client.on('messageCreate', (message) => {
if (message.embeds) {
const embed = message.embeds[0]
if (embed.title === '(FREE)') {
return message.channel.send('#Free mint')
}
}
})
Edit: I believe my question is different from the one suggested in the comment as I'm looking for specific content in the embed.
I managed to make the bot work with the following code, thanks #Gavin for suggesting it:
const Discord = require('discord.js');
const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES", "GUILD_WEBHOOKS"] })
client.on('ready', () => {
console.log(`Logged in...`);
});
client.on('messageCreate', message => {
for (let embed of message.embeds) {
if (embed.title.includes('FREE')) {
return message.channel.send("<#&" + roleId + ">")
}
}
});
I have a web app that needs to acces to camera, but I want to ask camera permission manually, because if the web app detects automatically camera permission, it will do it "too late".
What I need is to ask for permission, then I could render a 3rd party javascript function that renders a camera.
With react native is easy, but with normal React I can't find a way to ask when I want those permissions, for Chrome and Safari.
Any idea?
Prior to the link on the comment of #Shubh (thanks) I get it working only for Chrome:
navigator.permissions.query({ name: 'camera' })
.then((permissionObj) => {
console.log(permissionObj.state);
permission = permissionObj.state;
})
.catch((error) => {
console.log('Got error :', error);
});
But this is not supported for iphone IOS (Safari).
Now with getUserMedia() API I have this code semi-working:
let stream = null;
const constraints = {
video: true
};
try {
stream = await navigator.mediaDevices.getUserMedia(constraints);
/* use the stream */
} catch (err) {
/* handle the error */
}
My only problem here is the light on the camera (desktop) get stucked, I'm trying to find now how to "close" the getUserMedia, I just want to grant permissions, like the first way.
Edit: now for turn off the camera I did this:
const askCameraPermission =
async (): Promise<MediaStream | null> => await navigator.mediaDevices.getUserMedia({ video: true });
let localstream: MediaStream | null;
askCameraPermission()
.then(response => {
localstream = response;
})
.then(() => {
localstream?.getTracks().forEach(track => {
track.stop();
});
})
.catch(error => console.log(error));
navigator.getUserMedia({audio:true,video:true}, function(stream) {
stream.getTracks().forEach(x=>x.stop());
}, err=>console.log(err));
Take the stream, get the tracks and stop them to turn off the camera. Camera will still flash, but it will turn off.
Here is the demo: https://codesandbox.io/s/camera-app-86me8?file=/src/App.js
Make sure you check the error in the catch... it told me my problem...didn't have an input device connected!
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);
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);
}
I just want it to say some simple instructions or information in the chat whenever the bot joins a server.
Anyone know how I could do that?
client.on("guildCreate", guild => {
const channels = guild.channels.cache.filter(channel => channel.type == "text");
channels.first().send("Thank you for inviting me!").catch(e => console.log(e));
});