CoWinVaccineSlotFinder

Cross-Platform Software to Fetch the Available Slots & Book the Appointment for COVID-19 Vaccination

View the Project on GitHub SRvSaha/CoWinVaccineSlotFinder

CoWIN Vaccine Slot Finder Logo

Cross-Platform Real-Time Co-WIN Vaccine Slot Finder - We Find Your Shot!

LatestReleaseWindows LatestReleaseMacOS LatestReleaseLinux Downloads TotalBookings BookingsToday Issues MIT License

Watch Demo to See How It Works, Check Out App Statistics & Download Latest Version of the Software for your Operating System by clicking the above links or by clicking here & kindly follow the steps mentioned in How To Use and read the FAQs

NOTE: Please make sure these changes are done in Config file appsettings.json before running the Software

WATCH DEMO - How To Get Your Slot Under 60 Seconds

Click Here To Play The Demo

STATISTICS & FOOTPRINTS - See the Analytics from metadata of Slot Finder

Total Bookings Analysis till Date

StatisticsTillToday

Total Bookings Analysis for Today

StatisticsTillToday

Download Statistics of Last 3 Versions

StatisticsDownloads

Summary of Total Bookings Analysis till Date

StatisticsTillToday

Summary Total Bookings Analysis for Today

StatisticsTillToday

Overall Bookings from Different Places till Date

StatisticsTillToday

Bookings Today vs Overall vs Yesterday

StatisticsTillToday

Total Bookings Based on Age and Platform

StatisticsTillToday

Total Bookings Trendline and App Version

StatisticsTillToday

DISCLAIMER

NOTE: Please go through the Disclaimer, End User Lisence Agreement & the Privacy Policy, proceed further only if you accept the Terms and Conditions to use the Application/Software

Important:

Glimpse of the Application:

Application With Bare Miminum Configuration Changes

Application_Default

Application Start - Software Update Notifier

Application_Default

Application Start - Disclaimer, End-User Lisence Agreement, T&C, Privacy Policy Agreement Consent

Application_Default

Application Start - OTP Generation

Application Start

Application Start - OTP Validated - BearerToken Generation

Application Start

Application Start - OTP Validated - Invalid BearerToken provided in Config; Regeneration Session by Resending OTP

Application Start

Application Start - Invalid OTP Entered. Re-Generating new OTP

Application Start

Application OTP Retrigger In Case OTP is not received within time. Press Enter to Retrigger OTP

Application Start

Successful Booking Scenario - With AI-Auto Captcha

Application Sample

Successful Booking Scenario - Showing Support & Sharing Word of Mouth

Application SuccessfulBooking

Unsuccessful Booking - All Slots Full

Application Sample

Unsuccessful Booking - Server Under Heavy Load

Application Sample

Application Session Regeneration on TimeOut

Application Sample

Application OTP Validity Expired (Expiry Time 3 Minutes from Generation) when user enter the OTP for validation

Application Sample

Application Features

Following are some of the main features of the App:

Technical Details

It’s a simple hybrid Console Application being developed using .NET Core 3.1, WinForms and C#.

Currently, application is bundled as a Single Standalone Executable file with Runtime included and therefore no installations are needed to run the Application. Application can be used in Windows/Linux/Mac without any external dependencies

In General, to run the application, the following things are needed:

.NET Core 3.1 Runtime is bundled in the Release so no other external dependencies to run the Application. FOR DEVELOPERS TO BUILD/MODIFY .NET Core 3.1 SDK is required to build from Source Code or to make some customizations. Use of Visual Studio 2019 is recommended for the purpose of development.

Currently, searching using the findByDistrict API and findByPin API are integrated to get all the available slots in a particular district/PINCode.

There is API throttling (Rate-Limiting) of 100 requests/5 minutes from 1 IP Address. Application heuristically switches automatically to circumvent the issue for finding slot.

How to Use:

For Folks who just want to get shit done

For Windows Users:

Application Release

How to run on macOS/Linux Systems :

Troubleshooting macOS Problems :

How to Open appsettings.json

In layman terms, it is just like any other text file which can be opened in any text editor like Notepad, Wordpad, VS Code, Sublime Text, Notepad++ etc. Modification can be done and file to be saved again with the same name and File Types as “All Files”

How to Get User Specific Information for appsettings.json

  1. Go to cowin.gov.in
  2. Generate OTP for your registered mobile number. You need to provide this mobile number in the appsettings.json file.
  3. Validate the OTP
  4. After you are logged in, you’ll see a dashboard like this, get the highlighted number REF ID, which is your beneficary ID and would be required in your appsettings.json. If you have multiple members added in your registered mobile number, you will get multiple REF IDs. Use the REF IDs for which you want to do booking

BeneficiaryID

  1. Also, Once all these details are fetched, put them in the appsettings.json.
  2. Run the Application CoWinVaccineSlotFinder.EXE, that’s it.

You may also see a file with the name authToken.json in your directory when you are running the Application. This is done so that your session information is stored locally in your device and you don’t need to enter OTP manually until 15 minutes, in case you close the Application and run again, it will resume with your previous session. That is possible because of your data stored in this authToken.json file. However, that being said this doesn’t mean that you don’t have to enter OTP. You still have the dependency of entering OTP in the Application, just that if you have to close the Application due to IP Throttling or some other issue, you can resume if your Token is still valid without waiting for a new OTP.

Configuration Changes

The values of the following items MUST BE MODIFIED in appsettings.json

"BeneficiaryIds": [ "REPLACE_WITH_YOUR_BENEFICIARY_ID_1", "REPLACE_WITH_YOUR_BENEFICIARY_ID_2" ] 
// You'll get the beneficiary ID from Step 4 above. 
// If you have only 1 beneficiary ID then Use it in the <REPLACE_WITH_YOUR_BENEFICIARY_ID_1> section and remove rest like "REPLACE_WITH_YOUR_BENEFICIARY_ID_2" eg. ["1111111111111111"]. 
// If you have multiple beneficiaries for which you want to do booking, added them comma separated eg. ["11111111111111", "22222222222222", "33333333333333"]
"Mobile": "REPLACE_WITH_YOUR_REGISTERED_MOBILE_NO", 
// Use your registered mobile number used for generation of OTP in Step 2 above.
// Use it in the REPLACE_WITH_YOUR_REGISTERED_MOBILE_NO section. Suppose your Mobile Number is 8888333388 then it'll be like "Mobile" : "8888333388". 
// *NOTE* Don't use +91 infront of your mobile number, use only 10 digit mobile number
"DoseType":  "<REPLACE_ME>", // Use either 1 OR 2 Depending on 1st DOSE or 2nd DOSE in the <REPLACE_ME> section, by default 1 is selected for 1st Dose
"PINCodes": [
  "REPLACE_ME_WITH_YOUR_PIN_CODE_1",
  "REPLACE_ME_WITH_YOUR_PIN_CODE_2"
]
// You can use multiple PINCodes for which you wish to search for, examples are of Mumbai and nearby areas. 
// If you want to search say for a particular PIN Code of Mumbai let's say 400008 then the entry would look like this : "PINCodes": [ "400008" ].
// Basically, Replace REPLACE_ME_WITH_YOUR_PIN_CODE_1 WITH 400008. and remove everything else.
// In case you want to search for multiple PIN Codes say 400008 and 400007, 
// you'll have to remove REPLACE_ME_WITH_YOUR_PIN_CODE_1 with 400008 and REPLACE_ME_WITH_YOUR_PIN_CODE_2 with 40007 and so in, it would look something like this "PINCodes": [ "400008", "400007" ]

The values of the following items MAY BE MODIFIED in appsettings.json, default values are set

Please Note: DO NOT Change or remove to Defaut values if you are not going to use the setting for your Searching of Slot.

"MinAgeLimit": "<REPLACE_ME>", // Use either 18 or 45 in the REPLACE_ME Section. 18 means that you are searching for slots of 18+ and 45 means for 45+. By default, 18 is used.
"MaxAgeLimit": "<REPLACE_ME>", // Use either 44 or 99 in the REPLACE_ME Section. 44 means that you are searching for slots of only 18+ (18-44) Age Group and 100 means that you are searching for only 45+ (45-99) age group. By default, 44 is used.
"MinimumVaccineAvailability": "<REPLACE_ME>", // Use 1 or any Minumum Number that you feel should be available atleast when you are searching for slots, in the REPLACE_ME section. By default, 1 is selected as minimum availability
"ProtectedAPI": { "IsToBeUsed": "<REPLACE_ME>"} // Use true of false in the <REPLACE_ME> section. Use false if you want to search slots using Public API. By default, true to use ProtectedAPI for searching
"VaccineType": "<REPLACE_ME>", // USE EITHER COVAXIN OR COVISHIELD, OR SPUTNIK V or "" in the <REPLACE_ME> section, by default "" is selected with means any type of Vaccine
"VaccineFeeType": "<REPLACE_ME>", // USE Either Free or Paid or "" in the <REPLACE_ME> section, by default "Free" is selected, blank implies both Free and Paid types
"SlotPreference": "<REPLACE_ME>", // Preference of Slot of Booking, use either First or Last or Random in the <REPLACE_ME> section; Default is Last (due to higher changes of getting the slot)  
"IsSearchToBeDoneForVaccinationCentreName": "<REPLACE_ME>", // se Either true or false in the <REPLACE_ME> section where true means you want to search for specific Centres within your PINCode/District and false means you don't want to search by CentreName. By default, false is selected
"VaccinationCentreNames": [
    "REPLACE_ME_WITH_YOUR_VACCINATION_CENTER_NAME_1",
    "REPLACE_ME_WITH_YOUR_VACCINATION_CENTER_NAME_2"
], // You need to put the exact names of the Vaccination Centres for which you want to search in the REPLACE_ME_WITH_YOUR_VACCINATION_CENTER_NAME_1, REPLACE_ME_WITH_YOUR_VACCINATION_CENTER_NAME_2 sections.
// You'll get the names of the Centres from CoWIN Portal. By default all Vaccination Centres in the District/PINCodes are selected. Filter will work only if you set the IsSearchToBeDoneForVaccinationCentreName to true and provide proper exact names of the Centres for which you are searching slots
"IsSearchToBeDoneByPINCode": "<REPLACE_ME>", // Use Either true or false in the <REPLACE_ME> section where True means searching is done using PIN Code, by default true is selected. Set this is True if you want to search By PIN Code
"DateToSearch": "<REPLACE_ME>",  // Use date in DD-MM-YYYY Format in the <REPLACE_ME> section, Blank implies date of next day (i.e, tomorrow), by default "" is selected to search for Next Day
"IsSearchToBeDoneByDistrict": "<REPLACE_ME>", // Use Either true or false in the <REPLACE_ME> section where True means searching is done by DistrictId, by default false is selected, Set this is True if you want to search By District
"Districts": [
  "REPLACE_ME_WITH_YOUR_DISTRICT_CODE_1",
  "REPLACE_ME_WITH_YOUR_DISTRICT_CODE_2"
],
// You'll get District Codes from the link below this block, examples are for Mumbai and nearby districts. 
// Basically, Replace REPLACE_ME_WITH_YOUR_DISTRICT_CODE_1 with 395, then the entry would look like this : "Districts": [ "395" ].
// In case you want to search for multiple Districts say Mumbai and Thane, get the District-District Code Mapping from below "State-District-DistrictCode Mapping", // you'll get the DistrictCode of Mumbai as 395 and of Thane as 392.
// You'll have to remove REPLACE_ME_WITH_YOUR_DISTRICT_CODE_1 with 395 and REPLACE_ME_WITH_YOUR_DISTRICT_CODE_2 with 392, it would look something like this "Districts": [ "395", "392"]
"SleepIntervalInMilliseconds": "<REPLACE_ME>", // In the <REPLACE_ME> Section, Use the Time Interval in Milliseconds you want the system to take rest after trying out your Search Criteria of PIN/District/CentreName once. This will help in lessening the chances of getting IP Throttled. Default is 3500
"IsThrottlingToBeUsed": "<REPLACE_ME>", // In the <REPLACE_ME> Section, Use either true or false; By default true; True means IP throttling is there, False means IP throttling has been removed
"ThrottlingThreshold": "<REPLACE_ME>", //In the <REPLACE_ME> Section, Use the Number of requests per IP allowed for ThrottlingInterval. By default it is set to 100
// Say Throttling Interval is 5 minutes and ThrottlingThreshold is 100, that means, you are allowed for 20 Hits from your IP Address per minute. 
// Change these values accordingly whenever you face the issue of IP being throlled by Server. 
// You may even switch to a different network/IP/Proxy Server so that this can remove the IP Throttling issue for you
"ThrottlingIntervalInMinutes": "<REPLACE_ME>", // In the <REPLACE_ME> Section, use the Interval of Time that is being set for throttling of IP Address. By Default it is // set to 5 which means 5 minutes i.e, in Interval of 5 minutes, 100 requests from your IP Address/Software is allowed. After that you'll receive error unless you switch to another network.
"ThrottlingRefreshTimeInSeconds": "<REPLACE_ME>", // In the <REPLACE_ME> Section, use the Interval of Waiting Time in Seconds when IP is throttled, before resuming the application again. 
// By default, 5 seconds is set as the Refresh Time
// Set the value Higher if you want more wait time when you IP is throttled, or Lower if you are in hurry to book (with chances of getting IP throttled more frequently) 
"Proxy": 
{
   "IsToBeUsed": "<REPLACE_ME>", // Use true or false, true if you are behind Proxy Server, false if you're not, in the <REPLACE_ME> section, by default false would be selected
   "Address": "<REPLACE_ME>" // Use the THE PROXY ADDRESS IF YOU ARE BEHIND PROXY SERVER (usually in Office/Corporate Network) in the <REPLACE_ME> Section, by default this will be blank
}

You can get the District Name and District Code Mapping from State-District-DistrictCode Mapping. Just copy the values of the DistrictCode from the file and paste it in the appsettings.json file’s {“Districts”} Or, you can refer the readable State-District-DistrictCode Markdown file and get the values of District Codes from there.

Entries in the State-District-DistrictCode Mapping file would be like below. In this case, the DistrictCode will 3, 1 and 2.

  "Andaman and Nicobar Islands": {
    "Nicobar": 3,
    "North and Middle Andaman": 1,
    "South Andaman": 2
  }

Be default, this is how the appsettings.json would look like this:

{
  "CoWinAPI": {
    "PublicAPI": {
      "FetchByDistrictUrl": "https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/findByDistrict",
      "FetchByPINUrl": "https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/findByPin"
    },
    "ProtectedAPI": {
      "IsToBeUsed": true, // Set this to false if you want to search slots using Public API
      "FetchByDistrictUrl": "https://cdn-api.co-vin.in/api/v2/appointment/sessions/findByDistrict",
      "FetchByPINUrl": "https://cdn-api.co-vin.in/api/v2/appointment/sessions/findByPin",
      "ScheduleAppointmentUrl": "https://cdn-api.co-vin.in/api/v2/appointment/schedule",
      "AppointmentSlipUrl": "https://cdn-api.co-vin.in/api/v2/appointment/appointmentslip/download",
      "BeneficiaryIds": [ "REPLACE_WITH_YOUR_BENEFICIARY_ID_1", "REPLACE_WITH_YOUR_BENEFICIARY_ID_2" ]
    },
    "Auth": {
      "IsToBeUsed": true,
      "OTPGeneratorUrl": "https://cdn-api.co-vin.in/api/v2/auth/generateMobileOTP",
      "OTPValidatorUrl": "https://cdn-api.co-vin.in/api/v2/auth/validateMobileOtp",
      "Secret": "U2FsdGVkX18vDwDor+oOIG7vSUnINtlc/pxQcNiBulCm8LT5Sza+aIISKLqImbpMnRYgsN2QACPhggLWgZEpQg==",
      "Mobile": "REPLACE_WITH_YOUR_REGISTERED_MOBILE_NO"
    },
    "SleepIntervalInMilliseconds": 3500,
    "IsThrottlingToBeUsed": true, // Use either true or false; By default true; True means IP throttling is inplace, False means IP throttling has been removed
    "ThrottlingThreshold": 100, //Number of request per IP allowed for ThrottlingInterval
    "ThrottlingIntervalInMinutes": 5,
    "ThrottlingRefreshTimeInSeconds": 5, // Waiting Time when IP is throttled, before resuming the application again. Set the value Higher if you want more wait time when you IP is throttled, or Lower if you are in hurry to book (with chances of getting IP throttled more frequently)
    "TotalIterations": 10000,
    "SelfRegistrationPortal": "https://selfregistration.cowin.gov.in",
    "MinAgeLimit": 18,
    "MaxAgeLimit": 44,
    "MinimumVaccineAvailability": 1,
    "VaccineType": "", // Blank Implies Any VaccineType: COVISHIELD OR COVAXIN OR SPUTNIK V; Default is any type of Vaccine
    "DoseType": 1,
    "VaccineFeeType": "Free", // Blank Implies Any VaccineFeeType: Free or Paid; Default is Free    
    "SlotPreference": "Last", // Preference of Slot of Booking, use either First or Last or Random; Default is Last (due to higher changes of getting the slot)  
    "IsSearchToBeDoneForVaccinationCentreName": false, // Set this is true if you want to search for specific Centres within your PINCode/District
    "VaccinationCentreNames": [ // Don't change me if you are not setting IsSearchToBeDoneForVaccinationCentreName as true
      "REPLACE_ME_WITH_YOUR_VACCINATION_CENTER_NAME_1",
      "REPLACE_ME_WITH_YOUR_VACCINATION_CENTER_NAME_2"
    ], // You need to put the exact names of the Vaccination Centres for which you want to search. You'll get that from CoWIN Portal
    "IsSearchToBeDoneByPINCode": true, // Set this as true if you want to set by PINCode
    "PINCodes": [
      "REPLACE_ME_WITH_YOUR_PIN_CODE_1",
      "REPLACE_ME_WITH_YOUR_PIN_CODE_2"
    ],
    "IsSearchToBeDoneByDistrict": false, // Set this is true if you want to search By District
    "Districts": [ // Don't change me if you are not setting IsSearchToBeDoneByDistrict as true
      "REPLACE_ME_WITH_YOUR_DISTRICT_CODE_1",
      "REPLACE_ME_WITH_YOUR_DISTRICT_CODE_2"
    ],
    "DateToSearch": "" // DD-MM-YYYY Format, Blank implies tomorrow's day; Slots are searched ONLY FOR THE DATE in DateToSearch
  },
  "Proxy": {
    "IsToBeUsed": "false",
    "Address": ""
  }
}

As simple as that!

Enjoy and feel free to Star the Repo, if it could help you in any way!

For Developers or Curious Minds:

If you have Visual Studio installed, go ahead an Clone the Repository, Open the SLN file, Make changes in appsettings.json, Ctrl + F5 and Boom! It will do the searching for you, your booking will get done but your booking notifications won’t work and you’ll get System.IO.InvalidDataException exception. Reason for this is that Telemetry and Notification Module needs an Base64 encoded Encrypted Endpoint, API Key and Secret. Since it’s not a good practice to HardCode it in Source Code, so it won’t work unless you get the Encrypted API Endpoint, Telegram Bot Auth Token and the Secret Key along with similar API Endpoint and Secret Key for Telemetry. Unless you care about these, you can proceed, everything will work just fine!

Still curious about that, check out Telemetry and TelegramBotModel

However the standalone release for Windows/Linux/MacOS has all these dependencies buldled so you don’t need to worry about anything! Everything will work seamlessly, we got your back!

Well, want to dig deeper?

So basically, you’ve this Project Named CoWin.Core which contains appsettings.json which performs most of the magic. CoWin.UI is just a small project for handling the Captcha. CoWin.Tests is used for Automated Unit Tests.

Rest of the Business Logic are there inside the /Models directory. Authentication & Authorization stuffs can be found in /Auth directory. API consumption stuffs can be found in /Providers directory. Application begins from Program.cs from the CoWin.Core project.

Clean Coding Practices have been followed during the development of the Application within a span of 2 days after Office Hours. So, you won’t find proper Exception Handling, using Dependency Injection or Logging or even Documentation, duh!

I know, I know, it’s unacceptable, but folks, it’s all about quick Time to Market first and then doing one thing at a time, to improve the product.

I’ll be more than happy to have PRs with modifications.

If you’d like to do it the hard way, clone it, build it and run it. Make sure you’ve the dependencies required to run the Application as mentioned in Technical Details Section

FAQs

Cheers!

NB: appsettings.json play the major role for accessing and booking and filtration of searches. Fiddle with it! Appologies that the Code doesn’t have inline documentation, but code is readable and self explanatory. In case of any suggestions or bugs or feature request, feel free to raise an Issue.

Contact us for any further queries or bug report by mailing us at Vaccine Slot Finder