Automate USCIS Case Tracking

Automate USCIS Case Tracking

Deploy a bot that checks case status and notifies

To get the latest case status(H1B, H4 etc.), one has to visit USCIS and check status by providing case ID. Straight and easy…

What if someone is so lazy(or so busy) to visit the site daily and check the status? Or what if there are more than one Case ID to check everyday?

Having a script that checks daily and notifies us would be so helpful 😀. USCIS does have API features but there is a process and policies on who can get access and use. Maybe it's not worth going through all that process if it's just for one case ID. As a workaround, a simple NodeJS script can be deployed to run daily and lookup the status on our behalf.

Idea:

  1. Take the case ID as input and get the status of the case.

  2. Notify with the latest status

  3. Repeat the process (until stopped)

Have NodeJS and NPM installed already

#1 Script to run the process

Puppeteer’s NPM package will be used to automate running a headless version of browser and get details from USCIS website.

npm i puppeteer

// Checkout the documentation to use other browser than the default.
// Also, optional parameters may require in actual code depending on
// OS and version

Next, the snippet to take the case ID and give the status back.

// index.js
import puppeteer from 'puppeteer';
// Set the case ID
const id = 'YourCaseID';
const mainUrl = 'https://egov.uscis.gov';

const browser = await puppeteer.launch({
    headless: true,
    args: ['--no-sandbox']
});
const page = await browser.newPage();
// Setting user agent is required in headless mode
await page.setUserAgent('Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/133.0');

await page.goto(mainUrl);

// Type into search box
await page.locator('#receipt_number').fill(id);

// Wait and click on first result

await page.locator('[name=initCaseSearch]').click();

const reqUrl = `${mainUrl}/csol-api/case-statuses/${id}`;

// Wait for API request
await page.waitForResponse(reqUrl);

// Capture the value from the element that shows the status

const textSelector = await page
    .locator('#landing-page-header')
    .waitHandle();
const fullTitle = await textSelector?.evaluate(el => el.textContent);

// Print the full title.
console.log(id, fullTitle);

await browser.close();

#2 Notifications:

This is a personal preference on how and when to get notified. Personally I have set up a text message service to get notified via text everyday with the latest status.

But there are other ways to setup and get notified via email(nodemailer) or Webhooks or text messages.

#3 Repeat the process

I have used a Linux VM to run this script. And so, a CRON job has been set up and scheduled to run on a daily basis at a specific time. This job runs the node script and sends out a text message with the latest status of my Case.

This CRON job can also be set up on any local Raspberry PI computer or any old computer. ** On windows a task scheduler does the similar trick.

When this is all put together, it works seamlessly and makes it convenient to track the status automatically.

Based on the operating system and version, puppeteer might run into issues while initializing a headless browser. Use the debug options available to get around the issue.

Cheers ✌

Did you find this article valuable?

Support Krishna Nidri by becoming a sponsor. Any amount is appreciated!