I have been looking up how to play sound with node.js all day, I can't use "document.getElementById" and I can't use "new Audio" either. I want it to be able to play sound when I do #everyone in my chatroom. The audio file is name "ping.mp3" and is in the same path as my main node.js file. I need some recommendations or code snippets. Thanks!
This is a code snippet of where the ping code is.
function highlight(message){
if(message == "") {
return message
}
let mentions = message.match(/#\b([A-Za-z0-9]+)\b/g)
let urlCheck1 = message.split(` `)
if (mentions === null ) { return message }
for (i = 0; i < mentions.length; i++) {
let urlCheck = urlCheck1[i].includes(`http`)
let mention = mentions[i].substring(1)
if(sesskx.has(mention) && !urlCheck) {
message = message.replace(mentions[i], `<span class="name-color">#${mention}</span>`)
} else if (mention == 'everyone') {
ping.play();
message = message.replace(mentions[i], `<span class="name-color">#${mention}</span>`)
} else if (mention == 'here') {
ping.play();
message = message.replace(mentions[i], `<span class="name-color">#${mention}</span>`)
}
else {
return message;
}
}
return message
};
I want "ping.play();" to make the sound.
This is possible but kind of tricky. You can use play-sound to take care of it for you:
var player = require('play-sound')(opts = {})
player.play('foo.mp3', function(err){
if (err) throw err
});
What it basically does is look for sound players in the environment and try to use one of them to play the mp3:
const { spawn, execSync } = require('child_process');
// List of players used
const players = [
'mplayer',
'afplay',
'mpg123',
'mpg321',
'play',
'omxplayer',
'aplay',
'cmdmp3'
];
// find a player by seeing what command doesn't error
let player;
for(const p of players) {
if (isExec(p)) {
player = p;
break;
}
}
function isExec(command) {
try{
execSync(command)
return true
}
catch {
return false
}
}
spawn(player, ['ping.mp3']);
If you are creating a node.js server, node.js is back-end/server side, so users won't be able to hear anything that happens if a sound is "played" there. So you'll have to do it client side using "new Audio()", when the client receives a message including "#everyone" (which I don't understand why you cant use, you can send the mp3 file to the client with the page.).
I also made an example for you on repl.
Related
so i was told to Present a loader to the user when a call is made to the server (indicating the server is calculating) Present an error to the user if the input number is more than 50, and do not send a server request Try passing the number 42 to the server. The server will send back an error, present this error to the user.
now what i did is everything besides the last error to present it to the user.
i have tried everything i could think of, and no matter what the user types, it displays both of the messages.
this is my code:
const clcBtn = document.getElementById("calcButton");
let clcInput = document.getElementById("calcInput");
const result = document.getElementById('paragraph');
const loader = document.getElementById('spinner');
const error = document.getElementById('error-message');
const serverError = document.getElementById('server-error');
clcBtn.addEventListener("click", calcFunc);
function numValidate(value) {
if(value > 50) {
return false;
}
return true;
}
function calcFunc() {
if (!numValidate (clcInput.value)) {
error.style.display = "block"
setTimeout(() => {
error.style.display = "none";
}, 5000);
console.error("Can't be larger than 50") // only bec it's a cool feature :D
return;
}
loader.classList.add("spinner-border");
fetch(`http://localhost:5050/fibonacci/${clcInput.value}`).then(function (response) {
return response.json().then(function (data) {
result.innerHTML = data.result;
});
});
setTimeout(() => {
loader.classList.remove("spinner-border");
}, 1000);
}
this is my code with what i have tried to add (on of the things i have tried.. this is the best output i could come with)
code:
// additional code to present to the user the error message if the input value is equal to 42.
clcBtn.addEventListener("click", errMsg);
function numValidateTwo(value) {
if(value === 42) {
return true;
}
return false;
}
function errMsg() {
if (!numValidateTwo (clcInput.value)) {
serverError.style.display = "block";
}
return;
}
a little bit more about what i am trying to achieve:
i want to present this error message to the user, whenever the input value is equal to 42.
is it related to async or callback? which i need to go through the lectures again.. but right now i need to solve this bec i have no time.
what did i do wrong ?
and how i can make it work?
can someone explain this to me?
thanks in advance!
I am working on creating a telegram bot, I want to make an anti-spam system, that is, when a person presses a button too many times, the bot will freeze for him for a certain number of seconds, it is possible to write a message about blocking. People in other matters do not help me.
import {
bot
} from '../token.js';
import {
keyboardMain
} from '../keyboards/keyboardsMain.js';
export function commands() {
bot.on('message', msg => {
const text = msg.text;
const chatId = msg.chat.id;
if (text === '/start') {
return bot.sendMessage(chatId, 'hello', keyboardMain);
}
return bot.sendMessage(chatId, 'error');
});
}
Do you use telegraf as telegram module ? If yes, you can kick users from channels or groups.
here is a little piece that i made for you :)
you can apply it to anything ^_^
var tps = 0;
var allowpassage = false;
var detectspamon = document;
c = function() {
setTimeout(()=>{
console.log("got clicks:",tps);
if (tps==0) {console.log("no clicking detected");}
else if (tps==1) {console.log("success");allowpassage=true;}
else {console.log("too many clicks per second");}
tps=0;
console.log("setting clicks to 0");
},500);
}
detectspamon.onclick = () => {tps++;console.log(tps);c(tps);}
const Discord = require("discord.js"),
bot = new Discord.Client();
let pre = "?"
bot.on("message", async msg => {
var msgArray = msg.content.split(" ");
var args = msgArray.slice(1);
var prisonerRole = msg.guild.roles.find("name", "Prisoner");
let command = msgArray[0];
if (command == `${pre}roll`) {
if (!msg.member.roles.has(prisonerRole.id)) {
roll = Math.floor(Math.random()*6)+1;
msg.reply(`You rolled a ${roll}`)
} else {
msg.reply(`HaHa NOOB, you're in prison you don't get priveleges!`)
}
}
if (command == `${pre}kick`) {
var leaderRole = msg.guild.roles.find("name", "LEADER");
var co_leaderRole = msg.guild.roles.find("name", "CO-LEADER");
if (msg.member.roles.has(leaderRole.id) ||
msg.member.roles.has(co_leaderRole.id)) {
var kickUser = msg.guild.member(msg.mentions.users.first());
var kickReason = args.join(" ").slice(22);
msg.guild.member(kickUser).kick();
msg.channel.send(`${msg.author} has kicked ${kickUser}\nReason: ${kickReason}`);
} else {
return msg.reply("Ya pleb, you can't kick people!");
}
}
})
bot.login("token").then(function() {
console.log('Good!')
}, function(err) {
console.log('Still good, as long as the process now exits.')
bot.destroy()
})
Everything works except actually kicking the person. The message sends nut it doesn't kick people. For example, when I type in ?kick #BobNuggets#4576 inactive, it says
#rishabhase has kicked #BobNuggets
Reason: inactive
But it doesn't actually kick the user, which is weird, can you help me?
Change
msg.guild.member(kickUser).kick();
to
kickUser.kick();
also, make sure the bot is elevated in hierarchy
Use kickUser.kick();
I recommend using a command handler to neaten up your code. You don't want all your commands in one .js file.
Try something like this for the Ban command itself. I use this for my Bot:
client.on("message", (message) => {
if (message.content.startsWith("!ban")) {
if(!message.member.roles.find("name", "Role that can use this bot"))
return;
// Easy way to get member object though mentions.
var member= message.mentions.members.first();
// ban
member.ban().then((member) => {
// Successmessage
message.channel.send(":wave: " + member.displayName + " has been successfully banned :point_right: ");
}).catch(() => {
// Failmessage
message.channel.send("Access Denied");
});
}
});
That should work, set the role you want to use it (cAsE sEnSiTiVe) and change !ban to whatever you feel like using. If you change all "ban"s in this to kick, it will have the same effect. If this helped you, mark this as the answer so others can find it, if not, keep looking :)
I can't get tracks to skip on our music bot without it panicking and deleting the entire playlist. More details below.
On command, this bot will use YouTube-DL to download a video from YouTube or track from BandCamp and play it back through a voice channel. The track is downloaded, loaded into an array and they play back one after the other. When the track finishes, it moves on to the next without a problem. But when it comes to skipping tracks manually, it's like the whole function bugs out and runs repeatedly until the playlist is empty and the files have been removed.
A few variables to get us started:
// References
var VC;
var TC;
var AS;
var DS;
var playlist = new Array();
var reqlist = new Array();
var volume = 100;
var fulltitle;
This is the function that goes to the next track:
function Next()
{
if(!(DS===undefined)) DS.pause();
if (playlist.length > 0)
{
// Delete the first audio file in the list (the one that just finished)
var fileRemove = false
try {
fs.remove(playlist[0].file)
console.log('File removed!');
fileRemove = true
} catch(e) {
fileRemove = false
console.err(e)
}
if (fileRemove = true) {
playlist.splice(0, 1);
console.log('Spliced!');
} else {
console.err('Could not splice or file not removed.')
}
//console.log(playlist)
//fulltitle = playlist[0].info.fulltitle
return StartPlay();
}
console.log('Length: ' + playlist.length)
if(playlist.length === 0) {
client.user.setPresence( { status: 'idle', game: { name: null } } )
}// else {
// // Start playing
// return StartPlay();
// }
}
Here's StartPlay():
function StartPlay() // Automatically plays queue once a song has been added successfully
{
if (playlist.length >= 1) {
// Play the audio file
DS = AS.playFile(playlist[0].file);
DS.passes = 12;
DS.setVolume(volume/200.0);
//fulltitle = playlist[0].info.fulltitle
// Display song title in 'Game played'
client.user.setPresence({ status: 'online', game: { type:2, name: fulltitle } });
// Once the song is done
DS.on('end', reason => {
// Go to the next track
Next();
});
}
}
And here's the command to get it to skip:
case 'skip':
if(VC===undefined) return;
if(TC===undefined) return;
if(!CheckTCVC(message)) return;
if(playlist.length === 0) return message.channel.send('There is nothing to skip.');
if(playlist.length === 1) return message.channel.send('There is nothing to skip to. Queue something else first or use `' + prefix + 'leave`.')
if(message.content.length > 5) {
const trackNumber = parseInt(message.content.split(' ')[1])
if (trackNumber !== 1) {
fs.remove(playlist[trackNumber-1].file).then(() => {
console.log('File removed!');
playlist.splice(0, trackNumber-1)
message.channel.send('Future song skipped!')
}).catch(err => {
console.error(err)
})
} else {
Next();
message.channel.send('Current song skipped!')
}
} else {
Next();
message.channel.send('Song skipped!')
}
break;
I'm not sure what else anyone will need from the code. Just let me know and I'll paste it in.
Here's a link to the Discord.JS documentation, not that I think it's really needed here: https://discord.js.org/#/docs/main/stable/general/welcome
Thanks in advance!
When you call playlist.splice(0, trackNumber-1), I believe you're using splice wrong. According to the MDN documentation, splice has two arguments: The starting position, and the amount of elements to remove. You've put 0 as your position, and trackNumber as the amount to remove. So if track number is 42, you'll remove 42 elements from the array. Try using playlist.splice(trackNumber-1, 1) to see if that gives you the desired effect.
This is what I have to switch between channels in the chat, but it does not leave the channel even when calling the .leave() function
new Twilio.Chat.Client.create(data.token).then(function(chatClient) {
$(".change-channel").on("click", function(){
if ($(this).text() == "General Button"){
if(currentChannel != "general"){
chatClient.getSubscribedChannels().then(joinChannel(chatClient, 'general','General Chat Channel'));
currentChannel.leave();
}
// if not current channel general then:
}
if ($(this).text() == "Specific Button"){
if(currentChannel != "generals"){
chatClient.getSubscribedChannels().then(joinChannel(chatClient, 'generals','Generals Chat Channel'));
currentChannel.leave();
}
// if not currentchannel generals then:
}
});
});
Twilio developer evangelist here.
I think the channels may be getting confused as you join and leave them and promises and callbacks are resolved. I would try making sure that you have left the channel first, before joining the next one and disallowing the switching of channels while the process is going on.
Something like this:
new Twilio.Chat.Client.create(data.token).then(function(chatClient) {
let currentChannel, nextChannel, nextChannelName;
let changingChannel = false;
// fired when a channel has been left completely
chatClient.on('channelLeft', channel => {
chatClient.getSubscribedChannels()
.then(joinChannel(chatClient, nextChannel, nextChannelName));
})
// fired when a channel has been successfully joined
chatClient.on('channelJoined', channel => {
currentChannel = channel;
changingChannel = false;
nextChannel = nextChannelName = null;
})
$(".change-channel").on("click", function(){
if (changingChannel) {
// already switching channels, don't do anything
return;
}
if ($(this).text() == "General Button"){
if(currentChannel.uniqueName != "general"){
changingChannel = true;
nextChannel = 'general';
nextChannelName = 'General Chat Channel';
// start the process to leave the channel
currentChannel.leave();
currentChannel = null;
}
// if not current channel general then:
}
if ($(this).text() == "Specific Button"){
if(currentChannel.uniqueName != "generals"){
changingChannel = true;
nextChannel = 'generals';
nextChannelName = 'Generals Chat Channel';
// start the process to leave the channel
currentChannel.leave();
currentChannel = null;
}
// if not currentchannel generals then:
}
});
});
Let me know if that helps at all.