-
Notifications
You must be signed in to change notification settings - Fork 8
/
index.js
169 lines (152 loc) · 5.15 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
const axios = require("axios");
const dotenv = require("dotenv");
const nodemailer = require("nodemailer");
const express = require("express");
const moment = require("moment");
const cors = require("cors");
const app = express();
app.use(cors());
dotenv.config();
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.GMAIL_EMAIL,
pass: process.env.GMAIL_PASS,
},
});
// Sends mail to specified email address
const sendEmail = (text, send_to) => {
transporter.sendMail(
{
from: process.env.GMAIL_EMAIL,
to: send_to,
subject: "Cowin available",
text,
},
(err, info) => {
if (err) {
console.log(err);
} else {
console.log(info);
}
}
);
};
let listeners = {}; // Stores all active listeners and their associated email addresses
// vaccination date is the next day in 'DD-MM-YYYY' format
const vaccinationDate = moment().add(1, "d").format("DD-MM-YYYY");
const getData = async () => {
try {
Object.entries(listeners).map(async (listener) => {
// Iterate over all active listeners and get availability for each requested pincode
req_pincode = listener[0];
const curUrl = `https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/findByPin?pincode=${req_pincode}&date=${vaccinationDate}`;
const result = await axios.get(curUrl);
const { sessions } = result.data;
//Data is filtered with limitations on the minimum age limit and available capacity
let availableSlots = sessions.filter(
(obj) => obj.min_age_limit < 45 && obj.available_capacity > 0
);
if (availableSlots.length > 0) {
// showing the table in terminal
const actualDataToDisplay = availableSlots.map((slot) => {
const {
session_id,
slots,
lat,
long,
allow_all_age,
state_name,
district_name,
block_name,
pincode,
min_age_limit,
center_id,
from,
to,
date,
...necessaryData
} = slot; // a neat trick to exclude keys from an object
return necessaryData;
});
console.table(actualDataToDisplay);
// Sending emails to notify people
listener[1].emails.forEach((req_email) => {
// Iterate over all email addresses associated with pincode
sendEmail(JSON.stringify(availableSlots, null, 2), req_email); // Send email
});
// Stopping listenning for the updates
clearInterval(listener[1].interval);
delete listeners[listener[0]];
} else {
const date = new Date();
console.log(
date.toTimeString(),
"no available slots available for",
vaccinationDate
);
}
});
} catch (error) {
console.error(error);
}
};
//created a server using express
app.get("/", (req, res) => {
// new requirement will be added soon
res.end(); //end the response
});
// Created an endpoint to take in pincode and email and assign listener
// http://localhost:PORT/subscribe?pincode=PINCODE&email=EMAIL
app.get("/subscribe", (req, res) => {
let req_pincode = req.query.pincode; // Getting pincode and email from url query
let req_email = req.query.email;
if (req_pincode in listeners) {
// Checking if listener already exists
if (!listeners[req_pincode].emails.includes(req_email)) {
listeners[req_pincode].emails = [
...listeners[req_pincode].emails,
req_email,
]; // Adding email to listener if exists and does not contain email
}
} else {
listeners[req_pincode] = {
// Creating a new listener and adding email to it
emails: [req_email],
interval: setInterval(() => {
getData();
}, 10000),
};
}
res.end(); // Ending the response
});
// Created an endpoint to take in email and remove listener
// http://localhost:PORT/unsubscribe?email=EMAIL
app.get("/unsubscribe", (req, res) => {
let req_email = req.query.email; // Getting email from url query
Object.entries(listeners).map((listener) => {
// Mapping over the active listeners
if (listener[1].emails.includes(req_email)) {
listener[1].emails.splice(listener[1].emails.indexOf(req_email), 1); // Removing the email if it exists in current listener
}
if (listener[1].emails.length === 0) {
delete listeners[listener[0]]; // Removing the listener if no emails associated with it
}
});
res.end(); // Ending the response
});
// Created an endpoint to show all active listeners
// http://localhost:PORT/all
app.get("/all", (req, res) => {
let all_listeners = {};
Object.entries(listeners).map((listener) => {
all_listeners[listener[0]] = listener[1].emails; // Selecting only pincode and emails to return, excluding interval
});
res.write(JSON.stringify(all_listeners, null, 2)); // Returning all active listeners and associated emails
res.end(); // Ending the response
});
const port = process.env.PORT || 8000;
//Binds and listens the connections on the specified port
app.listen(port, () => {
console.log(`App is running on port ${port}`);
});