Skip to content

Instantly share code, notes, and snippets.

@umanghome
Created April 29, 2021 09:29
Show Gist options
  • Save umanghome/1a15d584c49bbee4ba8b716030a148bc to your computer and use it in GitHub Desktop.
Save umanghome/1a15d584c49bbee4ba8b716030a148bc to your computer and use it in GitHub Desktop.
Do we have vaccination slots for 25 year olds yet?
/**
* run `npm init -y`
* run `npm i node-fetch`
* run `node index.js`
* turn Slack notifications on
*
* Get cowinUrl from the DevTools' network tab
* Get authorization string from the Request Headers as the value of authorization header of the network request for cowinUrl. If this expires, the script will stop working. You'll have to log in again and get a new value for this.
*/
const fetch = require('node-fetch');
const slackWebhookUrl = ''; // Your Slack webhook URL
const authorization = ''; // Bearer auth string
const cowinUrl = 'https://cdn-api.co-vin.in/api/v2/appointment/sessions/calendarByDistrict?district_id=265&date=29-04-2021'; // This is for Bangalore Urban on 29th April
function sleep(time) {
return new Promise((resolve) => {
setTimeout(resolve, time);
});
}
async function main() {
while (true) {
const d = new Date();
console.log('Checking at', d.toLocaleTimeString());
const changed = await check();
if (changed) {
break;
}
// sleep for 5 mins
await sleep(300000);
}
}
function sendToSlack(message) {
return fetch(slackWebhookUrl, {
body: JSON.stringify({
text: message,
}),
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
});
}
function uniq(arr) {
const s = new Set(arr);
return Array.from(s);
}
function getSlotsFor25(res) {
let centers = [];
if (!('centers' in res)) {
return centers;
}
centers = res.centers.filter((centre) => {
return centre.sessions.some((session) => session.min_age_limit <= 25);
});
return centers.map((c) => {
return {
name: c.name,
pin: c.pincode,
vaccines:
uniq(c.sessions.map((s) => s.vaccine).filter(Boolean)).join(' ') ||
'Not specified',
};
});
}
function check() {
return fetch(cowinUrl, {
headers: {
accept: 'application/json, text/plain, */*',
'accept-language': 'en-US,en;q=0.9',
authorization,
'cache-control': 'no-cache',
pragma: 'no-cache',
'sec-ch-ua':
'" Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"',
'sec-ch-ua-mobile': '?0',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'cross-site',
},
referrer: 'https://selfregistration.cowin.gov.in/',
referrerPolicy: 'strict-origin-when-cross-origin',
body: null,
method: 'GET',
mode: 'cors',
credentials: 'include',
})
.then((res) => res.json())
.then((response) => {
const slotsFor25 = getSlotsFor25(response);
if (slotsFor25.length) {
const msg = slotsFor25
.map((s) => `[${s.pin}] ${s.name}. Vaccines: ${s.vaccines}`)
.join('\n');
sendToSlack(`Found slots!\n${msg}`);
return true;
} else {
return false;
}
})
.catch((error) => {
console.error(error);
sendToSlack('Script errored!', error);
return true;
});
}
main();
@yashshah1
Copy link

Changing the URL to https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/calendarByDistrict?district_id=${id}&date=${date} removes the need for a bearer token! This probably reduces the number of times someone would have to log in just to get that token

@umanghome
Copy link
Author

@yashshah1 Neat. Thanks!

@umanghome
Copy link
Author

@yashshah1 That URL has stale data every time.

@yashshah1
Copy link

@umanghome Somehow I haven't come across this issue. Let me recheck

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment