Add register notification webhook (#764)
I find it super motivating when people use my stuff, so this makes it _even easier_ to know when someone new signs up!
This commit is contained in:
parent
ca5bbea0d4
commit
b978f9a4de
4 changed files with 49 additions and 3 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -169,6 +169,7 @@ dependencies = [
|
|||
"fs-err",
|
||||
"http",
|
||||
"rand",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sodiumoxide",
|
||||
|
|
|
@ -35,3 +35,7 @@ fs-err = "2.9"
|
|||
chronoutil = "0.2.3"
|
||||
tower = "0.4"
|
||||
tower-http = { version = "0.3", features = ["trace"] }
|
||||
reqwest = { version = "0.11", features = [
|
||||
"json",
|
||||
"rustls-tls-native-roots",
|
||||
], default-features = false }
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use std::borrow::Borrow;
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
|
||||
use axum::{
|
||||
extract::{Path, State},
|
||||
|
@ -6,7 +8,7 @@ use axum::{
|
|||
};
|
||||
use http::StatusCode;
|
||||
use sodiumoxide::crypto::pwhash::argon2id13;
|
||||
use tracing::{debug, error, instrument};
|
||||
use tracing::{debug, error, info, instrument};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{ErrorResponse, ErrorResponseStatus, RespExt};
|
||||
|
@ -16,6 +18,8 @@ use crate::{
|
|||
router::AppState,
|
||||
};
|
||||
|
||||
use reqwest::header::CONTENT_TYPE;
|
||||
|
||||
use atuin_common::api::*;
|
||||
|
||||
pub fn verify_str(secret: &str, verify: &str) -> bool {
|
||||
|
@ -32,6 +36,30 @@ pub fn verify_str(secret: &str, verify: &str) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
// Try to send a Discord webhook once - if it fails, we don't retry. "At most once", and best effort.
|
||||
// Don't return the status because if this fails, we don't really care.
|
||||
async fn send_register_hook(url: &str, username: String, registered: String) {
|
||||
let hook = HashMap::from([
|
||||
("username", username),
|
||||
("content", format!("{registered} has just signed up!")),
|
||||
]);
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
let resp = client
|
||||
.post(url)
|
||||
.timeout(Duration::new(5, 0))
|
||||
.header(CONTENT_TYPE, "application/json")
|
||||
.json(&hook)
|
||||
.send()
|
||||
.await;
|
||||
|
||||
match resp {
|
||||
Ok(_) => info!("register webhook sent ok!"),
|
||||
Err(e) => error!("failed to send register webhook: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip_all, fields(user.username = username.as_str()))]
|
||||
pub async fn get<DB: Database>(
|
||||
Path(username): Path<String>,
|
||||
|
@ -71,8 +99,8 @@ pub async fn register<DB: Database>(
|
|||
let hashed = hash_secret(®ister.password);
|
||||
|
||||
let new_user = NewUser {
|
||||
email: register.email,
|
||||
username: register.username,
|
||||
email: register.email.clone(),
|
||||
username: register.username.clone(),
|
||||
password: hashed,
|
||||
};
|
||||
|
||||
|
@ -94,6 +122,16 @@ pub async fn register<DB: Database>(
|
|||
token: (&token).into(),
|
||||
};
|
||||
|
||||
if let Some(url) = &state.settings.register_webhook_url {
|
||||
// Could probs be run on another thread, but it's ok atm
|
||||
send_register_hook(
|
||||
url,
|
||||
state.settings.register_webhook_username.clone(),
|
||||
register.username,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
match db.add_session(&new_session).await {
|
||||
Ok(_) => Ok(Json(RegisterResponse { session: token })),
|
||||
Err(e) => {
|
||||
|
|
|
@ -15,6 +15,8 @@ pub struct Settings {
|
|||
pub db_uri: String,
|
||||
pub open_registration: bool,
|
||||
pub max_history_length: usize,
|
||||
pub register_webhook_url: Option<String>,
|
||||
pub register_webhook_username: String,
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
|
@ -37,6 +39,7 @@ impl Settings {
|
|||
.set_default("open_registration", false)?
|
||||
.set_default("max_history_length", 8192)?
|
||||
.set_default("path", "")?
|
||||
.set_default("register_webhook_username", "")?
|
||||
.add_source(
|
||||
Environment::with_prefix("atuin")
|
||||
.prefix_separator("_")
|
||||
|
|
Loading…
Reference in a new issue