Sorting through html with javascript - 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.

Related

Image not refreshing (discord.js)

So basically I'm trying to create a Discord bot that when you type "!cat" the Discord bot sends an image of a random cat inside of an embed but every time I use the command the image stays the same.... I tried to put the embed variable inside of the function so it refreshes every time someone says "!cat" but it didn't work..... this is the code that I'm using:
const Discord = require('discord.js');
const client = new Discord.Client();
client.once('ready', () => {
console.log('Ready!');
});
client.on('message', message => {
console.log(message.content);
if (message.content === "!cat") {
const catEmbed = new Discord.MessageEmbed()
.setTitle("MEOW!")
.setImage("http://theoldreader.com/kittens/600/400")
.setThumbnail("http://theoldreader.com/kittens/600/400")
message.channel.send(catEmbed)
}
});
client.login('NOT GONNA TELL MY TOKEN');
It looks like a caching issue. Try to append some random character as a query string to your URL. Something like this should work:
client.on('message', (message) => {
if (message.content === '!cat') {
// generate a random string
const rand = Math.random().toString(36).slice(2);
const catEmbed = new Discord.MessageEmbed()
.setTitle('MEOW!')
// append it as a query string
.setImage(`http://theoldreader.com/kittens/600/400?${rand}`)
.setThumbnail(`http://theoldreader.com/kittens/600/400?${rand}`);
message.channel.send(catEmbed);
}
});

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 snekfetch body undefined problem

const Discord = require("discord.js")
const snekfetch = require("snekfetch")
const client = new Discord.Client({disableEveryone: false});
//const CSGO = require("csgo-api"); // Import the npm package.
//const jb = new CSGO.Server('185.198.75.5', '27015') // Set the IP with port.
var prefix2 = "!"
client.on('ready', async ()=> {
snekfetch.get("http://query.li/api/csgo/185.198.75.5/27015").then(r => console.log(r.body.game.players.name));
//jb.getOnlinePlayers().then(data => console.log(data)) // Get & log the data
});
Hello friends, I'm trying to print the players section on http://query.li/api/csgo/185.198.75.5/27015 to message.channel.send but it gives undefined can you help me?
I'm using Google Translate sorry my English so bad :/
You are trying to get the body of the result. But it is null. Your result contains these children: game, whois, status, banner_url, and cached.
And also, your players are an array. So you should select an index to console.log().
Try this:
snekfetch.get("http://query.li/api/csgo/185.198.75.5/27015").then(r => console.log(r.game.players[0].name));
You can use this web site to beautify your response JSON.
EDIT:
If you want to print the names of all players then you can use a foreach() loop for players. Like this:
snekfetch.get("http://query.li/api/csgo/185.198.75.5/27015").then(r => {
r.game.players.forEach(player => {
console.log(player.name)
});
}
);

DiscordJS Database Not Storing Information Ideally

I'm trying to get the Discord bot to create a database that is basically the user map (a row for each user and columns for ID, nick name, avatar URL, etc) when it receives a !getdata command.
I've gotten to the point where the database successfully takes data, in this case the username and user ID, but it displays all the unique values in two columns as long comma separated values (i.e. the username column displays 'user1,user2,user3').
I'm sure this is by design, but I'm really struggling with restructuring. I'd like to either have it take all the data from an object map (client.users or message.guild.members) but I cannot figure it out.
The other option, which is what I'm trying now, is to create a row for each user and then fill in the values that I want to store, but I'm getting nowhere fast.
I'm very new with SQLite (and node/DiscordJS/JS for that matter), so any advice is greatly appreciated.
Index.js
const Discord = require('discord.js');
const client = new Discord.Client();
const sql = require('sqlite3');
let db = new sql.Database("users.sqlite", (err) => {
if (err) {
console.log('Error connecting to the database', err)
} else {
console.log('Database connected.')
}
})
let token = process.env.CLIENT_TOKEN;
let prefix = process.env.PREFIX ;
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
db.run(`CREATE TABLE IF NOT EXISTS users(username TEXT, id TEXT)`);
})
client.on('message', function(message) {
if (!message.content.startsWith(prefix));
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if (command === 'getdata') {
let username = message.guild.members.map(m=>m.user.username);
let userid = message.guild.members.map(m=>m.user.id);
db.run(`INSERT OR REPLACE INTO users(username, id) VALUES(?,?)`, [`${username}`,`${userid}`]);
return message.channel.send(`User database updated.`);
}
});
client.login(token);
If you're curious as to the formatting or way things are written, the answer is two fold:
I'm pretty new at this
This was the only way I could get the values in the database to return something other than null
Thanks in advance,
First off, welcome to the site.
I hope that I can shine some light here without diving into refactoring your code or making you change anything major.
One thing sticks out to me as to why you are storing an array instead of a single value.
let username = message.guild.members.map(m=>m.user.username);
let userid = message.guild.members.map(m=>m.user.id);
The .map call returns an array, not a single value.
Each user that issues a command is part of the message object. If I remember correctly, you would want this to be something like...
(simplified version)
const { username, id } = message.member.user;
db.run(`INSERT OR REPLACE INTO users(username, id) VALUES(?,?)`, [username, id]);
// ...
User documentation can be found here
Edit:
If you wanted to build the database for all users in that one command you could do something like the following with a bulk insert... (quick and dirty)
db.serialize(() => {
db.run('BEGIN TRANSACTION;');
// execute inserts in transaction
for (const m of message.guild.members) {
db.run('INSERT OR REPLACE INTO users(username, id) VALUES(?,?);', [m.user.username, m.user.id]);
}
// commit all inserts :)
db.run('COMMIT;')
});
message.channel.send('User database updated.');
Control flow documenation
Hopefully this points you in the right direction :)

generalChannel.send is not a function

I'm creating a discord bot, and I am trying to make it so that it would greet everyone when it turns on. I have been using bot.channels.get to find the channel and so far that part of the code works fine. It stops working when it tries to send a message.
I have tried all combinations of bot.channels.get and bot.channels.find, together with generalChannel.send and generalChannel.sendMessage, but to still no avail.
const Discord = require('discord.js');
const fs = require('fs');
const bot = new Discord.Client();
let rawVariables = fs.readFileSync('variables.json');
let variables = JSON.parse(rawVariables);
var generalChannel;
bot.on('ready', () => {
generalChannel = bot.channels.get(variables.Channels.general);
generalChannel.send("Helllo!");
});
bot.login(variables.BotToken);
I just need it to message the channel when it starts up.
variables.Channels.general should be a string of the id of your channel
you can get the id by rightclicking on a channel -> copy id
it should look something like this:
'408632672669273'

Categories

Resources