DEV Community

Cover image for Vaccinater | vaccine notification
Mayukh Pankaj
Mayukh Pankaj

Posted on

3 2

Vaccinater | vaccine notification

To beat covid-19, Vaccination is going all around the world. In India vaccination is being carried at a great pace with coWIN.gov.in .But unfortunately, getting a slot for your jab is tough, as they quickly fill out.
So I thought of a hack that can notify users whenever vaccine slots is available in their location.

Image description

$ git init

While searching api for covid data for my covid dashboard, I came across api.setu.gov.in, API endpoints for CoWin app. I started looking into these api response.
Image description
As you can see it returns an array with centers data like like available dose, vaccine name , address etc. API takes two parameters, district id & current date.

url = 'https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/calendarByDistrict?district_id='+str(district)+'&date='+today
response = requests.get(url).json()
Enter fullscreen mode Exit fullscreen mode

requesting url with python Requests library and then .json() converts JSON response to python dictionary, Now we can easily access response data.
Now with data at our hands, we want to request this API for each users, so we need to get each users data, so let’s build a form. Since I’m using python so I will be using Flask and instead of using WTForms I have used POST method to save user responses.
after getting user details, we also need to add it to a database. since all user’s data are unrelated so I’m simply using NoSQL, like MongoDB with pymongo.

@app.route("/register", methods=["POST","GET"])
def home():
if request.method == "POST":
name = request.form["name"]
district = request.form["district"]
mail = request.form["email"]
user_data = { "name": name , "d": district , "email": mail }
check_user = collection.count_documents({"email": mail})
print(check_user)
if(check_user):
print("user already registered")
return render_template("register.html",message="You are already Registered :)")
else:
collection.insert_one(user_data)
return render_template("success.html",message="Congrats You are Registered !")
else:
return render_template("register.html")
view raw flask-POST-form hosted with ❤ by GitHub

*Notification.py *

Now with data stored in our DB, we want to iterate it over and make request to CoWin API for each user, make a message out of it & send it to users email.
sorting the whole database & using previous response can save us a lot of time. Like if 100 users are from Delhi, Instead of calling the API 100 times for Delhi, We can use the first response for rest 99 users.
Sort Query on MongoDB

sorted_doc = collection.find().sort('district',pymongo.ASCENDING)
users = list(sorted_doc)

Remember collection.find() gives a cursor object which is not exactly a list, so we can use list() to get a list & can iterate it easily.

Sending pretty HTML emails

we can setup a basic SMTP client to send emails & use MIMEText to send html in email. HTML ? yes, now we can design our email just like any webpage.

import smtplib, ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
sender_email = "abc@gmail.com"
receiver_email = "xyz@gmail.com"
password = "abc123"
# Create secure connection with server and send email
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
server.login(sender_email, password)
message = MIMEMultipart("alternative")
message["Subject"] = "multipart test"
message["From"] = sender_email
message["To"] = receiver_email
# Create the plain-text and HTML version of your message
text = "Hello world"
html = """\
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1> Hello world</h1>
</body>
</html>
"""
# Turn these into plain/html MIMEText objects
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
# Add HTML/plain-text parts to MIMEMultipart message
# The email client will try to render the last part first
message.attach(part1)
message.attach(part2)
server.sendmail(sender_email, receiver_email, message.as_string())
view raw HTML-email-py hosted with ❤ by GitHub

Scheduling

since we want to carry out this operation & send email everyday at specific time so we need schedule this job. we can use scheduler or APScheduler in python, but it requires the cloud instances to be running, So I have used GCP cloud function to schedule this job.

import schedule
import time
def notify():
 #todo
schedule.every().day.at("09:00").do(notify)
while True:
 schedule.run_pending()
 time.sleep(1)
Enter fullscreen mode Exit fullscreen mode

**
Thank you for reading !**

Top comments (0)

nextjs tutorial video

📺 Youtube Tutorial Series

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay