Skip to content

Instantly share code, notes, and snippets.

@amalmurali47
Last active May 11, 2021 06:53
Show Gist options
  • Save amalmurali47/050ef9250c5e1cd611f2e54012d1ece3 to your computer and use it in GitHub Desktop.
Save amalmurali47/050ef9250c5e1cd611f2e54012d1ece3 to your computer and use it in GitHub Desktop.

Downloading the script

Execute the command in a terminal window:

wget "https://gist.github.com/amalmurali47/050ef9250c5e1cd611f2e54012d1ece3/raw/29126c4e7e2ae79f8c61cd057e8b30c1345367ec/vaccine_checker.py"

It will save the script as vaccine_checker.py.

Requirements

You need the following installed:

  • Python
  • Requests module (install using python -m pip install requests)
  • [OPTIONAL] Text to speech engine -- This is only required if you wish to have a speech alert when the slots are available.
    • If you're using Mac, "say" command is installed by default.
    • If you're running Linux, install espeak-ng package.
    • Windows is currently unsupported.
  • If you wish to use any of the other notification methods such as Telegram, Slack etc., refer to the setup instructions below.

Notifications

Currently, the script supports the following notification channels:

  1. Telegram
  2. SimplePush (Android-only app)
  3. Slack
  4. Voice alerts using system's text-to-speech

Setup instructions for Telegram (Android and iOS)

  1. Install Telegram.
  2. Open a conversation with @botfather username. Send the command /newbot. Complete the process and create a bot.
  3. Copy the bot token and specify that on line 12.

Setup instructions for SimplePush (Android)

  1. Install SimplePush app from Play Store: https://play.google.com/store/apps/details?id=io.simplepush
  2. Select free version and click on Next.
  3. Your key will be displayed on the screen. Copy the key and specify that on line 11.

Usage instructions

  1. Vaccine slots usually get published by around 4 PM IST. Run the script around 3.45 PM using python3 vaccine_checker.py.
  2. Wait for it to alert you about open slots at any centers. Typically, this can be at any time from 4:00 PM to 4:15 PM.
  3. When you get an alert about an open slot at any centers, login to COWIN portal at https://www.cowin.gov.in/ using your mobile number and OTP, and book the slots in the centre that is most convenient for you.
import json
import os
from datetime import datetime
from pprint import pprint
from sys import platform
from time import sleep
import requests
# Edit below this
simplepush_token = ''
telegram_bot_token = ''
slack_webhook = ''
# Edit above this
time_to_wait = 5
state_id = 17 # 17 = Kerala (Get it from: https://cdn-api.co-vin.in/api/v2/admin/location/states)
district_id = None
headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'}
cowin_api_base_url = 'https://cdn-api.co-vin.in/api/v2'
def get_districts():
find_districts_url = f'{cowin_api_base_url}/admin/location/districts/{state_id}'
try:
r = requests.get(find_districts_url, headers=headers)
except Exception:
raise SystemExit('Could not get the district details from COWIN API. Try again.')
else:
return r.json()['districts']
def get_district():
districts = get_districts()
for district_serial, district in enumerate(districts, 1):
print(f"{district_serial}. {district['district_name']}")
district_selection = input('\nSelect your district number (example: 5): ')
district_number = int(district_selection)
if district_number not in range(1, 15):
raise SystemExit('Invalid district number chosen. Try again.')
district_details = districts[district_number-1]
print(f"\nChosen district name: {district_details['district_name']}\n")
return district_details['district_id']
def get_json(district_id):
date_str = datetime.today().strftime('%d-%m-%Y')
slot_info_url = f'{cowin_api_base_url}/appointment/sessions/calendarByDistrict?district_id={district_id}&date={date_str}'
try:
return requests.get(slot_info_url, timeout=5, headers=headers).json()
except Exception:
print('Could not get the details from COWIN API.')
def notify_simplepush(msg):
simplepush_url = f'https://api.simplepush.io/send/{simplepush_token}/'
msg = requests.utils.quote(msg)
try:
r = requests.get(f'{simplepush_url}COVID_ALERT/{msg}')
except Exception:
print('Failed to send notification to SimplePush.')
def notify_telegram(msg):
telegram_url = f'https://api.telegram.org/{telegram_bot_token}'
msg = requests.utils.quote(msg)
try:
r = requests.get(f'{telegram_url}/getUpdates').json()
chat_id = r['result'][1]['message']['chat']['id']
r = requests.get(
f'{telegram_url}/sendMessage?chat_id={chat_id}&text={msg}').json()
except Exception:
print('Failed to send notification to Telegram.')
def notify_slack(msg):
try:
r = requests.post(slack_webhook, json={'text': msg})
except Exception:
print('Failed to send notification to Slack.')
def say(m):
if platform == "linux" or platform == "linux2":
os.system(f'espeak-ng "{m}"')
elif platform == "darwin":
os.system(f'say "{m}"')
elif platform == "win32":
pass
if __name__ == "__main__":
while True:
if not district_id:
district_id = get_district()
data = get_json(district_id)
if not data:
sleep(5)
continue
current_time = datetime.today().strftime('%I:%M:%S %p')
for center in data['centers']:
slots = center['sessions'][0]['available_capacity']
vaccine = center['sessions'][0]['vaccine']
center_name = center['name']
if slots:
msg = f'{slots} slots for {vaccine} available in {center_name}'
print(msg)
if telegram_bot_token:
print('Sending Telegram notification')
notify_telegram(msg)
if simplepush_token:
print('Sending SimplePush notification')
notify_simplepush(msg)
if slack_webhook:
print('Sending Slack notification')
notify_slack(msg)
say(msg)
# If vaccine is not available anywhere
if not any([c['sessions'][0]['available_capacity'] for c in data['centers']]):
print(f'Vaccine not available yet. Last checked at: {current_time}')
for i in reversed(range(time_to_wait)):
print(f'Sleeping for {i}...', end='\r')
sleep(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment