GitHub Notification Manager
Rule-based automation for GitHub notifications. Define rules to automatically mark notifications as read or archive them based on repository, notification type, age, and more.
Built in Rust for performance and ease of deployment (single binary).
Features
- Rule-based processing: Define flexible rules with multiple filter criteria
- Multiple actions: Mark as read, mark as done (archive), or skip
- Pattern matching: Support for wildcards in repository names
- Age-based filtering: Process notifications based on age or date ranges
- Dry-run mode: Test rules before applying them
- Beautiful CLI output: Colored terminal output with tables
- Validation: Validate configuration before running
- Smart authentication: Uses
gh auth tokenwith fallback toGITHUB_TOKEN
Installation
Build from source
cd ~/src/home/tools/github-notif-manager
cargo build --release
The binary will be at target/release/github-notif-manager.
Authentication
The tool automatically uses authentication from:
- GitHub CLI (
gh auth token) - if you’re logged in withgh auth login - Environment variable -
GITHUB_TOKENorGH_TOKEN
No manual token configuration needed if you use the GitHub CLI!
Configuration
Create a configuration file (start with config.example.yaml):
cp config.example.yaml my-config.yaml
Edit to define your rules:
rules:
# Archive Dependabot notifications
- name: "Archive Dependabot"
filters:
reason: "subscribed"
repository: "myorg/*"
subject_type: "PullRequest"
action: mark_done
enabled: true
# Mark CI notifications as read
- name: "Auto-read CI"
filters:
subject_type: "CheckSuite"
action: mark_read
enabled: true
# Archive old read notifications
- name: "Archive old"
filters:
unread: false
age_days: 7
action: mark_done
enabled: true
Available Filters
repository: Repository name or pattern (e.g.,"owner/repo"or"owner/*")reason: Notification reason (e.g.,"subscribed","mention","team_mention","author","state_change","review_requested")subject_type: Type of subject (e.g.,"Release","Issue","PullRequest","CheckSuite","Discussion")subject_title: Pattern matching on notification title (e.g.,"*bump *") - supports wildcards, case-insensitiveunread: Boolean -truefor unread,falsefor readage_days: Number - notifications older than N daysupdated_before: ISO date string - notifications updated before this date (YYYY-MM-DD)updated_after: ISO date string - notifications updated after this date (YYYY-MM-DD)
Available Actions
mark_read: Mark notification as read (keeps in inbox)mark_done: Mark notification as done (archives it)skip: Don’t process (useful for exclusion rules)
Usage
Validate Configuration
Check your configuration file for errors:
github-notif-manager validate --config config.yaml
List Notifications
View your recent notifications (useful for testing filters):
github-notif-manager list --limit 20
Process Notifications (Dry Run)
Test your rules without making changes:
github-notif-manager process --config config.yaml --dry-run
Process Notifications (Live)
Apply rules to your notifications:
github-notif-manager process --config config.yaml
Verbose Output
Show all processed notifications including skipped ones:
github-notif-manager process --config config.yaml --dry-run --verbose
Examples
Archive Merged Dependabot PRs
rules:
- name: "Archive merged Dependabot PRs"
filters:
subject_type: "PullRequest"
reason: "state_change"
subject_title: "*bump *" # Case-insensitive; matches "Bump ..." and "chore(deps): bump ..."
action: done
Archive All Dependabot Notifications
rules:
- name: "Archive Dependabot"
filters:
reason: "subscribed"
repository: "*/*" # All repositories
action: mark_done
Mark CI Notifications as Read from Specific Org
rules:
- name: "Auto-read org CI"
filters:
repository: "myorg/*"
subject_type: "CheckSuite"
action: mark_read
Archive Old Read Notifications
rules:
- name: "Cleanup old"
filters:
unread: false
age_days: 14 # Older than 2 weeks
action: mark_done
Skip Important Repositories
rules:
# This rule should come BEFORE other broader rules
- name: "Keep important notifications"
filters:
repository: "myorg/critical-repo"
action: skip
- name: "Archive everything else from org"
filters:
repository: "myorg/*"
action: mark_done
Complex Multi-Filter Rule
rules:
- name: "Archive old subscribed PRs"
filters:
repository: "myorg/*"
subject_type: "PullRequest"
reason: "subscribed"
unread: false
age_days: 3
action: mark_done
Automation
Daily Cron Job
Add to your crontab:
# Run daily at 2 AM
0 2 * * * /path/to/github-notif-manager process --config /path/to/config.yaml
Systemd Timer
Create ~/.config/systemd/user/github-notif-manager.service:
[Unit]
Description=GitHub Notification Manager
After=network-online.target
[Service]
Type=oneshot
WorkingDirectory=%h/src/home/tools/github-notif-manager
ExecStart=%h/src/home/tools/github-notif-manager/target/release/github-notif-manager process --config config.yaml
Create ~/.config/systemd/user/github-notif-manager.timer:
[Unit]
Description=Run GitHub Notification Manager daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
Enable and start:
systemctl --user enable --now github-notif-manager.timer
Tips
- Test with dry-run first: Always test your rules with
--dry-runbefore running live - Start with specific rules: Begin with narrow filters and expand as needed
- Use skip for exclusions: Place exclusion rules (with
skipaction) before broader rules - Check notification reasons: Use
github-notif-manager listto see what notification reasons you receive - Monitor API rate limits: The tool respects GitHub API rate limits, but be aware when running frequently
Troubleshooting
“No GitHub token found”
Either:
- Run
gh auth loginto authenticate with GitHub CLI, or - Set the
GITHUB_TOKENenvironment variable:export GITHUB_TOKEN="your_token"
“Configuration file not found”
Specify the full path to your config file:
github-notif-manager process --config ~/path/to/config.yaml
Rules not matching as expected
Use --verbose --dry-run to see all notifications and which rules match:
github-notif-manager process --config config.yaml --dry-run --verbose
Development
Build:
cargo build
Run tests:
cargo test
Format code:
cargo fmt
License
MIT