-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 73ebe3b
Showing
9 changed files
with
2,604 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/node_modules/ | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
_In order to deploy this you'll need to use a system supporting puppeteer. Most platforms can do this with a couple of commands. For Heroku or Dokku just use this https://github.com/jontewks/puppeteer-heroku-buildpack_ | ||
|
||
# Prereqs | ||
|
||
- Have Chrome installed | ||
- Make a Discord bot | ||
- Go to https://discordapp.com/developers | ||
- Make a new app and give it a unique name | ||
- Note down your CLIENT_ID | ||
- Go to the bot tab and click "Add Bot" | ||
- Note down your token | ||
- Add the bot to a Discord server (https://discordapp.com/oauth2/authorize?&client_id=ENTER_YOUR_BOT_CLIENT_ID_HERE&scope=bot&permissions=51200) | ||
|
||
# Running | ||
|
||
- Add your bot token to index.js | ||
- yarn | ||
- node index.js | ||
- The bot should now appear as online on your Discord server | ||
- Message the bot "testme" | ||
- The fetching process should start! | ||
|
||
# Making the bot actually do stuff | ||
|
||
- In production you proably want to separate the actual card fetching and the Discord bot. Maybe even render cards every time they're saved. This can be a little complicated to setup as you'll need a job queue and a setup to handle card image requests while their corresponding jobs are queued | ||
- Fetching a card | ||
- Currently the bot goes to youtube.com and uses a query selector, then takes a picture of that element | ||
- To populate a card the best way to do this is to expose a route on the frontend that is just a card (with an id on the div) and have the bot go there | ||
- If you don't want all of your cards to be public facing you could expose expose this as a service and send a payload to it, which is used as an escaped querystring to render the card (i.e. `mintr.io/card-preview?payload=${URLEncodedPayload}`). Here is a nice SO post on this https://stackoverflow.com/questions/3308846/serialize-object-to-query-string-in-javascript-jquery | ||
- Memoization | ||
- You probably want to upload these files to S3. For the Discord ".attachFile" method you can simply pass a URL string and that will be attached | ||
- The best way to use this service "on demand" without having to rerender the same card multiple times is to simply name the file based on the record \_id and updatedAt timestamp. If this exists in your S3 bucket then send that over as an attachment instanly | ||
- Linking cards to Discord accounts | ||
- In the Discord bot management set up an OAuth integration | ||
- Use something like Passport in your API to make a super simple route that links your internal users to Discord IDs | ||
- `message.author.id of a message will include the users' Discord IDs, which you simply match to their Mintr account |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,344 @@ | ||
const puppeteer = require('puppeteer') | ||
const Discord = require('discord.js') | ||
const client = new Discord.Client() | ||
const fs = require('fs'); | ||
|
||
const grabPage3 = async () => { | ||
const browser = await puppeteer.launch() | ||
const page = await browser.newPage() | ||
await page.goto(website) | ||
const el = await page.$('.ThumbnailLayouts__ThumbnailGrid-sc-18xwycr-0') | ||
const buffer = await el.screenshot({ path: "./screenshot.png" }) | ||
|
||
await browser.close() | ||
return buffer | ||
} | ||
const grabPage1 = async () => { | ||
const browser = await puppeteer.launch() | ||
const page = await browser.newPage() | ||
await page.goto(website1) | ||
const buffer = await page.screenshot({ path: "./screenshot.png" }) | ||
|
||
await browser.close() | ||
return buffer | ||
} | ||
const grabPage2 = async () => { | ||
const browser = await puppeteer.launch() | ||
const page = await browser.newPage() | ||
await page.goto(website) | ||
const buffer = await page.screenshot({ path: "./screenshot.png" }) | ||
|
||
await browser.close() | ||
return buffer | ||
} | ||
client.on('ready', () => { | ||
console.log('I am ready!') | ||
}) | ||
//Help Command | ||
client.on('message', async message => { | ||
if (message.content.includes('!help')) { | ||
const embed = new Discord.RichEmbed() | ||
// Set the title of the field | ||
.setTitle('Help And Commands') | ||
// Set the color of the embed | ||
.setColor(0xff0000) | ||
// Set the main content of the embed | ||
.setDescription(help) | ||
//console.log('message sent') | ||
// Send the embed to the same channel as the message | ||
message.channel.send(embed) | ||
} | ||
}) | ||
//Call Abbreviation | ||
client.on('message', async message => { | ||
if (message.content.includes('!u')) { | ||
var messagec = message.content; | ||
var message1 = messagec.replace("!u ",""); | ||
var sender = message.author.username + '#'+ message.author.discriminator; | ||
const fs = require('fs') | ||
fs.readFile('./shortcuts.json', 'utf8', function (err,data1) { | ||
if (err) { | ||
return console.log(err); | ||
} | ||
try { | ||
var data1 = data1 + "}" | ||
const data2 = JSON.parse(data1) | ||
//console.log(message2) | ||
var sendercheck = data2[sender]; | ||
website = data2[sender][message1] | ||
//console.log(website) | ||
async function myfunction() { | ||
const grabPage2 = async () => { | ||
const browser = await puppeteer.launch() | ||
const page = await browser.newPage() | ||
await page.goto(website) | ||
const buffer = await page.screenshot({ path: "./screenshot.png", }) | ||
|
||
await browser.close() | ||
return buffer | ||
} | ||
}; | ||
|
||
(async() => { | ||
const buffer = await grabPage2(website); | ||
|
||
// We can create embeds using the MessageEmbed constructor | ||
// Read more about all that you can do with the constructor | ||
// over at https://discord.js.org/#/docs/main/stable/class/RichEmbed | ||
|
||
const embed = new Discord.RichEmbed() | ||
// Set the title of the field | ||
.setTitle('Here Is Your NBA Top Shot Stats For ' + message1 + '!') | ||
// Set the color of the embed | ||
.setColor(0xff0000) | ||
// Set the main content of the embed | ||
.setDescription('Brought To You By The NBA Top Shot Pros') | ||
.attachFile(buffer) | ||
//console.log('message sent') | ||
// Send the embed to the same channel as the message | ||
message.channel.send(embed) | ||
fs.unlink("./screenshot.png",(err => { | ||
if (err) console.log(err)})); | ||
})(); | ||
} | ||
|
||
catch (err) { | ||
console.log(err) | ||
} | ||
}) | ||
} | ||
}) | ||
//ADD Abbreviation | ||
client.on('message', async message => { | ||
if (message.content.includes('!add')&& message.content.includes(',')) { | ||
var messagec = message.content; | ||
//!add BB, JAMES HARDEN Layup Base Set (Series 2) | ||
// 1. write abbreviation to file under sender name | ||
//2. fetch the link from file | ||
//3. save abbreviation and link to new file | ||
|
||
var message1 = messagec.replace("!add ",""); | ||
var messagev = message1.split(",") | ||
var sender = message.author.username + '#'+ message.author.discriminator; | ||
var abbrev = messagev[0] | ||
var alink = messagev[1] | ||
var slink1= alink.replace(/\s+/g, ''); | ||
//console.log(mname,slink) | ||
const fs = require('fs') | ||
fs.readFile('./shortcuts.json', 'utf8', function (err,data1) { | ||
if (err) { | ||
return console.log(err); | ||
} | ||
try { | ||
var data1 = data1 + "}" | ||
const data2 = JSON.parse(data1) | ||
//console.log(message2) | ||
var sendercheck = data2[sender]; | ||
//console.log(data2) | ||
data2[sender][abbrev] = alink | ||
var data3 = JSON.stringify(data2) | ||
var data3 = data3.replace(/\}([^}]*)$/,'') | ||
fs.writeFile("./shortcuts.json", data3, (err) => { | ||
if (err) | ||
console.log(err);}) | ||
|
||
// We can create embeds using the MessageEmbed constructor | ||
// Read more about all that you can do with the constructor | ||
// over at https://discord.js.org/#/docs/main/stable/class/RichEmbed | ||
const embed = new Discord.RichEmbed() | ||
// Set the title of the field | ||
.setTitle("Abbreviation Has Been Stored, You Can Now Use It") | ||
// Set the color of the embed | ||
.setColor(0xff0000) | ||
// Set the main content of the embed | ||
.setDescription('Brought To You By The NBA Top Shot Pros') | ||
// Send the embed to the same channel as the message | ||
message.channel.send(embed); | ||
fs.unlink("./screenshot.png",(err => { | ||
if (err) console.log(err)})); | ||
} | ||
catch(err) { | ||
console.log(err) | ||
const fs = require('fs'); | ||
|
||
let moment =` | ||
"${sender}": { | ||
"${abbrev}": "${alink}" | ||
}`; | ||
const data5 = ","+"\n" +(moment); | ||
//console.log(data1) | ||
fs.appendFile('./shortcuts.json', data5, (err) => { | ||
if (err) { | ||
console.log(err); | ||
} | ||
|
||
// We can create embeds using the MessageEmbed constructor | ||
// Read more about all that you can do with the constructor | ||
// over at https://discord.js.org/#/docs/main/stable/class/RichEmbed | ||
const embed = new Discord.RichEmbed() | ||
// Set the title of the field | ||
.setTitle("Abbreviation Has Been Stored, It Can Now Be Used!") | ||
// Set the color of the embed | ||
.setColor(0xff0000) | ||
// Set the main content of the embed | ||
.setDescription('Brought To You By The NBA Top Shot Pros') | ||
// Send the embed to the same channel as the message | ||
message.channel.send(embed); | ||
fs.unlink("./screenshot.png",(err => { | ||
if (err) console.log(err)})); | ||
}); | ||
//console.log('hello1') | ||
} | ||
}) | ||
} | ||
}) | ||
//Store Moments for !m | ||
client.on('message', async message => { | ||
if (message.content.includes('!s')&& message.content.includes(',')) { | ||
var messagec = message.content; | ||
var message1 = messagec.replace("!s ",""); | ||
var messagev = message1.split(",") | ||
var mname = messagev[0] | ||
var slink = messagev[1] | ||
var slink1= slink.replace(/\s+/g, ''); | ||
//console.log(mname,slink) | ||
|
||
|
||
const fs = require('fs'); | ||
|
||
let moment =` | ||
"${mname}": { | ||
"website": "${slink}" | ||
}`; | ||
const data1 = ","+"\n" +(moment); | ||
//console.log(data1) | ||
fs.appendFile('./moments.json', data1, (err) => { | ||
if (err) { | ||
console.log(err); | ||
} | ||
|
||
// We can create embeds using the MessageEmbed constructor | ||
// Read more about all that you can do with the constructor | ||
// over at https://discord.js.org/#/docs/main/stable/class/RichEmbed | ||
console.log('hello') | ||
const embed = new Discord.RichEmbed() | ||
// Set the title of the field | ||
.setTitle("Moment Has Been Stored, It Can Now Be Recalled Using The !m Function!") | ||
// Set the color of the embed | ||
.setColor(0xff0000) | ||
// Set the main content of the embed | ||
.setDescription('Brought To You By The NBA Top Shot Pros') | ||
// Send the embed to the same channel as the message | ||
message.channel.send(embed); | ||
fs.unlink("./screenshot.png",(err => { | ||
if (err) console.log(err)})); | ||
}); | ||
//console.log('hello1') | ||
} | ||
}) | ||
//GET Player Cards | ||
client.on('message', async message => { | ||
if (message.content.includes('!p')) { | ||
var messagec = message.content; | ||
var message1 = messagec.replace("!p ",""); | ||
var message2 = message1.replace(/\s+/g, '-'); | ||
var data = require("./playerlist.json") | ||
var website1 = data[`${message2}`].link; | ||
website = website1.replace(/\s+/g, '-'); | ||
async function myfunction() { | ||
const grabPage3 = async () => { | ||
const browser = await puppeteer.launch() | ||
const page = await browser.newPage() | ||
await page.goto(website) | ||
const buffer = await page.screenshot({ path: "./screenshot.png", }) | ||
|
||
await browser.close() | ||
return buffer | ||
} | ||
}; | ||
|
||
(async() => { | ||
const buffer = await grabPage3(website); | ||
|
||
// We can create embeds using the MessageEmbed constructor | ||
// Read more about all that you can do with the constructor | ||
// over at https://discord.js.org/#/docs/main/stable/class/RichEmbed | ||
|
||
const embed = new Discord.RichEmbed() | ||
// Set the title of the field | ||
.setTitle('Here Is Your NBA Top Shot Stats For ' + message1 + '!') | ||
// Set the color of the embed | ||
.setColor(0xff0000) | ||
// Set the main content of the embed | ||
.setDescription('Brought To You By The NBA Top Shot Pros') | ||
.attachFile(buffer) | ||
//console.log('message sent') | ||
// Send the embed to the same channel as the message | ||
message.channel.send(embed) | ||
fs.unlink("./screenshot.png",(err => { | ||
if (err) console.log()})); | ||
})(); | ||
} | ||
}) | ||
//GET SPECIFIC MOMENT | ||
client.on('message', async message => { | ||
if (message.content.includes('!m')) { | ||
var messagec = message.content; | ||
var message1 = messagec.replace("!m ",""); | ||
const fs = require('fs') | ||
fs.readFile('./moments.json', 'utf8', function (err,data1) { | ||
if (err) { | ||
return console.log(err); | ||
} | ||
//console.log(data1); | ||
var data = data1 +"}" | ||
const message2 = JSON.parse(data) | ||
//console.log(message2) | ||
website1 = message2[message1].website; | ||
console.log(website1) | ||
async function myfunction() { | ||
const grabPage1 = async () => { | ||
const browser = await puppeteer.launch() | ||
const page = await browser.newPage() | ||
await page.goto(website1) | ||
const buffer = await page.screenshot({ path: "./screenshot.png" }) | ||
|
||
await browser.close() | ||
return buffer | ||
} | ||
}; | ||
|
||
// Here we wait for the myfunction to finish | ||
// and then returns a promise that'll be waited for aswell | ||
// It's useless to wait the myfunction to finish before to return | ||
// we can simply returns a promise that will be resolved later | ||
|
||
// Call start | ||
(async() => { | ||
const buffer = await grabPage1(website1); | ||
|
||
// We can create embeds using the MessageEmbed constructor | ||
// Read more about all that you can do with the constructor | ||
// over at https://discord.js.org/#/docs/main/stable/class/RichEmbed | ||
|
||
const embed = new Discord.RichEmbed() | ||
// Set the title of the field | ||
.setTitle('Here Is Your NBA Top Shot Stats For ' + message1 + '!') | ||
// Set the color of the embed | ||
.setColor(0xff0000) | ||
// Set the main content of the embed | ||
.setDescription('Brought To You By The NBA Top Shot Pros') | ||
.attachFile(buffer) | ||
//console.log('message sent') | ||
// Send the embed to the same channel as the message | ||
message.channel.send(embed) | ||
fs.unlink("./screenshot.png",(err => { | ||
if (err) console.log(err)})); | ||
})(); | ||
}) | ||
} | ||
}); | ||
|
||
|
||
|
||
client.login('ODE3NTI5NzkxNzcwMDAxNDU4.YEK18w._oWxDlYeZHFN582JVl8x_ru5RyI') |
Oops, something went wrong.