Compare commits

...

26 Commits
v1.5 ... v1.7.2

Author SHA1 Message Date
Félix MARQUET
de60020b01 Merge pull request #13 from BreizhHardware/dev
fix(dependabot): ensure updates target the dev branch
2025-06-10 11:47:55 +02:00
Félix MARQUET
1430d39b5c fix(dependabot): ensure updates target the dev branch 2025-06-10 11:46:40 +02:00
Félix MARQUET
47fa8f820e Merge pull request #10 from BreizhHardware/dev
Create dependabot.yaml
2025-06-10 11:31:06 +02:00
Félix MARQUET
56439d8c62 Update dependabot.yaml 2025-06-10 11:30:56 +02:00
Félix MARQUET
013c5bd70d Create dependabot.yaml 2025-06-10 11:29:08 +02:00
Félix MARQUET
c81fc26881 fix(dockerfile): add send_slack.py to the dockerfile 2025-05-05 09:08:18 +00:00
Félix MARQUET
e7b89930f1 Merge pull request #7 from Mahmoud0x00/slack-notification-add
feat: add Slack notification
2025-05-05 08:36:45 +02:00
Mahmoud Osama
246b727d0a Update notification messages format
Update notification messages format to use Emojis with:
* Discord
* Gotify
* Ntfy
2025-05-04 19:59:39 +03:00
Mahmoud Osama
83cfd9a2f1 Update README.md with SLACK_WEBHOOK_URL 2025-05-04 14:13:43 +03:00
Mahmoud Osama
8795add7f0 Add SLACK_WEBHOOK_URL to Dockerfile 2025-05-03 20:52:08 +03:00
Mahmoud Osama
3d33cb8282 Add Slack notifcation
 Support Slack incoming webhook notifications with good looking block message design
2025-05-03 20:17:20 +03:00
Félix MARQUET
aa2f654d4b Merge pull request #6 from BreizhHardware/dev
feat: Refactor web UI
2024-12-23 20:17:52 +01:00
e1b16ac645 feat: Refactor web UI
- Refactor of the webUI
2024-12-23 20:12:11 +01:00
Félix MARQUET
7a221a9ab9 Merge pull request #5 from BreizhHardware/dev
feat: merge dev into main

    Created the connection with Discord.
    Added CONTRIBUTION.md.
    Reworked GitHub CI.
    Fixed threading issues.
2024-12-23 20:00:10 +01:00
a3e892c8f0 fix: use separate database connections for each function
- Refactored `send_discord.py` to better work with webhook (but remove the embed)
- Updated Dockerfile to adjust package installation order.
2024-12-23 19:56:57 +01:00
e8eb8d18d2 fix: use separate database connections for each function
- Refactored `send_gotify.py`, `send_ntfy.py`, and `send_discord.py` to use separate database connections for each function.
- Added `get_db_connection` function to create a new database connection.
- Updated `github_send_to_gotify`, `docker_send_to_gotify`, `github_send_to_ntfy`, `docker_send_to_ntfy`, `github_send_to_discord`, and `docker_send_to_discord` functions to use the new `get_db_connection` function.
- Modified `ntfy.py` to use threading for calling notification functions simultaneously.
2024-12-23 19:33:49 +01:00
Félix MARQUET
66759932f0 chore(ci): remove GitHub release build to use Docker only
Edit CI configuration to remove GitHub release build. Now, builds are only for Docker, and I will use the Conventional Release Bot app to manage releases.
2024-12-23 15:47:49 +00:00
Félix MARQUET
dc831c958f docs: update README.md with dependancies installation
- Add instruction for installing the dependencies
2024-12-23 12:41:57 +00:00
Félix MARQUET
edff2e3806 docs: add CONTRIBUTION.md and update README.md with contribution guidelines
- Added CONTRIBUTION.md to provide guidelines for contributing to the project.
- Updated README.md to include a link to CONTRIBUTION.md for easy access to contribution guidelines.
2024-12-23 12:29:18 +00:00
Félix MARQUET
91cc7bc9bf First itération for discord 2024-12-23 12:20:13 +00:00
fc577ea17f Fix error 2024-11-21 17:20:57 +01:00
ae95654ec3 Fix error 2024-11-21 17:19:52 +01:00
Félix MARQUET
7c0e34c08c Merge pull request #4 from BreizhHardware/dev
Fix DOCKERFILE error
2024-10-25 08:39:33 +02:00
Félix MARQUET
921f40e98e Fix DOCKERFILE error 2024-10-25 06:39:03 +00:00
Félix MARQUET
dcf9edba97 Merge pull request #3 from BreizhHardware/dev
New Readme.md
2024-10-24 15:54:55 +02:00
Félix MARQUET
5f2e86d86a New Readme.md 2024-10-24 13:54:27 +00:00
13 changed files with 573 additions and 218 deletions

12
.github/dependabot.yaml vendored Normal file
View File

@@ -0,0 +1,12 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "pip" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
target-branch: "dev"

View File

@@ -1,73 +1,30 @@
name: Docker Build and Release
on:
push:
branches:
- main
jobs:
build-and-push-on-docker-hub:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/github-ntfy:latest
release-on-github:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get the latest tag
id: get_latest_tag
run: echo "latest_tag=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_ENV
- name: Increment version
id: increment_version
run: |
latest_tag=${{ env.latest_tag }}
if [ -z "$latest_tag" ]; then
new_version="v1.5"
else
IFS='.' read -r -a version_parts <<< "${latest_tag#v}"
new_version="v${version_parts[0]}.$((version_parts[1] + 1)).0"
fi
echo "new_version=$new_version" >> $GITHUB_ENV
- name: Read changelog
id: read_changelog
run: echo "changelog=$(base64 -w 0 CHANGELOG.md)" >> $GITHUB_ENV
- name: Decode changelog
id: decode_changelog
run: echo "${{ env.changelog }}" | base64 -d > decoded_changelog.txt
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
with:
tag_name: ${{ env.new_version }}
release_name: Release ${{ env.new_version }}
body: ${{ steps.decode_changelog.outputs.changelog }}
draft: false
prerelease: false
name: Docker Build and Release
on:
push:
branches:
- main
jobs:
build-and-push-on-docker-hub:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/github-ntfy:latest

View File

@@ -0,0 +1,73 @@
name: Docker Build and Release
on:
push:
branches:
- main
jobs:
build-and-push-on-docker-hub:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/github-ntfy:latest
release-on-github:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get the latest tag
id: get_latest_tag
run: echo "latest_tag=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_ENV
- name: Increment version
id: increment_version
run: |
latest_tag=${{ env.latest_tag }}
if [ -z "$latest_tag" ]; then
new_version="v1.5.2"
else
IFS='.' read -r -a version_parts <<< "${latest_tag#v}"
new_version="v${version_parts[0]}.$((version_parts[1] + 1)).0"
fi
echo "new_version=$new_version" >> $GITHUB_ENV
- name: Read changelog
id: read_changelog
run: echo "changelog=$(base64 -w 0 CHANGELOG.md)" >> $GITHUB_ENV
- name: Decode changelog
id: decode_changelog
run: echo "${{ env.changelog }}" | base64 -d > decoded_changelog.txt
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
with:
tag_name: ${{ env.new_version }}
release_name: Release ${{ env.new_version }}
body: ${{ steps.decode_changelog.outputs.changelog }}
draft: false
prerelease: false

View File

@@ -1,4 +1,6 @@
**New features**:
- Add gotify compatibility please Read the README.md
- Add arm64 support
- Add armv7 support
**Full Changelog**: https://github.com/BreizhHardware/ntfy_alerts/compare/v1.4.3...v1.5

54
CONTRIBUTION.md Normal file
View File

@@ -0,0 +1,54 @@
# Contribution Guidelines
Thank you for considering contributing to this project! Your help is greatly appreciated. Please follow these guidelines to ensure a smooth contribution process.
## How to Contribute
1. **Fork the repository**: Click the "Fork" button at the top right of this repository to create a copy of the repository in your GitHub account.
2. **Clone your fork**: Clone your forked repository to your local machine.
```sh
git clone https://github.com/BreizhHardware/ntfy_alerts.git
cd ntfy_alerts
```
3. **Create a new branch**: Create a new branch for your feature or bugfix.
```sh
git checkout -b feat/my-feature-branch
```
4. **Make your changes**: Make your changes to the codebase. Ensure your code follows the project's coding standards and includes appropriate tests.
5. **Commit your changes**: Commit your changes with a clear and concise commit message using conventional commit.
```sh
git add .
git commit -m "feat: add feature X"
```
6. **Push to your fork**: Push your changes to your forked repository.
```sh
git push origin feat/my-feature-branch
```
7. **Create a Pull Request**: Go to the original repository and create a pull request from your forked repository. Provide a clear description of your changes and the problem they solve.
## Code Style
- Follow the existing code style and conventions.
- Write clear and concise comments where necessary.
- Ensure your code is well-documented.
## Testing
- Write tests for any new features or bug fixes.
- Ensure all tests pass before submitting your pull request.
## Reporting Issues
If you find a bug or have a feature request, please create an issue on the GitHub repository. Provide as much detail as possible to help us understand and address the issue.
## Code of Conduct
Please note that this project is released with a Contributor Code of Conduct. By participating in this project, you agree to abide by its terms.
Thank you for contributing!

View File

@@ -7,9 +7,13 @@ ADD ntfy.py /
ADD ntfy_api.py /
ADD requirements.txt /
ADD entrypoint.sh /
ADD send_ntfy.py /
ADD send_gotify.py /
ADD send_discord.py /
ADD send_slack.py /
ADD index.html /var/www/html/index.html
ADD script.js /var/www/html/script.js
RUN apk add --no-cache sqlite-dev sqlite-libs gcc musl-dev nginx
RUN apk add --no-cache sqlite-dev sqlite-libs musl-dev nginx gcc
RUN pip install -r requirements.txt
RUN chmod 700 /entrypoint.sh
@@ -23,6 +27,8 @@ ENV USERNAME="" \
DOCKER_PASSWORD="" \
GOTIFY_URL="" \
GOTIFY_TOKEN="" \
DISCORD_WEBHOOK_URL="" \
SLACK_WEBHOOK_URL="" \
FLASK_ENV=production
# Exposer le port 5000 pour l'API et le port 80 pour le serveur web

View File

@@ -1,25 +1,26 @@
# ntfy_alerts
Personal ntfy alerts system
<h1 align="center">Welcome to ntfy_alerts 👋</h1>
<p>
<img alt="Version" src="https://img.shields.io/badge/version-1.5-blue.svg?cacheSeconds=2592000" />
<a href="#" target="_blank">
<img alt="License: GPL--3" src="https://img.shields.io/badge/License-GPL--3-yellow.svg" />
</a>
<a href="https://twitter.com/BreizhHardware" target="_blank">
<img alt="Twitter: BreizhHardware" src="https://img.shields.io/twitter/follow/BreizhHardware.svg?style=social" />
</a>
</p>
Feel free to contribute and to fork !
> This project allows you to receive notifications about new GitHub or Docker Hub releases on ntfy, gotify, and Discord.
# Python ntfy.py
## Description:
This script is used to watch the github repos and send a notification to the ntfy server when a new release is published.
## Installation
It can aloso watch Docker Hub repos and do the same as github.
## Utilisation:
auth and ntfy_url are required to be set as environment variables.
To install the dependencies, run:
```sh
pip install -r requirements.txt
```
auth: can be generataed by the folowing command: echo -n 'username:password' | base64
## Usage
ntfy_url: the url of the ntfy server including the topic
````python
python ntfy.py
````
## Docker:
If you want to use the docker image you can use the following docker-compose file for x86_64:
If you want to use the Docker image, you can use the following docker-compose file for x86_64:
````yaml
services:
github-ntfy:
@@ -35,6 +36,8 @@ services:
- DOCKER_PASSWORD= # Default is empty (Docker Hub password)
- GOTIFY_URL=gotify_url # Required if gotify is used
- GOTIFY_TOKEN= # Required if gotify is used
- DISCORD_WEBHOOK_URL= # Required if discord is used
- SLACK_WEBHOOK_URL= # Required if Slack is used
volumes:
- /path/to/github-ntfy:/github-ntfy/
ports:
@@ -57,6 +60,8 @@ services:
- DOCKER_PASSWORD= # Default is empty (Docker Hub password)
- GOTIFY_URL=gotify_url # Required if gotify is used
- GOTIFY_TOKEN= # Required if gotify is used
- DISCORD_WEBHOOK_URL= # Required if discord is used
- SLACK_WEBHOOK_URL= # Required if Slack is used
volumes:
- /path/to/github-ntfy:/github-ntfy/
ports:
@@ -79,15 +84,29 @@ services:
- DOCKER_PASSWORD= # Default is empty (Docker Hub password)
- GOTIFY_URL=gotify_url # Required if gotify is used
- GOTIFY_TOKEN= # Required if gotify is used
- DISCORD_WEBHOOK_URL= # Required if discord is used
- SLACK_WEBHOOK_URL= # Required if Slack is used
volumes:
- /path/to/github-ntfy:/github-ntfy/
ports:
- 80:80
restart: unless-stopped
````
GHNTFY_TOKEN, need to have repo, read:org and read:user
GHNTFY_TOKEN is a github token, it need to have repo, read:org and read:user
## Author
👤 **BreizhHardware**
* Website: https://mrqt.fr?ref=github
* Twitter: [@BreizhHardware](https://twitter.com/BreizhHardware)
* Github: [@BreizhHardware](https://github.com/BreizhHardware)
* LinkedIn: [@félix-marquet-5071bb167](https://linkedin.com/in/félix-marquet-5071bb167)
## Contribution
If you want to contribut, feel free to open a pull request, but first read the [contribution guide](CONTRIBUTION.md)!
Docker Hub repo: https://hub.docker.com/r/breizhhardware/github-ntfy
## TODO:
- [x] Dockerize the ntfy.py
- [x] Add the watched repos list as a parameter
@@ -96,36 +115,9 @@ Docker Hub repo: https://hub.docker.com/r/breizhhardware/github-ntfy
- [x] Add Docker Hub compatibility
- [ ] Rework of the web interface
- [x] Compatibility with Gotify
- [ ] Compatibility with Discord Webhook
- [x] Compatibility with Discord Webhook
- [x] Compatibility and distribution for arm64 and armv7
# Bash setup-notify.sh
## Description:
This script is used to setup the ntfy notification system on ssh login for a new server.
## Utilisation:
````bash
bash setup-notify.sh <ntfy_url> <username> <password> <topic>
````
ntfy_url: the url of the ntfy server
username: the username of the user
password: the password of the user
topic: the topic of the notification
This script will create a send-notify.sh in the root of your disk and add the login-notify.sh to the /etc/profile.d/ folder.
# Bash send-notify.sh
## Description:
This script is used to send a notification to the ntfy server.
## Utilisation:
````bash
bash send-notify.sh <ntfy_url> <basic_auth> <topic> <message>
````
ntfy_url: the url of the ntfy server
basic_auth: the basic auth of the user
topic: the topic of the notification
message: the message of the notification
## Show your support
Give a ⭐️ if this project helped you!

View File

@@ -3,74 +3,67 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Github-Ntfy Add a repo</title>
<title>Github-Ntfy Add a Repo</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="./script.js" defer></script>
</head>
<body class="bg-gradient-to-b from-stone-500 to-green-700">
<h1 class="text-4xl font-semibold leading-10 text-gray-900 text-center">Github-Ntfy</h1>
<div class="flex flex-row gap-2 justify-center items-center my-2 h-screen">
<div class="flex flex-col gap-2 justify-center items-center my-2 h-screen border-double border-2 border-white p-2" id="github">
<h1>Add a github repo</h1>
<form id="addRepoForm">
<div class="space-y-12">
<div class="border-b border-gray-900/10 pb-12">
<h2 class="text-base font-semibold leading-7 text-gray-900">Name of the github repo</h2>
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
<div class="sm:col-span-4">
<div class="mt-2">
<div class="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600 sm:max-w-md">
<span class="flex select-none items-center pl-3 sm:text-sm">github.com/</span>
<input type="text" name="repo" id="repo" autocomplete="repo" class="block flex-1 border-0 bg-transparent py-1.5 pl-1 placeholder:text-gray-600 focus:ring-0 sm:text-sm sm:leading-6" placeholder="BreizhHardware/ntfy_alerts">
</div>
</div>
</div>
</div>
</div>
<body class="bg-[#1b2124] text-gray-200">
<header class="text-center py-8 bg-[#23453d] shadow-lg">
<h1 class="text-5xl font-bold tracking-wide text-white">Github-Ntfy</h1>
</header>
<main class="flex flex-wrap justify-center gap-8 py-12">
<!-- Github Repo Section -->
<section class="bg-[#23453d] rounded-lg shadow-lg p-6 w-full max-w-lg">
<h2 class="text-2xl font-semibold mb-4">Add a Github Repo</h2>
<form id="addRepoForm" class="space-y-6">
<div>
<label for="repo" class="block text-sm font-medium">Name of the Github Repo</label>
<div class="mt-2 flex items-center border rounded-md bg-gray-700">
<span class="px-3 text-gray-400">github.com/</span>
<input type="text" name="repo" id="repo" autocomplete="repo" class="flex-1 py-2 px-3 bg-transparent focus:outline-none" placeholder="BreizhHardware/ntfy_alerts">
</div>
<div class="mt-6 flex items-center justify-end gap-x-6">
<button type="button" class="text-sm font-semibold leading-6 text-gray-900">Cancel</button>
<button type="submit" class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Save</button>
</div>
</form>
<div class="mt-8">
<h2 class="text-base font-semibold leading-7 text-gray-900">Watched Github Repositories</h2>
<ul id="watchedReposList" class="mt-4">
<!-- Dynamically populated with JavaScript -->
</ul>
</div>
</div>
<div class="flex flex-col gap-2 justify-center items-center my-2 h-screen border-double border-2 border-white p-2" id="docker">
<h1>Add a docker repo</h1>
<form id="addDockerRepoForm">
<div class="space-y-12">
<div class="border-b border-gray-900/10 pb-12">
<h2 class="text-base font-semibold leading-7 text-gray-900">Name of the docker repo</h2>
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
<div class="sm:col-span-4">
<div class="mt-2">
<div class="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600 sm:max-w-md">
<span class="flex select-none items-center pl-3 sm:text-sm">hub.docker.com/r/</span>
<input type="text" name="dockerRepo" id="dockerRepo" autocomplete="dockerRepo" class="block flex-1 border-0 bg-transparent py-1.5 pl-1 placeholder:text-gray-600 focus:ring-0 sm:text-sm sm:leading-6" placeholder="breizhhardware/github-ntfy">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="mt-6 flex items-center justify-end gap-x-6">
<button type="button" class="text-sm font-semibold leading-6 text-gray-900">Cancel</button>
<button type="submit" class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Save</button>
</div>
</form>
<div class="mt-8">
<h2 class="text-base font-semibold leading-7 text-gray-900">Watched Docker Repositories</h2>
<ul id="watchedDockerReposList" class="mt-4">
<!-- Dynamically populated with JavaScript -->
</ul>
<div class="flex justify-end gap-4">
<button type="button" class="px-4 py-2 text-gray-400 hover:text-white">Cancel</button>
<button type="submit" class="px-4 py-2 bg-green-700 hover:bg-green-600 text-white font-semibold rounded-md">Save</button>
</div>
</form>
<div class="mt-8">
<h3 class="text-lg font-semibold mb-2">Watched Github Repositories</h3>
<ul id="watchedReposList" class="space-y-2">
<!-- Dynamically populated with JavaScript -->
</ul>
</div>
</div>
<p class="font-semibold leading-10 text-gray-900 text-center">I know this web interface is awfull but I'm not a web designer ^^.</p>
</section>
<!-- Docker Repo Section -->
<section class="bg-[#23453d] rounded-lg shadow-lg p-6 w-full max-w-lg">
<h2 class="text-2xl font-semibold mb-4">Add a Docker Repo</h2>
<form id="addDockerRepoForm" class="space-y-6">
<div>
<label for="dockerRepo" class="block text-sm font-medium">Name of the Docker Repo</label>
<div class="mt-2 flex items-center border rounded-md bg-gray-700">
<span class="px-3 text-gray-400">hub.docker.com/r/</span>
<input type="text" name="dockerRepo" id="dockerRepo" autocomplete="dockerRepo" class="flex-1 py-2 px-3 bg-transparent focus:outline-none" placeholder="breizhhardware/github-ntfy">
</div>
</div>
<div class="flex justify-end gap-4">
<button type="button" class="px-4 py-2 text-gray-400 hover:text-white">Cancel</button>
<button type="submit" class="px-4 py-2 bg-green-700 hover:bg-green-600 text-white font-semibold rounded-md">Save</button>
</div>
</form>
<div class="mt-8">
<h3 class="text-lg font-semibold mb-2">Watched Docker Repositories</h3>
<ul id="watchedDockerReposList" class="space-y-2">
<!-- Dynamically populated with JavaScript -->
</ul>
</div>
</section>
</main>
<footer class="text-center py-6 bg-[#23453d]">
<p class="text-sm">I know this web interface is simple, but I'm improving!</p>
</footer>
</body>
</html>
</html>

67
ntfy.py
View File

@@ -5,6 +5,8 @@ import logging
import sqlite3
import subprocess
import json
import threading
from send_ntfy import (
github_send_to_ntfy,
docker_send_to_ntfy,
@@ -13,6 +15,15 @@ from send_gotify import (
github_send_to_gotify,
docker_send_to_gotify,
)
from send_discord import (
github_send_to_discord,
docker_send_to_discord,
)
from send_slack import (
github_send_to_slack,
docker_send_to_slack,
)
# Configuring the logger
logging.basicConfig(
@@ -29,9 +40,11 @@ if github_token:
docker_username = os.environ.get("DOCKER_USERNAME")
docker_password = os.environ.get("DOCKER_PASSWORD")
discord_webhook_url = os.environ.get("DISCORD_WEBHOOK_URL")
def create_dockerhub_token(username, password):
url = "https://hub.docker.com//v2/users/login"
url = "https://hub.docker.com/v2/users/login"
headers = {"Content-Type": "application/json"}
data = json.dumps({"username": username, "password": password})
@@ -169,6 +182,40 @@ def get_changelog(repo):
return latest_release_list["body"]
return "Changelog not available"
def notify_all_services(github_latest_release, docker_latest_release, auth, ntfy_url, gotify_url, gotify_token, discord_webhook_url, slack_webhook_url):
threads = []
if ntfy_url:
if github_latest_release:
threads.append(threading.Thread(target=github_send_to_ntfy, args=(github_latest_release, auth, ntfy_url)))
if docker_latest_release:
threads.append(threading.Thread(target=docker_send_to_ntfy, args=(docker_latest_release, auth, ntfy_url)))
if gotify_url and gotify_token:
if github_latest_release:
threads.append(threading.Thread(target=github_send_to_gotify, args=(github_latest_release, gotify_token, gotify_url)))
if docker_latest_release:
threads.append(threading.Thread(target=docker_send_to_gotify, args=(docker_latest_release, gotify_token, gotify_url)))
if discord_webhook_url:
if github_latest_release:
threads.append(threading.Thread(target=github_send_to_discord, args=(github_latest_release, discord_webhook_url)))
if docker_latest_release:
threads.append(threading.Thread(target=docker_send_to_discord, args=(docker_latest_release, discord_webhook_url)))
if slack_webhook_url:
if github_latest_release:
threads.append(threading.Thread(target=github_send_to_slack, args=(github_latest_release, slack_webhook_url)))
if docker_latest_release:
threads.append(threading.Thread(target=docker_send_to_slack, args=(docker_latest_release, slack_webhook_url)))
for thread in threads:
thread.start()
for thread in threads:
thread.join()
if __name__ == "__main__":
start_api()
@@ -177,27 +224,20 @@ if __name__ == "__main__":
ntfy_url = os.environ.get("NTFY_URL")
gotify_url = os.environ.get("GOTIFY_URL")
gotify_token = os.environ.get("GOTIFY_TOKEN")
discord_webhook_url = os.environ.get("DISCORD_WEBHOOK_URL")
timeout = float(os.environ.get("GHNTFY_TIMEOUT"))
slack_webhook_url = os.environ.get("SLACK_WEBHOOK_URL")
if auth and ntfy_url:
if auth and (ntfy_url or gotify_url or discord_webhook_url):
while True:
github_watched_repos_list = get_watched_repos()
github_latest_release = get_latest_releases(github_watched_repos_list)
docker_watched_repos_list = get_docker_watched_repos()
docker_latest_release = get_latest_docker_releases(docker_watched_repos_list)
if ntfy_url != "":
if github_latest_release:
github_send_to_ntfy(github_latest_release, auth, ntfy_url)
if docker_latest_release:
docker_send_to_ntfy(docker_latest_release, auth, ntfy_url)
if gotify_url != "" and gotify_token != "":
if github_latest_release:
github_send_to_gotify(github_latest_release, gotify_token, gotify_url)
if docker_latest_release:
docker_send_to_gotify(docker_latest_release, gotify_token, gotify_url)
notify_all_services(github_latest_release, docker_latest_release, auth, ntfy_url, gotify_url, gotify_token, discord_webhook_url, slack_webhook_url)
time.sleep(timeout) # Wait an hour before checking again
time.sleep(timeout)
else:
logger.error("Usage: python ntfy.py")
logger.error(
@@ -211,4 +251,5 @@ if __name__ == "__main__":
logger.error(
"GOTIFY_TOKEN: the token of the gotify server need to be stored in an environment variable named GOTIFY_TOKEN"
)
logger.error("DISCORD_WEBHOOK_URL: the webhook URL for Discord notifications need to be stored in an environment variable named DISCORD_WEBHOOK_URL")
logger.error("GHNTFY_TIMEOUT: the time interval between each check")

94
send_discord.py Normal file
View File

@@ -0,0 +1,94 @@
import requests
import sqlite3
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger(__name__)
def get_db_connection():
return sqlite3.connect("/github-ntfy/ghntfy_versions.db", check_same_thread=False)
def github_send_to_discord(releases, webhook_url):
conn = get_db_connection()
cursor = conn.cursor()
for release in releases:
app_name = release["repo"].split("/")[-1]
version_number = release["tag_name"]
app_url = release["html_url"]
changelog = release["changelog"]
release_date = release["published_at"].replace("T", " ").replace("Z", "")
cursor.execute("SELECT version FROM versions WHERE repo=?", (app_name,))
previous_version = cursor.fetchone()
if previous_version and previous_version[0] == version_number:
logger.info(f"The version of {app_name} has not changed. No notification sent.")
continue # Move on to the next application
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n📝 *Changelog*:\n\n```{changelog}```"
if len(message) > 2000:
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n🔗 *Release Link*: {app_url}"
# Updating the previous version for this application
cursor.execute(
"INSERT OR REPLACE INTO versions (repo, version, changelog) VALUES (?, ?, ?)",
(app_name, version_number, changelog),
)
conn.commit()
data = {
"content": message,
"username": "GitHub Ntfy"
}
headers = {
"Content-Type": "application/json"
}
response = requests.post(webhook_url, json=data, headers=headers)
if 200 <= response.status_code < 300:
logger.info(f"Message sent to Discord for {app_name}")
else:
logger.error(f"Failed to send message to Discord. Status code: {response.status_code}")
logger.error(f"Response: {response.text}")
conn.close()
def docker_send_to_discord(releases, webhook_url):
conn = get_db_connection()
cursor = conn.cursor()
for release in releases:
app_name = release["repo"].split("/")[-1]
digest_number = release["digest"]
app_url = release["html_url"]
release_date = release["published_at"].replace("T", " ").replace("Z", "")
cursor.execute("SELECT digest FROM docker_versions WHERE repo=?", (app_name,))
previous_digest = cursor.fetchone()
if previous_digest and previous_digest[0] == digest_number:
logger.info(f"The digest of {app_name} has not changed. No notification sent.")
continue
message = f"🐳 *Docker Image Updated!*\n\n🔐 *New Digest*: `{digest_number}`\n\n📦 *App*: {app_name}\n\n📢*Published*: {release_date}\n\n🔗 *Link*: {app_url}"
cursor.execute(
"INSERT OR REPLACE INTO docker_versions (repo, digest) VALUES (?, ?)",
(app_name, digest_number),
)
conn.commit()
data = {
"content": message,
"username": "GitHub Ntfy"
}
headers = {
"Content-Type": "application/json"
}
logger.info(f"Sending payload to Discord: {data}")
response = requests.post(webhook_url, json=data, headers=headers)
if 200 <= response.status_code < 300:
logger.info(f"Message sent to Discord for {app_name}")
else:
logger.error(f"Failed to send message to Discord. Status code: {response.status_code}")
logger.error(f"Response: {response.text}")
conn.close()

View File

@@ -2,20 +2,18 @@ import requests
import sqlite3
import logging
conn = sqlite3.connect(
"/github-ntfy/ghntfy_versions.db",
check_same_thread=False,
)
cursor = conn.cursor()
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger(__name__)
def get_db_connection():
return sqlite3.connect("/github-ntfy/ghntfy_versions.db", check_same_thread=False)
def github_send_to_gotify(releases, token, url):
conn = get_db_connection()
cursor = conn.cursor()
url = url + "/message"
url = url + "?token=" + token
for release in releases:
@@ -36,7 +34,7 @@ def github_send_to_gotify(releases, token, url):
logger.info(f"The version of {app_name} has not changed. No notification sent.")
continue # Move on to the next application
message = f"New version: {version_number}\nFor: {app_name}\nPublished on: {release_date}\nChangelog:\n{changelog}\n{app_url}"
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n📝 *Changelog*:\n\n```{changelog}```\n\n🔗 *Release Url*:{app_url}"
# Updating the previous version for this application
cursor.execute(
"INSERT OR REPLACE INTO versions (repo, version, changelog) VALUES (?, ?, ?)",
@@ -57,7 +55,9 @@ def github_send_to_gotify(releases, token, url):
logger.error(f"Failed to send message to Gotify. Status code: {response.status_code}")
def docker_send_to_ntfy(releases, token, url):
def docker_send_to_gotify(releases, token, url):
conn = get_db_connection()
cursor = conn.cursor()
url = url + "/message"
url = url + "?token=" + token
for release in releases:
@@ -77,7 +77,7 @@ def docker_send_to_ntfy(releases, token, url):
logger.info(f"The digest of {app_name} has not changed. No notification sent.")
continue # Move on to the next application
message = f"New version: {digest_number}\nFor: {app_name}\nPublished on: {release_date}\n{app_url}"
message = f"🐳 *Docker Image Updated!*\n\n🔐 *New Digest*: `{digest_number}`\n\n📦 *App*: {app_name}\n\n📢 *Published*: {release_date}\n\n🔗 *Release Url*:{app_url}"
# Updating the previous digest for this application
cursor.execute(
"INSERT OR REPLACE INTO docker_versions (repo, digest) VALUES (?, ?, ?)",

View File

@@ -2,20 +2,18 @@ import requests
import sqlite3
import logging
conn = sqlite3.connect(
"/github-ntfy/ghntfy_versions.db",
check_same_thread=False,
)
cursor = conn.cursor()
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger(__name__)
def get_db_connection():
return sqlite3.connect("/github-ntfy/ghntfy_versions.db", check_same_thread=False)
def github_send_to_ntfy(releases, auth, url):
conn = get_db_connection()
cursor = conn.cursor()
for release in releases:
app_name = release["repo"].split("/")[-1] # Getting the application name from the repo
version_number = release["tag_name"] # Getting the version number
@@ -34,7 +32,7 @@ def github_send_to_ntfy(releases, auth, url):
logger.info(f"The version of {app_name} has not changed. No notification sent.")
continue # Move on to the next application
message = f"New version: {version_number}\nFor: {app_name}\nPublished on: {release_date}\nChangelog:\n{changelog}\n{app_url}"
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n📝 *Changelog*:\n\n```{changelog}```\n\n 🔗 *Release Url*: {app_url}"
# Updating the previous version for this application
cursor.execute(
"INSERT OR REPLACE INTO versions (repo, version, changelog) VALUES (?, ?, ?)",
@@ -58,6 +56,8 @@ def github_send_to_ntfy(releases, auth, url):
def docker_send_to_ntfy(releases, auth, url):
conn = get_db_connection()
cursor = conn.cursor()
for release in releases:
app_name = release["repo"].split("/")[-1] # Getting the application name from the repo
digest_number = release["digest"]
@@ -75,7 +75,7 @@ def docker_send_to_ntfy(releases, auth, url):
logger.info(f"The digest of {app_name} has not changed. No notification sent.")
continue # Move on to the next application
message = f"New version: {digest_number}\nFor: {app_name}\nPublished on: {release_date}\n{app_url}"
message = f"🐳 *Docker Image Updated!*\n\n🔐 *New Digest*: `{digest_number}`\n\n📦 *App*: {app_name}\n\n📢*Published*: {release_date}\n\n 🔗 *Release Url*: {app_url}"
# Updating the previous digest for this application
cursor.execute(
"INSERT OR REPLACE INTO docker_versions (repo, digest) VALUES (?, ?, ?)",
@@ -85,10 +85,10 @@ def docker_send_to_ntfy(releases, auth, url):
headers = {
"Authorization": f"Basic {auth}",
"Title": f"New version for {app_name}",
"Title": f"🆕 New version for {app_name}",
"Priority": "urgent",
"Markdown": "yes",
"Actions": f"view, Update {app_name}, {app_url}, clear=true",
"Actions": f"View, Update {app_name}, {app_url}, clear=true",
}
response = requests.post(f"{url}", headers=headers, data=message)
if response.status_code == 200:

131
send_slack.py Normal file
View File

@@ -0,0 +1,131 @@
import requests
import sqlite3
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger(__name__)
def get_db_connection():
return sqlite3.connect("/github-ntfy/ghntfy_versions.db", check_same_thread=False)
def github_send_to_slack(releases, webhook_url):
conn = get_db_connection()
cursor = conn.cursor()
for release in releases:
app_name = release["repo"].split("/")[-1]
version_number = release["tag_name"]
app_url = release["html_url"]
changelog = release["changelog"]
release_date = release["published_at"].replace("T", " ").replace("Z", "")
cursor.execute("SELECT version FROM versions WHERE repo=?", (app_name,))
previous_version = cursor.fetchone()
if previous_version and previous_version[0] == version_number:
logger.info(f"The version of {app_name} has not changed. No notification sent.")
continue
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n📝 *Changelog*:\n\n```{changelog}```"
if len(message) > 2000:
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n📝 *Changelog*:\n\n `truncated..` use 🔗 instead "
cursor.execute(
"INSERT OR REPLACE INTO versions (repo, version, changelog) VALUES (?, ?, ?)",
(app_name, version_number, changelog),
)
conn.commit()
message = {
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"{message}"
},
"accessory": {
"type": "button",
"text": {
"type": "plain_text",
"text": "🔗 Release Url"
},
"url": f"{app_url}",
"action_id": "button-action"
}
},
{
"type": "divider"
}
]
}
headers = {
"Content-Type": "application/json"
}
response = requests.post(webhook_url, json=message, headers=headers)
if response.status_code == 200:
logger.info(f"Message sent to Slack for {app_name}")
else:
logger.error(f"Failed to send message to Slack. Status code: {response.status_code}")
logger.error(f"Response: {response.text}")
conn.close()
def docker_send_to_slack(releases, webhook_url):
conn = get_db_connection()
cursor = conn.cursor()
for release in releases:
app_name = release["repo"].split("/")[-1]
digest_number = release["digest"]
app_url = release["html_url"]
release_date = release["published_at"].replace("T", " ").replace("Z", "")
cursor.execute("SELECT digest FROM docker_versions WHERE repo=?", (app_name,))
previous_digest = cursor.fetchone()
if previous_digest and previous_digest[0] == digest_number:
logger.info(f"The digest of {app_name} has not changed. No notification sent.")
continue
message = f"🐳 *Docker Image Updated!*\n\n🔐 *New Digest*: `{digest_number}`\n\n📦 *App*: {app_name}\n\n📢*Published*: {release_date}"
cursor.execute(
"INSERT OR REPLACE INTO docker_versions (repo, digest) VALUES (?, ?)",
(app_name, digest_number),
)
conn.commit()
message = {
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"{message}"
},
"accessory": {
"type": "button",
"text": {
"type": "plain_text",
"text": "🔗 Release Url"
},
"url": f"{app_url}",
"action_id": "button-action"
}
},
{
"type": "divider"
}
]
}
headers = {
"Content-Type": "application/json"
}
response = requests.post(webhook_url, json=message, headers=headers)
if 200 <= response.status_code < 300:
logger.info(f"Message sent to Slack for {app_name}")
else:
logger.error(f"Failed to send message to Slack. Status code: {response.status_code}")
logger.error(f"Response: {response.text}")
conn.close()