Slack webhook for payout source threshold alerts (#4353)

* Slack webhook for payout alerts

* add PAYOUT_ALERT_SLACK_WEBHOOK to check_env_vars

* Fix commit

* Fix webhook format

* Add new env vars in .env.local

* Rename env vars, fire webhook on error

* Fix compilation

* Clippy

* Fix CI

* Add env vars to .env.docker-compose
This commit is contained in:
François-Xavier Talbot
2025-09-10 22:16:21 +01:00
committed by GitHub
parent af3b829449
commit 58aac642a9
11 changed files with 183 additions and 41 deletions

View File

@@ -178,7 +178,76 @@ async fn get_webhook_metadata(
}
}
pub async fn send_slack_webhook(
pub enum PayoutSourceAlertType {
UnderThreshold {
source: String,
threshold: u64,
current_balance: u64,
},
CheckFailure {
source: String,
display_error: String,
},
}
impl PayoutSourceAlertType {
pub fn message(&self) -> String {
match self {
PayoutSourceAlertType::UnderThreshold {
source,
threshold,
current_balance,
} => format!(
"\u{1f6a8} *Payout Source Alert*\n\nPayout source '{source}' has an available balance under the ${threshold} threshold.\nBalance: ${current_balance}."
),
PayoutSourceAlertType::CheckFailure {
source,
display_error,
} => format!(
"\u{1f6a8} *Payout Source Alert*\n\nFAILED TO CHECK payout source '{source}' balance.\nError: {display_error}"
),
}
}
}
pub async fn send_slack_payout_source_alert_webhook(
alert: PayoutSourceAlertType,
webhook_url: &str,
) -> Result<(), ApiError> {
let client = reqwest::Client::new();
client
.post(webhook_url)
.json(&serde_json::json!({
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": alert.message()
}
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": format!("via labrinth • <!date^{}^{{date_short_pretty}} at {{time}}|Unknown date>", Utc::now().timestamp())
}
]
}
],
}))
.send()
.await
.map_err(|_| {
ApiError::Slack("Error while sending projects webhook".to_string())
})?;
Ok(())
}
pub async fn send_slack_project_webhook(
project_id: ProjectId,
pool: &PgPool,
redis: &RedisPool,
@@ -288,7 +357,7 @@ pub async fn send_slack_webhook(
.send()
.await
.map_err(|_| {
ApiError::Discord(
ApiError::Slack(
"Error while sending projects webhook".to_string(),
)
})?;