GitHub notifications from the terminal

I work almost entirely from the terminal, and regret the few remaining tasks which still require me to venture elsewhere, such as a web browser. Until recently, one of my main reasons for constantly switching to my browser was to check my GitHub notifications. This post describes how I view my notifications within the terminal, including an option to mark them as “read” on GitHub. The internal functionality is encoded in R, although the functions are mere http::GET calls which could easily be translated into any other language.

The code described and linked to here uses GitHub’s REST (version 3) API, because notifications are not yet (at the time of writing) able to be accessed via the more recent GraphQL (verion 4) API. The GitHub Command-Line-Interface (cli) relies exclusively on the GraphQL API, and so also can’t (yet) be used to access notifications. Once notifications are accessible via GraphQL queries, the cli will be able to be used directly to do everything described here and much more. Until that time, the following provides one way to access GitHub notifications from the terminal.

The script

Like almost everything I do, I associate this with an alias, in this case gn for, of course, GitHub Notifications. The alias calls the following very simple bash script:

#!/usr/bin/bash

if [ "$1" == "" ]; then
    Rscript -e "mpmisc::gh_notifications ()"
elif [ "$1" == "done" ]; then
    Rscript -e "mpmisc::mark_gh_notifications_as_read()"
elif [[ "$1" =~ ^[0-9]+$ ]]; then
    Rscript -e "mpmisc::open_gh_notification ($1)"
else
    echo "gn only accepts 'done' or a single number"
    exit 1
fi

That shows the three options currently implemented:

  1. gn to view notifications;
  2. gn done to mark all notifications as read; and
  3. gn <number> to open the nominated notification in GitHub

All of these options call functions from an R package I use to hold my miscellaneous functions, mpmisc.

The `gh_notifications` functions

All of these functions are contained within a single file of that package, itself containing less than 200 lines of code. The main gh_notifications() function is a simple GET call to the API endpoint. The request requires authentication with a GitHub API token, and returns notifications for the user associated with the token. The request returns a wealth of JSON data described in the API docs (under “Response”), from which I extract a few essential details including:

  1. Title of the notification;
  2. Repository, in org/repo format;
  3. Issue Number (where present; not for notifications from such things as commit messages);
  4. Notification URL;
  5. Time at which notification updated/issued; and
  6. Time at which notification or issue was last read.

These notifications are then cached for immediate recall by other functions. Finally the notifications are printed to screen with a separate function which formats output using ANSII escape codes. The result then looks something like this:

org1/repo2 #3: title one
org4/repo5 #6: title two

Typing gn 1 will then open the first notification in my default web browser. The notifications for the open_gh_notification() function are loaded from the cached version, so opening is effectively instantaeous. Finally, the REST API offers one additional function to mark all notifications as read by issuing a PUT command to the same API endpoint. The mark_gh_notifications_as_read() function does exactly that, and is aliased in the above shell script to gn done.

Originally posted: 27 Oct 21 Updated: 28 Oct 21

Copyright © 2019--22 mark padgham