-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
121 lines (107 loc) · 3.76 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import axios from 'axios';
import dotenv from 'dotenv';
import twilio from 'twilio';
import personalMobile from './personalMobile.js'; // An of mobile numbers to notify
dotenv.config();
const appendZero = (num) => {
const inString = String(num);
return inString.padStart(2, '0');
}
const today = () => `${appendZero(new Date().getDate())}-${appendZero(new Date().getMonth() + 1)}-${new Date().getFullYear()}`;
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = twilio(accountSid, authToken);
const sendAlert = (pincode) => (to) => client.messages
.create({
to,
from: process.env.TWILIO_SOURCE_MOBILE,
body: 'Appointment available at ' + pincode,
})
.then();
const options = (districtId) => ({
method: 'GET',
url: 'https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/calendarByDistrict',
params: {district_id: districtId, date: today()},
headers: {accept: 'application/json', 'Accept-Language': 'hi_IN'}
});
const getAvailabilityFromCentre = (age) => (center) => {
const { sessions } = center;
const availableSessions = sessions.filter(({ min_age_limit, available_capacity }) => (available_capacity && (min_age_limit === age)));
if (availableSessions.length > 0) {
// Sessions available
return {
sessionAvailable: true,
availableSessions,
centre: { id: center.center_id, name: center.name, pincode: center.pincode }
}
}
return {
sessionAvailable: false,
availableSessions,
centre: null
}
}
const sessionAvailableFilter = (({ sessionAvailable }) => sessionAvailable);
const filterAvailableSession = (input) => input.filter(sessionAvailableFilter);
const filterForAge = (age) => (appointmentData) => {
const { centers } = appointmentData;
const getAvailabilityFor18 = getAvailabilityFromCentre(age);
const availableAppointments = filterAvailableSession(centers.map(getAvailabilityFor18));
return availableAppointments;
};
const getAllAppointments = async (districtId) => {
try {
const response = await axios.request(options(districtId));
const availableAppointments = filterForAge(18)(response.data);
return {
sessionAvailable: (availableAppointments.length > 0),
data: availableAppointments
}
} catch (ex) {
console.error(ex);
return {
sessionAvailable: false,
data: []
}
}
};
const sendMessages = async (pincode) => {
const sendToPincode = sendAlert(pincode);
await Promise.all(personalMobile.map(sendToPincode));
}
const main = async () => {
const districtIds = ['505', '506']; // JAIPUR I and II
const appointmentAvailability = await Promise.all(districtIds.map(getAllAppointments)).then(filterAvailableSession);
const totalData = appointmentAvailability.reduce((totalAppointments, { data = [] } = {}) => {
return [...totalAppointments, ...data];
}, []);
const formattedData = totalData.reduce(((tillNow, thisSession) => ({
...tillNow,
[thisSession.centre.id]: {
availableSessions: thisSession.availableSessions,
...thisSession.centre
}
})), {})
let foundSlots = false;
let messagePromise = new Promise((resolve) => resolve(1));
Object.values(formattedData).forEach(({ pincode, availableSessions }) => {
if (!foundSlots) {
foundSlots = true;
messagePromise = sendMessages(pincode);
}
console.log(pincode, ': ', availableSessions);
});
await messagePromise;
return foundSlots;
}
while(true) {
const foundSlots = await main();
if (!foundSlots) {
console.log('No slots found, Timestamp: ', (new Date()).toLocaleTimeString(), ', ', (new Date()).toLocaleDateString())
} else {
console.log('Found Slots!!')
process.exit(0);
}
await new Promise((resolve) => setTimeout(resolve, 300000));
console.log('trying again')
}