# Payer portal downloader - ops handover Version: not versioned (no version string in the project, see section 10) · Written 2026-10-23 · Escalation: raise a ticket in the **RPA Support** queue ## 1. What the bot does Every day at 07:00 (Windows Task Scheduler) the bot opens Chrome, signs in to the payer web portal, and downloads each provider's remittance report as a CSV file. It reads the input Excel `data/input/providers.xlsx`: the **Login** sheet (portal username and password) and the **Providers** sheet (one provider per row: NPI, name, Active). It produces one result file per day, `data/output/Download_Report_.xlsx`, with a Status and Remarks for every provider, puts the CSVs in `data/downloads/`, and saves a screenshot to `data/screens/` when a report page fails to load. It drives one app: **Google Chrome** (a Chrome window it opens itself). ## 2. How it works ``` Windows Task Scheduler (07:00 daily) └─ starts → bot (no window of its own) ──drives──> Chrome window → payer portal │ (do not touch while it runs) ├─ reads → data/input/providers.xlsx (Login + Providers sheets) ├─ writes → data/output/Download_Report_.xlsx (at the end) ├─ writes → data/downloads/*.csv (one per provider downloaded) └─ writes → data/screens/.png (only when a report page fails) ``` - **Task Scheduler** starts the bot at 07:00; nobody needs to click anything. - **The bot** has no window. You only see the Chrome window it opens; the bot closes it at the end. - **Chrome** is the browser the bot controls. Clicking or typing in it during a run breaks the run. - **The result file** is written once, when the run ends (also when the run ends early with a problem). Until then it does not exist. - **The downloads folder** collects every CSV. The bot decides "downloaded" by noticing a new CSV appear there. - **The screens folder** gets a picture of the portal page when a report did not load. **One run, step by step:** 1. Read the input Excel (Login and Providers sheets). 2. Open Chrome and sign in to the portal. If sign-in fails, every provider is marked Login Failed and the run ends. 3. For each provider row, top to bottom: - Active = `N` → marked "Skipped - inactive provider", nothing is opened. - Open the provider's remittance page. If the portal has logged the bot out, sign in again and retry. - Portal shows a maintenance banner → marked Downloaded with "portal maintenance - no file" (**no file was downloaded**, see E05). - Wait up to 30 s for the report table. Not there → screenshot, Error. - Portal says no results → No Data. - Click Export CSV and wait up to 60 s for a new CSV in the downloads folder. 4. Close Chrome and save the result file. ## 3. Before a run - [ ] Google Chrome is installed and up to date on the bot machine. The bot cannot start without it, and no result file is written (E08). - [ ] These folders exist: `data/input`, `data/output`, `data/downloads`, `data/screens`. If `data/output` is missing, the result file cannot be saved and the whole day's results are lost (E08). - [ ] The input file has a sheet named exactly **Login** (username in A2, password in B2) and a sheet named exactly **Providers** (row 1 = headers; from row 2: NPI in column A, name in column B, Active in column C). - [ ] Providers sheet rules: - One provider per row. A row with an empty column A is skipped silently and does **not** appear in the result file. - To skip a provider, put a capital `N` in column C. Bad: `n`, `No`, ` N`, `Inactive` - these all count as **active** and the bot will try to download. Good: `N`. Leave column C empty (or `Y`) for active providers. - NPI as the plain 10 digits, e.g. `1000000000`. Bad: `NPI 1000000000`, `1000-000-000`. - [ ] When the portal password changes, update Login!B2 **before 07:00**, otherwise every provider shows Login Failed (E01). - [ ] Running the bot by hand on the same day **overwrites** that day's result file. Copy or rename the 07:00 result file first. - [ ] Don't put your own CSV files into `data/downloads/` - the bot counts any new CSV there as "downloaded". ## 4. During a run - Don't click, type or close tabs in the bot's Chrome window. Don't use that Chrome window for your own browsing. - Don't open, save or move files in `data/downloads/` while the bot runs. - Don't keep `providers.xlsx` or today's result file open in Excel during the run. An open result file can block the save at the end (E08). - To stop the bot: in **Task Scheduler**, right-click the task → **End**. Then close any Chrome window the bot left open. Stopping this way writes **no result file** for that run. Closing Chrome alone also stops it, but the result file may then be missing or cut short. - There is no stuck detection. Each provider normally takes under 2 minutes (30 s for the page + 60 s for the download, longer if it had to sign in again). If the Chrome window shows the same page for more than 10 minutes, the run is stuck: stop it as above and raise a ticket (E09). ## 5. Where to look when something goes wrong | Question | Where to look | |---|---| | Did the run finish? | `data/output/` → is there a `Download_Report_.xlsx`? If not, the run crashed before saving (E08). If it exists, compare its row count with the Providers sheet: fewer rows = the run stopped early (E07). | | Which providers failed? | Result file → Status column. Red = Error. Login Failed rows have no colour. | | Why did one provider fail? | Result file → Remarks column (see section 6 and 7). | | What did the portal show? | `data/screens/.png` (only for "Report grid did not load"). | | Was the file really downloaded? | `data/downloads/` → a CSV with a time just after that provider was processed. The CSV name comes from the portal and does not say which provider it belongs to. | | Did the bot already retry? | Only for "Session expired": it signed in again up to 3 times before giving up. Nothing else is retried. The retry record is in the bot log, which ops cannot open - ask Dev. | | Which version is running? | Not shown anywhere (see section 13). | ## 6. Statuses | Status - Remarks | Colour | Meaning | What ops does | |---|---|---|---| | Downloaded - "Report saved" | green | A new CSV appeared in the downloads folder within 60 s | nothing | | Downloaded - "portal maintenance - no file" | green | **Nothing was downloaded.** The portal showed a maintenance banner. | **Needs follow-up**: re-run this provider later (E05) | | No Data - "No remittances in the date range" | green | Portal said there is nothing to download | nothing | | Skipped - inactive provider - "Marked N in the input" | green | Column C was `N`; the bot did not open the portal for it | nothing | | Login Failed - "Check the portal username/password" | no colour | Sign-in failed at the start; **no provider was processed** (every row gets this, even inactive ones) | E01 | | Error - "Report grid did not load" | red | Report table didn't appear in 30 s | E02 | | Error - "Download did not finish" | red | No new CSV within 60 s after Export | E03 - check the downloads folder first | | Error - "Session expired" | red | Portal kept logging the bot out, even after 3 sign-ins | E04 | | *(provider missing from the result file)* | - | Run stopped before reaching it | E07 | | *(no result file for today)* | - | Run crashed before or while saving | E08 | ## 7. Exception catalogue | ID | What you see | How the bot identifies it | Where it is recorded | Type | Who acts | What to do | Escalate when | |---|---|---|---|---|---|---|---| | E01 | Every row: Login Failed - "Check the portal username/password" | After clicking Sign in, it waits 30 s for the portal dashboard; if it never appears, sign-in counts as failed | Result file, Status/Remarks on every row | Business (wrong password) or System (portal down/slow) | Ops | Sign in to the portal by hand with the Login sheet details. If that fails, fix the password in Login!B2. If it works by hand, wait 30 min and re-run (copy the morning result file first). | Manual sign-in works but the bot still gets Login Failed twice in a row | | E02 | Error - "Report grid did not load" | Waits 30 s for the remittance table on the provider's page | Result file; picture in `data/screens/.png` | System | Ops | Open the screenshot. If it shows a portal error or an empty page, re-run later. If it shows "provider not found" or similar, check the NPI in the input. | Same provider fails on 2 runs and the screenshot shows a normal-looking page | | E03 | Error - "Download did not finish" | After clicking Export CSV, waits 60 s for a new CSV in the downloads folder | Result file | System | Ops | **Check `data/downloads/` first** - the file may have arrived late. A late file can also be miscounted as the *next* provider's download (see section 13), so check that provider too. If no file: re-run. | Fails again on re-run | | E04 | Error - "Session expired" | The portal sent the bot back to the sign-in page; it signed in again and retried, 3 times | Result file | System | Bot, then Ops | Re-run later. If many rows show this, the portal is unstable that day. | More than 3 providers with this in one run, or on 2 days in a row | | E05 | Downloaded (green) - "portal maintenance - no file" | Portal page shows a maintenance banner | Result file | System | **Ops** | Treat as **not downloaded**. Re-run this provider after the maintenance window. Do not trust the green colour. | Banner still there after 24 h | | E06 | A provider you expected to be skipped was processed, or one you expected is missing | Only a capital `N` in column C means inactive; rows with empty column A are ignored | Result file (row status, or row absent) | Business | Ops | Fix the input per section 3 and re-run if needed | - | | E07 | Result file has fewer rows than the Providers sheet; the last row looks normal | The portal logged the bot out and the **re-sign-in** failed, or a portal button/field was missing. The bot stops at once; providers after that point are not processed | Result file (rows missing); the cause is only in the console output, which ops cannot see | System | Ops, then Dev | Note the first missing provider. Re-run (copy the morning result file first). | Happens again on re-run - send the result file and the time of the run | | E08 | No `Download_Report_.xlsx` in `data/output/` after the run should have finished | Chrome couldn't start, the input file couldn't be read, `data/output` is missing, or the result file was open in Excel | Nowhere ops can see | System | Ops, then Dev | Check section 3 (Chrome installed, folders exist, input file present, result file not open). Fix and re-run. | Everything in section 3 is fine and still no file - send the date/time and say whether a Chrome window appeared | | E09 | Chrome window stuck on the same page for >10 min | No detection - the bot has no watchdog | Nowhere | System | Ops, then Dev | Stop the bot (section 4) and re-run | Stuck again on re-run - send the time and a screenshot of the Chrome window | ## 8. What the bot recovers by itself | Problem | What the bot does | Limit | After the limit | |---|---|---|---| | Portal logged the bot out | Signs in again and reopens the provider's page | 3 sign-ins per provider (each waits up to 30 s) | Row = Error "Session expired", next provider | | Sign-in during that retry fails | Nothing - the run stops | 0 retries | Remaining providers missing from the result file (E07) | | Report table slow | Waits | 30 s, no retry | Row = Error "Report grid did not load", next provider | | Download slow | Waits | 60 s, no retry | Row = Error "Download did not finish", next provider | | First sign-in fails | Nothing | 0 retries | All rows Login Failed, run ends | Nothing else is retried. There is no automatic re-run of failed providers; ops re-runs by hand. ## 9. Known incidents There is no git history, bug log or release notes for this bot. One event is visible in the bot log: | When / version | What ops saw | Cause | What to do now | Ops could handle? | |---|---|---|---|---| | 2026-09-02 07:01 (unversioned) | One provider Error right after the portal logged the bot out once | Unknown - the bot log does not record the Remarks text, only the status | Treat per E02-E04 using the Remarks column | Partly | ## 10. Releases and version check - How an update arrives: there is no launcher or update process. A developer replaces the files in the bot folder. - How to confirm it applied: not possible today - the bot shows no version anywhere (section 13, item 7). - If you suspect an old build: raise a ticket and ask Dev which version is in the folder. ## 11. Escalating to dev Raise a ticket in the **RPA Support** queue. Send: the date and start time of the run, the exception ID from section 7, the result file `Download_Report_.xlsx`, the NPI of the failed provider, and the screenshot from `data/screens/` if there is one. Never send: the portal password, the Login sheet, `config.yaml`, or downloaded remittance CSVs (they contain patient payment data). ## 12. Failure-class check - F1 covered in section 3 (Chrome, folders, sheet names) and E08. - F2 covered in section 4 (hands off the bot's Chrome window; no files into the downloads folder). The bot does not match windows by title. - F3 covered in E02, E03, E09 and section 8 (30 s / 60 s waits, no retry). - F4 covered in section 3 (exact `N`, plain NPI, no empty column A) and E06. - F5 covered in E05 and section 13 item 1 (maintenance marked Downloaded with no file). - F6 covered in E03 and section 13 item 2 (late CSV can be credited to the next provider). - F7 covered in section 6 (maintenance row green, "needs follow-up"), E05 and section 13 item 1. - F8 covered in section 8 (re-sign-in limited to 3; no auto-rerun loop) and E09 / section 13 item 5 (no watchdog). - F9 covered in section 4 (stop via Task Scheduler → End, then close Chrome) and section 13 item 6. - F10 not applicable for queues: each provider is independent and nothing stays Pending across runs. The one blocker - a failed re-sign-in stops all later providers - is E07. - F11 covered in section 13 items 3, 4 and 8 (crash cause only on console, remarks not logged, CSV not tied to provider). - F12 covered in section 10 and section 13 item 7 (no version string). No shared resources are rewritten on start. ## 13. Fix before handover (dev team) | # | Gap | Why it hurts ops | Where (file:line) | |---|---|---|---| | 1 | Maintenance banner returns status "Downloaded" (green) with no file | Ops thinks the report was downloaded | `bot.py:54-55` | | 2 | Download check counts any new `*.csv` in the shared downloads folder; a late file from one provider is credited to the next. CSV is never renamed to the NPI | Wrong provider marked Downloaded; ops can't tell which CSV is whose | `bot.py:63-70` | | 3 | Re-sign-in failure inside the retry loop (`RuntimeError` from `login`) and any `NoSuchElementException` are not caught; run stops, remaining providers vanish from the report, traceback goes to console only | Silent partial runs (E07); cause not visible anywhere ops can open | `bot.py:96-102`, `bot.py:41-43`, `bot.py:64` | | 4 | Crashes before the `try` (input load, Chrome start) produce no report at all, and nothing is logged | No result file, no reason (E08) | `bot.py:75-81` | | 5 | No watchdog / overall run timeout | A hung page holds the run until someone notices (E09) | `bot.py:85-109` | | 6 | Ending the task kills Python without closing Chrome or saving the report; `driver.quit()` raising in `finally` would also skip the save | Stop = lost results, orphan Chrome | `bot.py:108-110` | | 7 | No version string anywhere | Ops can't confirm which build is running | project-wide | | 8 | Log line records status but not the remark; log file `logs/bot.log` is not reachable by ops | Incident cause can't be reconstructed (section 9) | `bot.py:105` | | 9 | Result file is named by date only; a same-day re-run overwrites the 07:00 report | Morning evidence lost | `bot.py:110` | | 10 | Login Failed rows get no colour fill (and inactive providers are also marked Login Failed) | Inconsistent with the colour legend | `bot.py:89-91` | | 11 | Active check is `!= "N"`: `n`, `No`, ` N` count as active | Providers meant to be skipped are processed | `bot.py:77` | | 12 | `data/output` (and other data folders) are not created by the bot | Missing folder = whole day's report lost | `bot.py:20-21`, `bot.py:110` | | 13 | A live-looking API token is committed in `config.yaml` (unused by the code); portal password is stored in plain text in the input Excel | Credential exposure | `config.yaml:2`, `bot.py:76` | | 14 | `requirements.txt` has no pinned versions | A Selenium update can break the bot without any code change | `requirements.txt:1-3` |