Skip to content

Instantly share code, notes, and snippets.

@aaronsbytes
Last active February 9, 2024 17:28
Show Gist options
  • Save aaronsbytes/886fc18e169333ba3ab0fa30a4f30056 to your computer and use it in GitHub Desktop.
Save aaronsbytes/886fc18e169333ba3ab0fa30a4f30056 to your computer and use it in GitHub Desktop.
A small project of mine to recieve GitHub notifications on GrapheneOS through my ntfy instance
import requests
from requests import Response
from dotenv import load_dotenv
import os
from datetime import datetime
class GithubNotifier:
"""
A small project for myself to receive GitHub notifications on GrapheneOS
Made by NeuroException
"""
def __init__(self, api_token: str, ntfy_instance: str):
# Define constants
self.__token = api_token
self.__ntfy_instance = ntfy_instance
# Check for api token
if not self.__token:
self.__log("You must provide an api token!")
# Fetch json data
response: Response = self.__fetch()
# Check for errors
if response.status_code != 200:
self.__log(f"[Error] {response.status_code}")
return
# Parse as json
notifications: dict = response.json()
# Return if no notifications
if not notifications:
return
# Send all notifications
for notification in notifications:
# Parse action info for the notification
repo_name: str = notification['repository']['full_name']
subject: str = notification['subject']['title']
url: str = notification['subject']['url']
# Send the notification
self.__notify(repo_name, subject, url)
# Mark all as read (to avoid duplicate notifications)
self.__mark_read()
@staticmethod
def __get_current_time() -> str:
"""
Method for getting the current date + time
:return: The current date + time
"""
return datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
def __log(self, content):
"""
Method for logging events in a proper way
:param content: The message for the log
"""
# Get current time
current_time: str = self.__get_current_time()
# Print it
print(f"[{current_time}] {content}")
def __fetch(self) -> Response:
"""
Method for fetching all notifications from the GitHub api
:return: The api response
"""
# Set up the headers with the access token
headers: dict = {
'Authorization': f'Bearer {self.__token}'
}
# Get the api response
response: Response = requests.get("https://api.github.com/notifications", headers=headers)
# Return it
return response
def __mark_read(self) -> Response:
"""
Method for marking all notifications on GitHub as read
:return: The api response
"""
# Define url
url: str = "https://api.github.com/notifications"
# Define headers
headers: dict = {
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {self.__token}",
"X-GitHub-Api-Version": "2022-11-28"
}
# Get the current time
current_time: str = self.__get_current_time()
# Define payload
data: dict = {
"last_read_at": current_time,
"read": True
}
# Post request
response: Response = requests.put(url, headers=headers, json=data)
# Return api response
return response
def __notify(self, title, msg, subject_url) -> Response:
"""
Method for sending a notification to your ntfy instance
:param title: Title of the notification
:param msg: The content of the notification
:param subject_url: The url being opened when clicking on the notification
:return: The api response
"""
# Post request
action_response: Response = requests.get(subject_url)
# Grab action url from request
action_url: str = action_response.json()['html_url']
# Define headers
headers: dict = {
"X-Title": title,
"Click": action_url
}
# Send notification to ntfy server
response: Response = requests.post(url=self.__ntfy_instance, headers=headers, data=msg)
# Return api response
return response
# Load the .env
load_dotenv()
# Remember to set your api token
token: str = os.getenv("API_KEY")
# Set the url for your ntfy instance
ntfy_instance: str = os.getenv("NTFY_INSTANCE")
# Create an instance
notifier = GithubNotifier(api_token=token, ntfy_instance=ntfy_instance)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment