use std::net::SocketAddr; use actix::prelude::*; use tracing::{info, warn}; use crate::actors::webhook::message::WebhookMessage; pub async fn start( socket_addr: SocketAddr, address: actix::prelude::Recipient, ) { // start webhook server use warp::Filter; // Define the Warp route to handle incoming HTTP requests let route = warp::post() .map(move || address.clone()) .and(warp::path::param()) // .and(warp::query::raw()) .and(warp::header::headers_cloned()) .and(warp::body::bytes()) .and_then( |recipient: Recipient, path, // query: String, headers: warp::http::HeaderMap, body: bytes::Bytes| async move { info!("POST received"); let bytes = body.to_vec(); let request_data = String::from_utf8_lossy(&bytes).to_string(); let id = ulid::Ulid::new().to_string(); match headers.get("Authorization") { Some(auhorisation) => { info!(id, path, "Received webhook"); let authorisation = auhorisation .to_str() .map_err(|e| { warn!("Invalid value in authorization: {:?}", e); warp::reject() })? // valid characters .strip_prefix("Basic ") .ok_or_else(|| { warn!("Authorization must be 'Basic'"); warp::reject() })? // must start with "Basic " .to_string(); let message = WebhookMessage::new( id, path, /* query, headers, */ request_data, authorisation, ); recipient .try_send(message) .map(|_| { info!("Message sent ok"); warp::reply::with_status("OK", warp::http::StatusCode::OK) }) .map_err(|e| { warn!("Unknown error: {:?}", e); warp::reject() }) } _ => { warn!("No Authorization header"); Err(warp::reject()) } } }, ); // Start the server info!("Starting webhook server: {}", socket_addr); warp::serve(route).run(socket_addr).await; }