Added discord scraper

This commit is contained in:
eTronic
2018-06-28 23:19:51 -04:00
parent 6e4a855f02
commit e0cbcfe163
5 changed files with 390 additions and 10 deletions

View File

@@ -4,6 +4,7 @@ import WebSocket from 'ws';
import { mainBearerToken, players } from './config.json';
import Account from './classes/Account';
import Scraper from './scrapeDiscord.js';
const HOST = 'api-quiz.hype.space';
const INIT_TOKEN = mainBearerToken;
@@ -13,8 +14,14 @@ const headers = {
'user-agent': 'okhttp/3.8.0',
};
const PLAY_USING_DISCORD = true;
const SECONDS_BUFFER = 1; // How many seconds left you want to give before discord answers are used.
let playersInGame = players.map((player) => new Account(player));
const scraper = new Scraper();
scraper.run();
const removePlayer = (userId) => {
playersInGame = playersInGame.filter((player) => player.userId !== userId);
};
@@ -128,6 +135,7 @@ request('https://api-quiz.hype.space/shows/now', (error, response, body) => {
const { answerCounts, advancingPlayersCount } = questionSummary;
const index = answerCounts.findIndex(answer => answer.correct);
const correctAnswer = answerCounts[index];
scraper.endQuestion(index);
const wrongPlayers = [];
playersInGame.forEach((player) => {
@@ -160,16 +168,35 @@ request('https://api-quiz.hype.space/shows/now', (error, response, body) => {
if (type !== 'question') return;
const { questionNumber, question: theQuestion, questionId, timeLeftMs } = JSON.parse(data);
let timesUp = false;
/*
setTimeout(() => {
timesUp = true;
console.log('\nNo Answer: Splitting 1,2,3 to ensure automatically...');
playersInGame.forEach((player, index) => {
console.log(`Player ${player.username} sent answer ${(index % 3) + 1}`);
player.sendAnswer(questionId, answers[index % 3].answerId)
});
}, timeLeftMs - 300);*/
if (PLAY_USING_DISCORD) {
setTimeout(() => {
timesUp = true;
console.log('\nPlaying using Discord...');
const weights = scraper.getWeights();
console.log('WEIGHTS:', weights);
const totalWeight = weights
.filter(weight => weight > 0)
.reduce((accumulator, currentValue) => accumulator + currentValue);
const normalized = weights.map(weight => {
const zeroNegatives = weight < 0 ? 0 : weight;
return Math.round((zeroNegatives / totalWeight) * playersInGame.length);
});
normalized.forEach((playersAssignedToAnswer, index) => {
for (let i = 0; i < playersAssignedToAnswer; i++) {
const player = playersInGame[i];
player.sendAnswer(questionId, answers[index].answerId)
console.log(`Player ${player.username} sent answer ${index + 1}: ${answers[index].text}!`);
}
});
}, timeLeftMs - SECONDS_BUFFER * 1000);
}
scraper.startQuestion(questionId);
console.log('\n==================================\n');
console.log(`Question #${questionNumber} with ${Math.floor(timeLeftMs / 1000)} seconds left:`);
console.log(`\n${theQuestion}`);
@@ -177,7 +204,7 @@ request('https://api-quiz.hype.space/shows/now', (error, response, body) => {
console.log(`Choice 2: ${answers[1].text}`);
console.log(`Choice 3: ${answers[2].text}\n`);
if (playersInGame.length > 0) {
if (playersInGame.length > 0 && !PLAY_USING_DISCORD) {
prompt.start();
prompt.get(['answer'], (err, res) => {
console.log();

43
package-lock.json generated
View File

@@ -1083,6 +1083,34 @@
"repeating": "2.0.1"
}
},
"discord.js": {
"version": "11.3.2",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-11.3.2.tgz",
"integrity": "sha512-Abw9CTMX3Jb47IeRffqx2VNSnXl/OsTdQzhvbw/JnqCyqc2imAocc7pX2HoRmgKd8CgSqsjBFBneusz/E16e6A==",
"requires": {
"long": "4.0.0",
"prism-media": "0.0.2",
"snekfetch": "3.6.4",
"tweetnacl": "1.0.0",
"ws": "4.1.0"
},
"dependencies": {
"tweetnacl": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.0.tgz",
"integrity": "sha1-cT2LgY2kIGh0C/aDhtBHnmb8ins="
},
"ws": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz",
"integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==",
"requires": {
"async-limiter": "1.0.0",
"safe-buffer": "5.1.2"
}
}
}
},
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
@@ -2071,6 +2099,11 @@
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
"dev": true
},
"long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
},
"loose-envify": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
@@ -2282,6 +2315,11 @@
"dev": true,
"optional": true
},
"prism-media": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/prism-media/-/prism-media-0.0.2.tgz",
"integrity": "sha512-L6yc8P5NVG35ivzvfI7bcTYzqFV+K8gTfX9YaJbmIFfMXTs71RMnAupvTQPTCteGsiOy9QcNLkQyWjAafY/hCQ=="
},
"private": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
@@ -2552,6 +2590,11 @@
"integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
"dev": true
},
"snekfetch": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/snekfetch/-/snekfetch-3.6.4.tgz",
"integrity": "sha512-NjxjITIj04Ffqid5lqr7XdgwM7X61c/Dns073Ly170bPQHLm6jkmelye/eglS++1nfTWktpP6Y2bFXjdPlQqdw=="
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",

View File

@@ -11,6 +11,7 @@
"avatar": "babel-node changeAvatar.js --presets env,es2016,stage-2",
"cashout": "babel-node cashout.js --presets env,es2016,stage-2",
"answers": "babel-node getWeightedAnswers.js --presets env,es2016,stage-2",
"discord": "babel-node scrapeDiscord.js --presets env,es2016,stage-2",
"weekly": "babel-node makeItRain.js --presets env,es2016,stage-2"
},
"author": "",
@@ -23,6 +24,7 @@
},
"dependencies": {
"aws-sign": "^0.1.2",
"discord.js": "^11.3.2",
"http": "0.0.0",
"https": "^1.0.0",
"moniker": "^0.1.2",

106
playerAnswers.json Normal file
View File

@@ -0,0 +1,106 @@
{
"answers": {
"51598": [
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"number": "3"
}
},
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"number": "3"
}
},
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"number": "3",
"post": "apg"
}
},
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"number": "2",
"post": "apg"
}
},
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"number": "1",
"post": "?"
}
},
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"pre": "not",
"number": "2"
}
}
],
"98342": [
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"number": "1"
}
},
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"number": "1",
"post": "apg"
}
},
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"number": "2"
}
},
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"pre": "not",
"number": "3"
}
},
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"number": "3",
"post": "?"
}
},
{
"userId": "111146692547473408",
"username": "eTronic",
"answer": {
"number": "2"
}
},
{
"userId": "429872760303386647",
"username": "Mr. Peabody $29 Androids",
"answer": {
"number": "1"
}
}
]
}
}

202
scrapeDiscord.js Normal file
View File

@@ -0,0 +1,202 @@
import fs from 'fs';
import Discord from 'discord.js';
import { discordToken } from './config.json';
const DISCORD_TOKEN = discordToken;
const servers = [
{
name: 'Trivia Community',
id: '414461171974930434',
channels: [
{
name: 'roles-hq',
id: '454309318330810376',
weightModifier: 0.75,
},
{
name: 'public-hq',
id: '449575067333033984',
weightModifier: 0.25,
},
],
},
{
name: 'Trivia API',
id: '460797927279951892',
channels: [
{
name: 'testing-please-ignore',
id: '461599924488896512',
weightModifier: 1,
},
],
},
];
const weights = {
'standard': 3,
'apg': 5,
'not': -2,
'w': 0.5,
'?': 0.8,
'apb': 1,
};
export default class Scraper {
constructor() {
this.answers = [];
this.questionId = null;
this.collect = false;
this.weights = [0, 0, 0];
}
run() {
const client = new Discord.Client();
client.on('ready', () => {
console.log(`Discord Scraper... Logged in as ${client.user.tag}!`);
});
client.on('message', msg => {
if (this.collect) {
this.scrapeContents(msg);
}
});
client.login(DISCORD_TOKEN);
}
getWeights() {
return this.weights;
}
endQuestion(answerIndex) {
// use questionIndex to compare answers.
this.scoreUsers(answerIndex);
this.saveContents();
this.collect = false;
}
startQuestion(questionId) {
this.collect = true;
this.questionId = questionId;
this.answers = [];
this.weights = [0, 0, 0];
}
scoreUsers(answerIndex) {
const correctAnswer = answerIndex + 1;
this.answers.forEach((answer, index) => {
const { pre } = answer;
const negated = pre && pre === '?';
if (answer.number === correctAnswer) {
this.answers[index].correct = !negated;
} else {
this.answers[index].correct = negated;
}
});
}
scrapeContents(msg) {
const { channel, guild } = msg;
if (!guild || !channel) return;
const validServer = servers.find(({ id }) => id === guild.id);
if (!validServer) return;
const validChannel = validServer.channels.find(({ id }) => id === channel.id);
if (!validChannel) return;
const { author, content } = msg;
const { id: userId, username } = author;
const cleanedMessage = content.trim().replace(' ', '').toLowerCase();
const matchedMessage = /((w|not)?([123])([?]|apg|apb)?)/g.exec(cleanedMessage);
if (!matchedMessage || matchedMessage.length === 0) return;
const fullAnswer = matchedMessage[0];
const answer = {
pre: matchedMessage[2],
number: matchedMessage[3],
post: matchedMessage[4],
};
let weight = this.weightAnswer(userId, answer);
weight = weight * validChannel.weightModifier;
this.logAnswer(userId, username, answer, weight);
/*
This is for debugging. You don't want this during game.
console.log(`\n${validServer.name} => #${validChannel.name}`);
console.log(`${username}: ${fullAnswer}`);
console.log(`This answer carries weight modifier: ${weight}`);
*/
}
weightAnswer(id, answer) {
let weight = 0;
const { pre, post } = answer;
if (pre) {
weight += weights[pre] || 0;
}
if (post) {
weight += weights[post] || 0;
}
if (!pre && !post) {
weight += weights['standard'];
}
return weight;
}
logAnswer(userId, username, answer, weight) {
const userAnswer = {
userId,
username,
answer: {
...answer,
},
};
const { number } = answer;
if (['1','2','3'].includes(number)) {
this.weights[number - 1] += weight;
}
this.answers.push(userAnswer);
}
saveContents() {
fs.readFile('playerAnswers.json', 'utf8', (err, data) => {
if (err) {
console.log('Error reading playerAnswers for writing: ', err);
} else {
const playerAnswers = JSON.parse(data);
if (!playerAnswers.answers) playerAnswers.answers = {};
playerAnswers.answers[this.questionId] = this.answers;
const playerAnswersJSON = JSON.stringify(playerAnswers, null, 2);
fs.writeFile('playerAnswers.json', playerAnswersJSON, 'utf8', (err, data) => {
if (err) {
console.log('Error saving playerAnswers: ', err);
} else {
// console.log(`Saved results for question ${TEST_QUESTION_ID.toString()}`);
}
this.answers = [];
});
}
});
}
}