├── .gitignore ├── now.json ├── package.json ├── get-subscriptions.js ├── index.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "alias": "monthly-salt.now.sh", 4 | "builds": [{ 5 | "src": "index.js", 6 | "use": "@now/node", 7 | "config": { 8 | "maxLambdaSize": "40mb" 9 | } 10 | }], 11 | "routes": [{ 12 | "src": "/(.*)", 13 | "dest": "/index.js" 14 | }] 15 | } 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "monthly-salt", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "chrome-aws-lambda": "^1.12.0", 13 | "lodash": "^4.17.11", 14 | "puppeteer-core": "^1.12.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /get-subscriptions.js: -------------------------------------------------------------------------------- 1 | const chrome = require('chrome-aws-lambda'); 2 | const puppeteer = require('puppeteer-core'); 3 | 4 | async function getSaltSubs(team) { 5 | const browser = await puppeteer.launch({ 6 | args: chrome.args, 7 | executablePath: await chrome.executablePath, 8 | headless: chrome.headless, 9 | }); 10 | 11 | const page = await browser.newPage(); 12 | await page.goto(`https://salt.bountysource.com/teams/${ team }/supporters`); 13 | 14 | await page.waitFor(2000); 15 | 16 | const data = await page.evaluate(() => { 17 | const trs = Array.from(document.querySelectorAll('table tr')) 18 | console.log('got all trs?', trs); 19 | return trs 20 | // remove header 21 | .slice(1) 22 | .map((tr) => ({ 23 | username: tr.querySelector('td:nth-of-type(2)').innerHTML, 24 | thisMonth: tr.querySelector('td:nth-of-type(3)').innerHTML, 25 | thisMonthNum: +tr.querySelector('td:nth-of-type(3)').innerHTML.slice(1), 26 | allTime: tr.querySelector('td:nth-of-type(4)').innerHTML, 27 | allTimeNum: +tr.querySelector('td:nth-of-type(4)').innerHTML.slice(1) 28 | })); 29 | }); 30 | 31 | await browser.close(); 32 | return data; 33 | } 34 | 35 | module.exports = { getSaltSubs }; 36 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash'); 2 | const subscriptions = require('./get-subscriptions'); 3 | 4 | module.exports = async function (req, res) { 5 | try { 6 | 7 | const url = _.trimEnd(req.url, '/'); 8 | const teamName = url.replace(/^.*\//, ''); 9 | 10 | if (!teamName) { throw new Error('no team name!'); } 11 | 12 | const data = await subscriptions.getSaltSubs(teamName); 13 | 14 | console.log('GOT THE FOLLOWING DATA: ', data); 15 | 16 | const monthlySum = data.reduce(function (accumulator, currentValue) { 17 | return accumulator + currentValue.thisMonthNum; 18 | }, 0); 19 | 20 | res.statusCode = 200; 21 | 22 | // set cache for 1 hour 23 | res.setHeader("Cache-Control", "public, max-age=2700"); 24 | res.setHeader("Expires", new Date(Date.now() + 2700).toUTCString()); 25 | 26 | res.setHeader('Content-Type', `application/json`); 27 | res.end(JSON.stringify({ 28 | schemaVersion: 1, 29 | label: 'monthly salt', 30 | message: `$ ${ monthlySum }`, 31 | color: "#33ccff", 32 | style: 'for-the-badge' 33 | })); 34 | 35 | } catch (e) { 36 | res.statusCode = 200; 37 | res.setHeader('Content-Type', `application/json`); 38 | res.end(JSON.stringify({ 39 | schemaVersion: 1, 40 | isError: true, 41 | label: 'monthly salt', 42 | message: `unknown`, 43 | color: "#33ccff", 44 | style: 'for-the-badge' 45 | })); 46 | console.error('Server Error!', e); 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
14 | get the total subscriptions per month in a shields.io compatible JSON 15 |
16 |