mirror of
https://github.com/BreizhHardware/ntfy_alerts.git
synced 2026-03-18 21:40:38 +01:00
refactor(rust): update notification functions and improve database handling
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -399,7 +399,7 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "github-ntfy"
|
||||
version = "0.1.0"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"dotenv",
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
use log::info;
|
||||
use rusqlite::{Connection, Result as SqliteResult};
|
||||
use rusqlite::{Connection, Result as SqliteResult, OpenFlags};
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn init_databases() -> SqliteResult<(Connection, Connection)> {
|
||||
let db_path = env::var("DB_PATH").unwrap_or_else(|_| "/github-ntfy".to_string());
|
||||
std::fs::create_dir_all(&db_path).ok();
|
||||
|
||||
if let Err(e) = std::fs::create_dir_all(&db_path) {
|
||||
info!("Error while creating directory {}: {}", db_path, e);
|
||||
}
|
||||
|
||||
let versions_path = format!("{}/ghntfy_versions.db", db_path);
|
||||
let repos_path = format!("{}/watched_repos.db", db_path);
|
||||
|
||||
let conn = Connection::open(&versions_path)?;
|
||||
let conn = Connection::open_with_flags(&versions_path, OpenFlags::SQLITE_OPEN_CREATE | OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_URI)?;
|
||||
|
||||
info!("Database open at {}", versions_path);
|
||||
|
||||
conn.execute(
|
||||
"CREATE TABLE IF NOT EXISTS versions (
|
||||
@@ -28,7 +34,9 @@ pub fn init_databases() -> SqliteResult<(Connection, Connection)> {
|
||||
[],
|
||||
)?;
|
||||
|
||||
let conn2 = Connection::open(&repos_path)?;
|
||||
let conn2 = Connection::open_with_flags(&repos_path, OpenFlags::SQLITE_OPEN_CREATE | OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_URI)?;
|
||||
|
||||
info!("Database open at {}", repos_path);
|
||||
|
||||
conn2.execute(
|
||||
"CREATE TABLE IF NOT EXISTS watched_repos (
|
||||
|
||||
@@ -1,78 +1,85 @@
|
||||
use log::{error, info};
|
||||
use serde_json::json;
|
||||
use reqwest::header::HeaderMap;
|
||||
use crate::models::{GithubReleaseInfo, DockerReleaseInfo};
|
||||
|
||||
pub async fn send_github_notification(release: &GithubReleaseInfo, token: &str, gotify_url: &str) {
|
||||
pub async fn send_github_notification(release: &GithubReleaseInfo, webhook_url: &str) {
|
||||
let client = reqwest::Client::new();
|
||||
let app_name = release.repo.split('/').last().unwrap_or(&release.repo);
|
||||
|
||||
let url = format!("{}/message?token={}", gotify_url, token);
|
||||
|
||||
let message = format!(
|
||||
"📌 *New version*: {}\n\n📦*For*: {}\n\n📅 *Published on*: {}\n\n📝 *Changelog*:\n\n```{}```\n\n🔗 *Release Url*:{}",
|
||||
let mut message = format!(
|
||||
"📌 *New version*: {}\n\n📦*For*: {}\n\n📅 *Published on*: {}\n\n📝 *Changelog*:\n\n```{}```",
|
||||
release.tag_name,
|
||||
app_name,
|
||||
release.published_at.replace("T", " ").replace("Z", ""),
|
||||
release.changelog,
|
||||
release.html_url
|
||||
release.changelog
|
||||
);
|
||||
|
||||
let content = json!({
|
||||
"title": format!("New version for {}", app_name),
|
||||
"message": message,
|
||||
"priority": "2"
|
||||
if message.len() > 2000 {
|
||||
message = format!(
|
||||
"📌 *New version*: {}\n\n📦*For*: {}\n\n📅 *Published on*: {}\n\n🔗 *Release Link*: {}",
|
||||
release.tag_name,
|
||||
app_name,
|
||||
release.published_at.replace("T", " ").replace("Z", ""),
|
||||
release.html_url
|
||||
);
|
||||
}
|
||||
|
||||
let data = json!({
|
||||
"content": message,
|
||||
"username": "GitHub Ntfy"
|
||||
});
|
||||
|
||||
match client.post(&url)
|
||||
.json(&content)
|
||||
let headers = HeaderMap::new();
|
||||
|
||||
match client.post(webhook_url)
|
||||
.headers(headers)
|
||||
.json(&data)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(response) if response.status().is_success() => {
|
||||
info!("Message sent to Gotify for {}", app_name);
|
||||
info!("Message sent to Discord for {}", app_name);
|
||||
},
|
||||
Ok(response) => {
|
||||
error!("Failed to send message to Gotify. Status code: {}", response.status());
|
||||
error!("Failed to send message to Discord. Status code: {}", response.status());
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Error sending to Gotify: {}", e);
|
||||
error!("Error sending to Discord: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_docker_notification(release: &DockerReleaseInfo, token: &str, gotify_url: &str) {
|
||||
pub async fn send_docker_notification(release: &DockerReleaseInfo, webhook_url: &str) {
|
||||
let client = reqwest::Client::new();
|
||||
let app_name = release.repo.split('/').last().unwrap_or(&release.repo);
|
||||
|
||||
let url = format!("{}/message?token={}", gotify_url, token);
|
||||
|
||||
let message = format!(
|
||||
"🐳 *Docker Image Updated!*\n\n🔐 *New Digest*: `{}`\n\n📦 *App*: {}\n\n📢 *Published*: {}\n\n🔗 *Release Url*:{}",
|
||||
"🐳 *Docker Image Updated!*\n\n🔐 *New Digest*: `{}`\n\n📦 *App*: {}\n\n📢 *Published*: {}\n\n🔗 *Link*: {}",
|
||||
release.digest,
|
||||
app_name,
|
||||
release.published_at.replace("T", " ").replace("Z", ""),
|
||||
release.html_url
|
||||
);
|
||||
|
||||
let content = json!({
|
||||
"title": format!("New version for {}", app_name),
|
||||
"message": message,
|
||||
"priority": "2"
|
||||
let data = json!({
|
||||
"content": message,
|
||||
"username": "GitHub Ntfy"
|
||||
});
|
||||
|
||||
match client.post(&url)
|
||||
.json(&content)
|
||||
match client.post(webhook_url)
|
||||
.json(&data)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(response) if response.status().is_success() => {
|
||||
info!("Message sent to Gotify for {}", app_name);
|
||||
info!("Message sent to Discord for {}", app_name);
|
||||
},
|
||||
Ok(response) => {
|
||||
error!("Failed to send message to Gotify. Status code: {}", response.status());
|
||||
error!("Failed to send message to Discord. Status code: {}", response.status());
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Error sending to Gotify: {}", e);
|
||||
error!("Error sending to Discord: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,22 @@ use crate::models::DockerReleaseInfo;
|
||||
use crate::config::Config;
|
||||
use crate::notifications::{ntfy, gotify, discord, slack};
|
||||
|
||||
pub async fn send_to_ntfy(release: DockerReleaseInfo, auth: &str, ntfy_url: &str) {
|
||||
ntfy::send_docker_notification(&release, auth, ntfy_url).await;
|
||||
}
|
||||
|
||||
pub async fn send_to_gotify(release: DockerReleaseInfo, token: &str, gotify_url: &str) {
|
||||
gotify::send_docker_notification(&release, token, gotify_url).await;
|
||||
}
|
||||
|
||||
pub async fn send_to_discord(release: DockerReleaseInfo, webhook_url: &str) {
|
||||
discord::send_docker_notification(&release, webhook_url).await;
|
||||
}
|
||||
|
||||
pub async fn send_to_slack(release: DockerReleaseInfo, webhook_url: &str) {
|
||||
slack::send_docker_notification(&release, webhook_url).await;
|
||||
}
|
||||
|
||||
pub async fn send_notifications(releases: &[DockerReleaseInfo], config: &Config) {
|
||||
let mut tasks = Vec::new();
|
||||
|
||||
@@ -13,7 +29,7 @@ pub async fn send_notifications(releases: &[DockerReleaseInfo], config: &Config)
|
||||
let auth = config.auth.clone();
|
||||
let url_clone = url.clone();
|
||||
tasks.push(task::spawn(async move {
|
||||
ntfy::send_docker_notification(&release_clone, &auth, &url_clone).await;
|
||||
send_to_ntfy(release_clone, &auth, &url_clone).await;
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -23,7 +39,7 @@ pub async fn send_notifications(releases: &[DockerReleaseInfo], config: &Config)
|
||||
let token = gotify_token.clone();
|
||||
let url = gotify_url.clone();
|
||||
tasks.push(task::spawn(async move {
|
||||
gotify::send_docker_notification(&release_clone, &token, &url).await;
|
||||
send_to_gotify(release_clone, &token, &url).await;
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -32,7 +48,7 @@ pub async fn send_notifications(releases: &[DockerReleaseInfo], config: &Config)
|
||||
let release_clone = release.clone();
|
||||
let url = discord_url.clone();
|
||||
tasks.push(task::spawn(async move {
|
||||
discord::send_docker_notification(&release_clone, &url).await;
|
||||
send_to_discord(release_clone, &url).await;
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -41,7 +57,7 @@ pub async fn send_notifications(releases: &[DockerReleaseInfo], config: &Config)
|
||||
let release_clone = release.clone();
|
||||
let url = slack_url.clone();
|
||||
tasks.push(task::spawn(async move {
|
||||
slack::send_docker_notification(&release_clone, &url).await;
|
||||
send_to_slack(release_clone, &url).await;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,133 +1,69 @@
|
||||
use log::{error, info};
|
||||
use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
|
||||
use serde_json::json;
|
||||
use tokio::task;
|
||||
use crate::models::GithubReleaseInfo;
|
||||
use crate::config::Config;
|
||||
use crate::notifications::{ntfy, gotify, discord, slack};
|
||||
|
||||
pub async fn send_to_ntfy(release: GithubReleaseInfo, auth: &str, ntfy_url: &str) {
|
||||
let client = reqwest::Client::new();
|
||||
let app_name = release.repo.split('/').last().unwrap_or(&release.repo);
|
||||
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert("Title", HeaderValue::from_str(&format!("New version for {}", app_name))
|
||||
.unwrap_or_else(|_| HeaderValue::from_static("")));
|
||||
headers.insert("Priority", HeaderValue::from_static("urgent"));
|
||||
headers.insert("Markdown", HeaderValue::from_static("yes"));
|
||||
headers.insert("Actions", HeaderValue::from_str(&format!("view, Update {}, {}, clear=true", app_name, release.html_url))
|
||||
.unwrap_or_else(|_| HeaderValue::from_static("")));
|
||||
|
||||
let message = format!(
|
||||
"📌 *New version*: {}\n\n📦*For*: {}\n\n📅 *Published on*: {}\n\n📝 *Changelog*:\n\n```{}```\n\n 🔗 *Release Url*: {}",
|
||||
release.tag_name,
|
||||
app_name,
|
||||
release.published_at.replace("T", " ").replace("Z", ""),
|
||||
release.changelog,
|
||||
release.html_url
|
||||
);
|
||||
|
||||
match client.post(ntfy_url)
|
||||
.headers(headers)
|
||||
.body(message)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(response) if response.status().is_success() => {
|
||||
info!("Message sent to Ntfy for {}", app_name);
|
||||
},
|
||||
Ok(response) => {
|
||||
error!("Failed to send message to Ntfy. Status code: {}", response.status());
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Error sending to Ntfy: {}", e);
|
||||
}
|
||||
}
|
||||
ntfy::send_github_notification(&release, auth, ntfy_url).await;
|
||||
}
|
||||
|
||||
pub async fn send_to_gotify(release: GithubReleaseInfo, token: &str, gotify_url: &str) {
|
||||
let client = reqwest::Client::new();
|
||||
let app_name = release.repo.split('/').last().unwrap_or(&release.repo);
|
||||
|
||||
let url = format!("{}/message?token={}", gotify_url, token);
|
||||
|
||||
let message = format!(
|
||||
"📌 *New version*: {}\n\n📦*For*: {}\n\n📅 *Published on*: {}\n\n📝 *Changelog*:\n\n```{}```\n\n🔗 *Release Url*:{}",
|
||||
release.tag_name,
|
||||
app_name,
|
||||
release.published_at.replace("T", " ").replace("Z", ""),
|
||||
release.changelog,
|
||||
release.html_url
|
||||
);
|
||||
|
||||
let content = json!({
|
||||
"title": format!("New version for {}", app_name),
|
||||
"message": message,
|
||||
"priority": "2"
|
||||
});
|
||||
|
||||
match client.post(&url)
|
||||
.json(&content)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(response) if response.status().is_success() => {
|
||||
info!("Message sent to Gotify for {}", app_name);
|
||||
},
|
||||
Ok(response) => {
|
||||
error!("Failed to send message to Gotify. Status code: {}", response.status());
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Error sending to Gotify: {}", e);
|
||||
}
|
||||
}
|
||||
gotify::send_github_notification(&release, token, gotify_url).await;
|
||||
}
|
||||
|
||||
pub async fn send_to_discord(release: GithubReleaseInfo, webhook_url: &str) {
|
||||
let client = reqwest::Client::new();
|
||||
let app_name = release.repo.split('/').last().unwrap_or(&release.repo);
|
||||
|
||||
let mut message = format!(
|
||||
"📌 *New version*: {}\n\n📦*For*: {}\n\n📅 *Published on*: {}\n\n📝 *Changelog*:\n\n```{}```",
|
||||
release.tag_name,
|
||||
app_name,
|
||||
release.published_at.replace("T", " ").replace("Z", ""),
|
||||
release.changelog
|
||||
);
|
||||
|
||||
if message.len() > 2000 {
|
||||
message = format!(
|
||||
"📌 *New version*: {}\n\n📦*For*: {}\n\n📅 *Published on*: {}\n\n🔗 *Release Link*: {}",
|
||||
release.tag_name,
|
||||
app_name,
|
||||
release.published_at.replace("T", " ").replace("Z", ""),
|
||||
release.html_url
|
||||
);
|
||||
}
|
||||
|
||||
let data = json!({
|
||||
"content": message,
|
||||
"username": "GitHub Ntfy"
|
||||
});
|
||||
|
||||
let headers = HeaderMap::new();
|
||||
|
||||
match client.post(webhook_url)
|
||||
.headers(headers)
|
||||
.json(&data)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(response) if response.status().is_success() => {
|
||||
info!("Message sent to Discord for {}", app_name);
|
||||
},
|
||||
Ok(response) => {
|
||||
error!("Failed to send message to Discord. Status code: {}", response.status());
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Error sending to Discord: {}", e);
|
||||
}
|
||||
}
|
||||
discord::send_github_notification(&release, webhook_url).await;
|
||||
}
|
||||
|
||||
pub async fn send_to_slack(release: GithubReleaseInfo, webhook_url: &str) {
|
||||
// Implémentation pour Slack similaire à celle pour Discord
|
||||
// ...
|
||||
slack::send_github_notification(&release, webhook_url).await;
|
||||
}
|
||||
|
||||
pub async fn send_notifications(releases: &[GithubReleaseInfo], config: &Config) {
|
||||
let mut tasks = Vec::new();
|
||||
|
||||
for release in releases {
|
||||
// Send to Ntfy
|
||||
if let Some(url) = &config.ntfy_url {
|
||||
let release_clone = release.clone();
|
||||
let auth = config.auth.clone();
|
||||
let url_clone = url.clone();
|
||||
tasks.push(task::spawn(async move {
|
||||
send_to_ntfy(release_clone, &auth, &url_clone).await;
|
||||
}));
|
||||
}
|
||||
|
||||
// Send to Gotify
|
||||
if let (Some(gotify_url), Some(gotify_token)) = (&config.gotify_url, &config.gotify_token) {
|
||||
let release_clone = release.clone();
|
||||
let token = gotify_token.clone();
|
||||
let url = gotify_url.clone();
|
||||
tasks.push(task::spawn(async move {
|
||||
send_to_gotify(release_clone, &token, &url).await;
|
||||
}));
|
||||
}
|
||||
|
||||
// Send to Discord
|
||||
if let Some(discord_url) = &config.discord_webhook_url {
|
||||
let release_clone = release.clone();
|
||||
let url = discord_url.clone();
|
||||
tasks.push(task::spawn(async move {
|
||||
send_to_discord(release_clone, &url).await;
|
||||
}));
|
||||
}
|
||||
|
||||
// Send to Slack
|
||||
if let Some(slack_url) = &config.slack_webhook_url {
|
||||
let release_clone = release.clone();
|
||||
let url = slack_url.clone();
|
||||
tasks.push(task::spawn(async move {
|
||||
send_to_slack(release_clone, &url).await;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for all tasks to complete
|
||||
for task in tasks {
|
||||
let _ = task.await;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user