How to create arguments from a message - javascript

I am trying to make a music bot for my discord server, I have it set to play the music, but I can't figure out how to make it play a link that the user inputs
client.on("message", message => {
if (message.content.startsWith("^play")) {
let channel = client.channels.get('496722898858278912');
const ytdl = require('ytdl-core');
const streamOptions = {
seek: 0,
volume: 1
};
const broadcast = client.createVoiceBroadcast();
channel.join()
.then(connection => {
const stream = ytdl(('https://www.youtube.com/watch?v=XAWgeLF9EVQ'), {filter: 'audioonly'});
broadcast.playStream(stream);
const dispatcher = connection.playBroadcast(broadcast);
});
}
});
The link in the code would be replaced with the user submitted link.

To create arguments, you can split the content of the message using ' ' as separator, the arguments are the elements of that array except for the first (that's the command):
// message.content: "^play https://youtube.com/blablabla other arguments"
let args = message.content.split(' '); // ["^play", "https://youtube.com/blablabla", "other", "arguments"]: the string got splitted into different parts
args.shift(); // remove the first element (the command)
// you can do all your stuff, when you need the link you find it in args[0]
const stream = ytdl((args[0]), { filter : 'audioonly' });
Please note that the first argument is not granted to be a valid youtube link, so check it or prepare your code to handle an invalid argument.

Related

discord bot nested await message

Attempting to implement texas hold em poker in discord with a bot using node js.
Currently have a problem try to nest
client.on('message', message => {
calls. The idea behind these is that the first one looks for the !poker command, and subsequent ones listen for joining players, player bets etc.
code:
const Discord = require('discord.js');
const dotenv = require('dotenv').config();
const Game = require("./classes.js").Game
const Player = require("./classes.js").Player
// create a new Discord client
const client = new Discord.Client();
// when the client is ready, run this code
// this event will only trigger one time after logging in
client.once('ready', () => {
console.log('Ready!');
});
let prefix = '!';
client.on('message', message => {
//prevent feedback loops
if (!message.content.startsWith(prefix) || message.author.bot) return;
if (message.content.startsWith(`${prefix}poker`)){
//getting args
const args = message.content.slice(prefix.length).trim().split(' ');
const command = args.shift().toLowerCase();
//converting to relevant data type
let no_players = parseInt(args[0]);
let money = parseInt(args[1])
//initialising game object and card deck
let game = new Game();
game.deck = game.createDeck();
//list to contain players (will be objects from the Player class)
let players = [];
//list to contain player usernames, will be used to identify if someone has already joined
let player_users = [];
// loop until we have enough players, as specified by the first input arguemnt
while (players.length <= no_players){
//now wait for a join message
client.on('message', message => {
//if message == join, and the player has not already joined
if (message.content.startsWith('join')){
if (!players.includes(message.author.username)){
let newPlayer = new Player(message.author.username,money);
players.push(newPlayer);
player_users.push(message.author.username);
}
}
});
}
//debugging purposes
console.log(players)
}
if (message.content.startsWith(`${prefix}hands`)){
message.channel.send("Here are the poker hands", {files: ["poker-hand-rankings-mobile.png"]});
}
});
client.login(process.env.TOKEN);
The command syntax in discord will look like !poker {number of players} {betting money for each player}
Other functionality in create decks etc works fine.
When I run in the debugger it doesnt seem to enter the second client.on code block, and I recieve this error upon running FATAL ERROR: MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory
Not sure if my overall approach is flawed here, i.e. discord.js cant have two processes waiting for messages running at the same time. Or if there is variable overlap between defining message.
Considering scrapping and moving to python so any help would be greatly appreciated.

Discord.js | How to set output random from given jsondata links?

I'm trying to create random gif giver when people execute command !hp-random. I made a jsonData const here:
const jsonData = {
"1":"https://media.giphy.com/media/12nfFCZA0vyrSw/giphy.gif",
"2":"https://media.giphy.com/media/26BRzozg4TCBXv6QU/giphy.gif",
"3":"https://media.giphy.com/media/PXvCWUnmqVdks/giphy.gif",
"4":"https://media.giphy.com/media/7Yif3ae99ksCc/giphy.gif",
"5":"https://media.giphy.com/media/R65bZxLDrX2Mw/giphy.gif",
"6":"https://media.giphy.com/media/6jemHpKLDe27C/giphy.gif",
"7":"https://media.giphy.com/media/LLxwPAjfpLak8/giphy.gif",
"8":"https://media.giphy.com/media/oydIov5VxxXcG0mu1P/giphy.gif",
"9":"https://media.giphy.com/media/S3F8kkGTHZ4Y/giphy.gif",
"10":"https://media.giphy.com/media/RLo8seQ4drmAW02wSA/giphy.gif",
}
right after that I put this:
const values = Object.values(jsonData)
const randomValue = values[parseInt(Math.random(values.length))]
module.exports = {
name: 'hp-random',
description: "Gives random gif in chat",
execute(client, message, args, Discord) {
console.log(randomValue);
//message.channel.send(`${randomValue}`);
}
}
My problem is that it only outputs the first 1 and not the other 9 outputs in jsonData: outputs only this>"https://media.giphy.com/media/12nfFCZA0vyrSw/giphy.gif"
Console: (me executing the command in discord chat btw)
\Discord bot> node .
I'm working
https://media.giphy.com/media/12nfFCZA0vyrSw/giphy.gif
https://media.giphy.com/media/12nfFCZA0vyrSw/giphy.gif
https://media.giphy.com/media/12nfFCZA0vyrSw/giphy.gif
https://media.giphy.com/media/12nfFCZA0vyrSw/giphy.gif
https://media.giphy.com/media/12nfFCZA0vyrSw/giphy.gif
First, you need to move const randomValue = values[parseInt(Math.random(values.length))] inside your execute method so you create a new random variable every time a message is coming in.
The other issue is your random function. Math.random() doesn't take any parameters, so you can't call Math.random(values.length) and expect to call it anything else than a number between 0 and 1. You need to multiply the random value by the length of the array instead:
module.exports = {
name: 'hp-random',
description: 'Gives random gif in chat',
execute(client, message, args, Discord) {
const values = Object.values(jsonData);
const randomValue = values[parseInt(Math.random() * values.length)];
console.log(randomValue);
// message.channel.send(randomValue);
},
};

Sorting through html with javascript

I am making a discord bot in javascript. My intent is to visit https://api.chess.com/pub/player/edisonst/stats and somehow parse only the chess_daily last rating, chess_rapid last rating, chess_bullet last rating, chess_blitz last rating, etc. I do not know how to choose only those elements.
Here is my existing code.
const discord = require('discord.js')
const fetch = require('node-fetch');
const client = new discord.Client();
const prefix = '!';
client.once('ready', () =>{
console.log('Console is online');
});
client.on('message', async message => {
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length);
let url = "https://api.chess.com/pub/player/" + args + "stats";
})
In my last line of code I arrive at the site that I wish to get the information from, but I don't know how to get just those bits. Thank you for any and all help that I may receive.
You can use jsdom to "render" page that you get and manipulate it as you would in browser. This way you can select elements and get their contents.

discord.js How to revoke a ban of a banned user using code?

Revoking A Ban Using Code
So, I am making a moderation discord bot using VS Code and I have already set up a ban command. I want to make a unban command (revoking a ban) too so that the user can easily unban a user and not have to go into Server Settings to do it.
I know you can do it because I have been using another bot, GAwesomeBot, that is able to do it.
Link to GAwesomeBot: https://gawesomebot.com
I am a little new to Stack Overflow and this is my first question so pardon me if I am doing anything wrong.
Consider using GuildMemberManager#unban
https://discord.js.org/#/docs/main/stable/class/GuildMemberManager?scrollTo=unban
let guildMemberManager, toUnbanSnowflake;
guildMemberManager.unban(toUnbanSnowflake); // Takes UserResolveable as argument
First you want to define the user that you are unbanning.
Because the user is already banned you will have to mention the user by their ID and then unbanning them.
let args = message.content.split(/ +/g); //Split the message by every space
let user = message.guild.members.cache.get(args[1]); //getting the user
user.unban({ reason: args[2].length > 0 ? args[2] : 'No reason provided.' }); //Unbanning the user
The full example:
//Define your variables
const Discord = require('discord.js');
const client = new Discord.Client();
var prefix = 'your-prefix-here';
//Add a message event listener
client.on('message', () => {
let args = message.content.split(/ +/g); //Split the message by every space
if (message.content.toLowerCase() === prefix + 'unban') {
let user = message.guild.members.cache.get(args[1]); //getting the user
if (!user) return message.channel.send('Please specify a user ID');
user.unban({ reason: args[2].length > 0 ? args[2] : 'No reason provided.' }).then(() => message.channel.send('Success');
}
});

socket.io send data to matching socket's

when a user connects to my socket
I add to a session map:
io.on('connection', function (socket) {
sessionMap.set(socket.id,socket);
}
my session Map
var SessionMap = {};
module.exports = {
set: function(key,value){
SessionMap[key] = value;
},
get: function(key){
return SessionMap[key]
},
delete: function(key){
delete SessionMap[key]
},
all: function(){
return SessionMap
}
}
And also save my user socket id in a class player:
socket.on('addPlayer-Queue', (result) => {
sessionMap.set(socket.id,socket);
queue.addPlayer(new Player({
id: result.id,
name: result.name,
mmr: result.mmr
}, socket.id));
And I have a function that selects two players that are connected (where I save in an array) and create a "battle" and then I wanted to send to the socket that was selected / matched for this battle
the battle dice
This is my role that selects both players and creates a battle:
searching() {
const firstPlayer = this.getRandomPlayer();
const secondPlayer = this.players.find(
playerTwo =>
playerTwo.mmr < this.calculateLessThanPercentage(firstPlayer) &&
playerTwo.mmr > this.calculateGreaterThanPercentage(firstPlayer) &&
playerTwo.id != firstPlayer.id
);
if (!secondPlayer) {
return null;
}
const matchedPlayers = [firstPlayer, secondPlayer];
this.removePlayers(matchedPlayers);
return new Match(matchedPlayers);
}
}
And also when connecting I use a set interval to be performing this function every 1 second
But my difficulty is how I would send the data from this battle to the corresponding socket's
my relation socket with player
When a player enters my event I create a player by going through socket id
And I also make a session map of this socket
sessionMap.set(socket.id,socket);
my class player:
class Player {
constructor(player,socketId) {
this.id = player.id
this.socketId = socketId
this.name = player.name
this.mmr = player.mmr
}
}
module.exports = Player;
const getMatchConfigurationFor = player => {
/* configure and return the payload notifying the player of the match */
}
const configurePlayersForNewMatch = () => matchedPlayers.forEach(player =>
sessionMap.get(player.socketid)
.broadcast.to(player.socketid)
.emit(messageTags.MATCH_CONFIGURATION,
getMatchConfigurationFor(player)))
regarding where to do this work .. the single responsibility principle says that a function should have a singular clear purpose. So the search method should search for matching players, not configure the match. You should do this work in another function that is called while configuring the match, which itself is called after the search returns successfully. I've provided the wrapper function for that here: it is written in a fashion to expect the relevant pieces are in scope. You could rewrite it as a proper function with parameters if you prefer.
This is a work in progress solution for Felipe, posted by request.
After a match is found, you'd probably want to emit a MatchFound object to both clients detailing information about the match (including information about their opponent). Once a client gets this, you can initiate anything the client needs for a match (load a level, display names, or a lobby).

Categories

Resources