Last active
October 2, 2025 21:41
-
-
Save csvn/ecf6ff88524eb3a604c1d9817a8d3991 to your computer and use it in GitHub Desktop.
Short Deno script to clear "Ghost Notifications", inspired by https://github.com/orgs/community/discussions/6874?sort=new#discussioncomment-14481784. Requires the GH CLI, and Deno v2+. Edit the dates and repostories to clear notifications for before running.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| deno run delete-ghost-notifications.ts | |
| # Run with -A flag to disable permission checks | |
| deno run -A delete-ghost-notifications.ts |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { $ } from 'jsr:@david/dax@0.43.2'; | |
| import type { GetResponseDataTypeFromEndpointMethod } from 'npm:@octokit/types@15.0.0'; | |
| import type { Octokit } from 'npm:@octokit/rest@22.0.0'; | |
| type Notifications = GetResponseDataTypeFromEndpointMethod< | |
| InstanceType<typeof Octokit>['activity']['listNotificationsForAuthenticatedUser'] | |
| >; | |
| // UPDATE THESE BEFORE RUNNING | |
| const PAGE = 1; | |
| const SINCE = '2025-09-01T00:00:00Z'; | |
| const TO_REMOVE = new Set([ | |
| 'lido-fi-staking/lido-finance', | |
| ]); | |
| // Token via `gh` CLI | |
| const token = await $`gh auth token`.text(); | |
| const headers = new Headers({ | |
| Accept: 'application/vnd.github+json', | |
| Authorization: `Bearer ${token}`, | |
| 'X-GitHub-Api-Version': '2022-11-28', | |
| }); | |
| const deleteNotificationUrls = []; | |
| { | |
| console.log('\nFetching notifications...'); | |
| const res = await fetch( | |
| `https://api.github.com/notifications?all=true&since=${SINCE}&page=${PAGE}`, | |
| { headers }, | |
| ); | |
| const notifications: Notifications = await res.json(); | |
| for (const n of notifications) { | |
| if (TO_REMOVE.has(n.repository.full_name)) { | |
| deleteNotificationUrls.push(n.url); | |
| console.log(`Added ${n.repository.full_name} (${n.id}) to delete list: "${n.subject.title}"`); | |
| } | |
| } | |
| } | |
| console.log('\nDeleting notifications...'); | |
| for (const url of deleteNotificationUrls) { | |
| const res = await fetch(url, { method: 'DELETE', headers }); | |
| if (!res.ok) throw new Error(`Failed to DELETE notification with URL: ${url}`); | |
| console.log(`Successfully deleted notification with URL: ${url}`); | |
| } | |
| console.log('\nDone!'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment