Last active
April 6, 2023 14:07
-
-
Save trungdq88/6c9de42a87a24446a630cec59ece845e to your computer and use it in GitHub Desktop.
A scriptable's script to get Paddle revenue from multiple accounts using puppeteer.
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
/* | |
RUN THE SCRIPT BY YOURSELF: | |
- Run `node paddle-revenue.js` on your server and let it run 24/7. | |
- Access the API at http://your_server_ip:8175/ (JSON) | |
HOSTED VERSION: | |
If you don't want to run the script by your own, you can use the | |
hosted version. The price is $5 per month per Paddle account. | |
Here is how: | |
1. Go to Paddle dashboard → Business Account → Team Members. | |
2. Invite "paddle-bot-{your_vendor_id}@tdinh.me" to your Paddle | |
team. Replace the {your_vendor_id} with your paddle vendor ID, | |
for example, if your vendor ID is 811502, use the email | |
[email protected] for the invitation. Make sure to set | |
the permission as "Finance" so that the account only have access | |
to reports and revenue. | |
3. Ping me via Twitter @tdinh_me to make payment, then I will | |
set up the bot for you. | |
4. After the bot has been set up, you can access the JSON data | |
by sending a request to https://tdinh.me/paddle-bot/{your_vendor_id} | |
License for this code: MIT | |
*/ | |
const puppeteer = require('puppeteer'); | |
const fs = require('fs'); | |
async function getRevenue({ username, password }) { | |
const browser = await puppeteer.launch({ | |
headless: true, | |
}); | |
console.log(new Date(), username, 'Browser launched'); | |
const page = await browser.newPage(); | |
try { | |
await page.goto('https://vendors.paddle.com/'); | |
console.log(new Date(), username, 'Page loaded'); | |
// wait for page to finish loading | |
await page.waitForSelector('[type=email]', { visible: true }); | |
// Enter username | |
await page.type('[type=email]', username); | |
// Enter password | |
await page.type('[type=password]', password); | |
// Click login | |
await page.click('[type=submit]'); | |
console.log(new Date(), username, 'Logged in'); | |
// Wait for the element with class big-num to show up and have content | |
await page.waitForSelector('.financial-stats', { visible: true }); | |
// get the element with the big-num class | |
const element = await page.$('.financial-stats'); | |
console.log(new Date(), username, 'Got element'); | |
// get element's text | |
let value = (await page.evaluate((el) => el.textContent, element)) | |
.trim() | |
.replace('BalanceUS', ''); | |
console.log(new Date(), username, 'Got text', value); | |
await browser.close(); | |
return value; | |
} catch (e) { | |
console.error(new Date(), 'failed', e); | |
// take screenshot | |
await page.screenshot({ path: 'error.png' }); | |
} | |
} | |
async function start() { | |
const devutils = await getRevenue({ | |
username: 'account1', | |
password: 'password1', | |
}); | |
const xnapper = await getRevenue({ | |
username: 'account2', | |
password: 'password2', | |
}); | |
const blackmagic = await getRevenue({ | |
username: 'acccount3', | |
password: 'password3', | |
}); | |
const data = { devutils, xnapper, blackmagic, updated: new Date() }; | |
console.log(new Date(), 'result', data); | |
// write to file | |
fs.writeFileSync('data.json', JSON.stringify(data)); | |
} | |
// http server to serve the data.json file | |
const PORT = 8175; | |
const http = require('http'); | |
const server = http.createServer((req, res) => { | |
res.writeHead(200, { 'Content-Type': 'application/json' }); | |
try { | |
res.end(fs.readFileSync('data.json')); | |
} catch (e) { | |
console.error(e); | |
res.end(JSON.stringify({ error: 'uh oh' })); | |
} | |
}); | |
server.listen(PORT); | |
// run the script every 5 minutes | |
setInterval(start, 1000 * 60 * 5); | |
start(); |
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
// Use this script in the Scriptable app (https://scriptable.app/) | |
// data | |
let url = "http://your_host_ip:8175/" | |
let r = new Request(url) | |
let json = await r.loadJSON() | |
let minutesAgo = Math.round((Date.now() - new Date(json.updated).getTime()) / 1000 / 60) | |
// UI | |
const w = new ListWidget() | |
const now = new Date() | |
getwidget("DevUtils", 13, "#888888") | |
getwidget(json.devutils, 18, "#63ca56") | |
w.addSpacer(6) | |
getwidget("Black Magic", 13, "#888888") | |
getwidget(json.blackmagic, 18, "") | |
w.addSpacer(6) | |
getwidget("Xnapper", 13, "#888888") | |
getwidget(json.xnapper, 18, "#964eea") | |
w.addSpacer(6) | |
getwidget("Updated: " + minutesAgo + "m ago", 10, "#888888") | |
Script.setWidget(w) | |
Script.complete() | |
w.presentMedium() | |
function getwidget(value, size, color) { | |
const titlew = w.addText(value) | |
if (color) { titlew.textColor = new Color(color) } | |
titlew.font = Font.boldSystemFont(size || 13) | |
} |
@trungdq88 ok I see! great idea 💯
my only concern would be that https://scriptable.app would insert a backdoor by giving them so much access to my phone
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@vasco3 you shouldn't use this with your main account. Invite a new team member without 2FA and with the Financial role.