Skip to main content

core_api/
webhook.rs

1//! Transport-neutral webhook body contract shared by desktop and embedded hosts.
2use crate::{ErrorResponse, ExceptionCode};
3use serde_json::Value;
4
5pub const GENERAL_WEBHOOK_ROUTE: &str = "/webhook/general/{endpoint_id}";
6pub const MAX_WEBHOOK_BODY_BYTES: usize = 1024 * 1024;
7
8pub fn decode_body(content_type: &str, body: &[u8]) -> Result<Value, ErrorResponse> {
9    let media_type = content_type
10        .split(';')
11        .next()
12        .unwrap_or("")
13        .trim()
14        .to_ascii_lowercase();
15    let is_json = media_type == "application/json"
16        || (media_type.starts_with("application/") && media_type.ends_with("+json"));
17    if is_json {
18        serde_json::from_slice(body).map_err(|error| {
19            ErrorResponse::new(
20                ExceptionCode::BadRequest,
21                format!("Invalid webhook JSON: {error}"),
22            )
23        })
24    } else {
25        std::str::from_utf8(body)
26            .map(|text| Value::String(text.to_owned()))
27            .map_err(|_| {
28                ErrorResponse::new(ExceptionCode::BadRequest, "Webhook body must be UTF-8 text")
29            })
30    }
31}