# Opioid Watcher

View the [public dashboard](https://wayne-kepner.github.io/opioid-watcher/) or inspect the [source repository](https://github.com/wayne-kepner/opioid-watcher). The public dashboard displays the last snapshot committed to GitHub. Running the local refresh updates files on this computer; commit and push the changed data files to update the public dashboard.

Double-click `Open Opioid Watcher.command` to view the local dashboard in your browser. Keep its Terminal window open while you use the app. Double-click `refresh.command` to update the current news feed, five-year news archive, and CDC provisional mortality data, then reload the browser tab. The first archive retrieval takes several minutes; later runs reuse completed date windows and retrieve the newest dates. You can also run `/usr/bin/python3 refresh.py` and `/usr/bin/python3 archive.py` in Terminal. The scripts write `data.json` and `archive.json` for inspection, plus matching JavaScript files for the browser. Each script keeps its previous successful snapshot when retrieval fails.

You can search and filter headlines, save articles across refreshes, and export matching media leads to CSV. A saved search reports new matches when you reopen the app after a refresh, then clears its count when you open that watch. The browser stores saved items and review labels locally. The feed stores up to 300 recent headlines and links, not article text. A headline must contain an opioid-related term, but a person still needs to check its relevance. Keyword rules assign provisional topics. The default public health focus suppresses obvious criminal-case headlines, and you can turn that filter off. The U.S. edition feed can include reporting about events elsewhere.

The local `history.json` file records one retrieval count per day, including the count that passes the public health focus. The app plots this retrieval history after later refreshes. Source indexing and overlapping search feeds affect the count, so the trend cannot establish a change in opioid use or the number of distinct events. Several outlets may report the same event.

The five-year archive runs the same dated Google News search for opioid, fentanyl, naloxone, methadone, buprenorphine, xylazine, and nitazene across the full period. The script splits a date range whenever Google returns its 100-result RSS limit. It keeps distinct headlines and publishers, applies the same headline screen as the current feed, and groups results by publication month. A striped month contains a date that still reached the limit after splitting; its count is a minimum. The first and last months cover only part of a month. You can click a month, search headlines, filter topics, mark articles Relevant or Exclude, and export the matching rows to CSV. Google may change its search index, so these retrieval counts do not establish the total number of published articles or a stable media-attention trend. The browser stores review labels locally; the script does not claim that its keyword screen verifies relevance.

The health panel plots five years of the CDC's **predicted provisional counts of U.S. deaths involving any opioid**. Each monthly point counts deaths during the preceding 12 months, so nearby points overlap. The chart labels the year, and the table lists each ending month. CDC adjusts predicted counts for incomplete records, and later releases can revise them. The chart does not present a single month's deaths or a population rate. CDC advises caution when comparing specific-drug counts across states because toxicology practices differ.

## Why this design

John W. Ayers co-founded [Tobacco Watcher](https://stable.tobaccowatcher.org/about) with Joanna Cohen and Mark Dredze. Their [original surveillance poster](https://publichealth.jhu.edu/sites/default/files/2023-07/poster15srnttw.pdf) describes multilingual news retrieval and human-trained classification. The current site offers article search, analyses, signals, and alerts. I used its media-monitoring idea while separating news coverage from measured health outcomes. A [published methods study](https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0205822) reports imperfect automated topic and location coding, so the first release requires human review before anyone treats a headline as verified policy or an emerging outbreak.

## Sources and limits

- [Google News RSS](https://news.google.com/) supplies the current media leads. Search coverage depends on Google's indexing and ranking; article counts are not a stable census of reporting or a measure of opioid use.
- [CDC provisional drug overdose data](https://data.cdc.gov/d/xkb8-kh2a) supply the national opioid series. The [CDC technical page](https://www.cdc.gov/nchs/nvss/vsrr/drug-overdose-data.htm) explains its 12-month periods, provisional status, and drug involvement codes. The U.S. total covers the 50 states and DC, excludes Puerto Rico, and groups deaths by place of occurrence.
- [CDC DOSE-SYS](https://www.cdc.gov/overdose-prevention/data-research/facts-stats/dose-sys-accessible.html) measures suspected opioid-involved emergency visits per 10,000 total ED visits in participating jurisdictions. I have not combined that rate with deaths because the systems measure different events and populations.
- The separate National Addiction Vital Signs dashboard covers broader national measures. Opioid Watcher specializes in media leads and one clearly labeled mortality series.

## Iteration notes

The first design considered treating news volume as an early overdose signal. Reviewers rejected that interpretation because publication volume changes with editorial attention and search coverage. The current design labels every new article as unreviewed, omits geographic event inference from publisher location, and reserves the outcome panel for an official measure. A future release could add source-specific agency feeds, primary-record verification status, and a separately labeled DOSE-SYS panel after testing the ingestion and denominator labels.
