///|
/// A webhook event is the immutable payload delivered to a Hook.
pub(all) struct WebhookEvent {
id : String
event_type : String
subject : String
payload : String
timestamp_ms : Int
idempotency_key : String
} derive(Eq, @debug.Debug)
///|
/// Constructs a `WebhookEvent` directly. Prefer `EventBuilder` for validation.
pub fn WebhookEvent::new(
id : String,
event_type : String,
subject : String,
payload : String,
timestamp_ms : Int,
idempotency_key : String,
) -> WebhookEvent {
{ id, event_type, subject, payload, timestamp_ms, idempotency_key, }
}
///|
/// Builder for `WebhookEvent` with validation in `build`.
pub(all) struct EventBuilder {
id : String
event_type : String
subject : String
payload : String
timestamp_ms : Int
idempotency_key : String
} derive(Eq, @debug.Debug)
///|
pub fn EventBuilder::new() -> EventBuilder {
{
id: "",
event_type: "",
subject: "",
payload: "{}",
timestamp_ms: 0,
idempotency_key: "",
}
}
///|
pub fn EventBuilder::with_id(self : EventBuilder, id : String) -> EventBuilder {
{
id,
event_type: self.event_type,
subject: self.subject,
payload: self.payload,
timestamp_ms: self.timestamp_ms,
idempotency_key: self.idempotency_key,
}
}
///|
pub fn EventBuilder::with_event_type(
self : EventBuilder,
event_type : String,
) -> EventBuilder {
{
id: self.id,
event_type,
subject: self.subject,
payload: self.payload,
timestamp_ms: self.timestamp_ms,
idempotency_key: self.idempotency_key,
}
}
///|
pub fn EventBuilder::with_subject(
self : EventBuilder,
subject : String,
) -> EventBuilder {
{
id: self.id,
event_type: self.event_type,
subject,
payload: self.payload,
timestamp_ms: self.timestamp_ms,
idempotency_key: self.idempotency_key,
}
}
///|
pub fn EventBuilder::with_payload(
self : EventBuilder,
payload : String,
) -> EventBuilder {
{
id: self.id,
event_type: self.event_type,
subject: self.subject,
payload,
timestamp_ms: self.timestamp_ms,
idempotency_key: self.idempotency_key,
}
}
///|
pub fn EventBuilder::with_timestamp_ms(
self : EventBuilder,
timestamp_ms : Int,
) -> EventBuilder {
{
id: self.id,
event_type: self.event_type,
subject: self.subject,
payload: self.payload,
timestamp_ms,
idempotency_key: self.idempotency_key,
}
}
///|
pub fn EventBuilder::with_idempotency_key(
self : EventBuilder,
idempotency_key : String,
) -> EventBuilder {
{
id: self.id,
event_type: self.event_type,
subject: self.subject,
payload: self.payload,
timestamp_ms: self.timestamp_ms,
idempotency_key,
}
}
///|
/// Validates required fields and falls back to a deterministic
/// idempotency key based on event id and type.
pub fn EventBuilder::build(self : EventBuilder) -> Result[WebhookEvent, String] {
if self.id == "" {
Err("event id is required")
} else if self.event_type == "" {
Err("event type is required")
} else {
let key = if self.idempotency_key == "" {
self.id + ":" + self.event_type
} else {
self.idempotency_key
}
Ok(
WebhookEvent::new(
self.id,
self.event_type,
self.subject,
self.payload,
self.timestamp_ms,
key,
),
)
}
}