rust_woocommerce/controllers/
webhooks.rs

1use anyhow::{anyhow, Result};
2use serde::{Deserialize, Serialize};
3use serde_with::skip_serializing_none;
4
5use crate::{Event, Resource, WebhookStatus};
6#[skip_serializing_none]
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct WebhookCreate {
9    name: Option<String>,
10    status: Option<WebhookStatus>,
11    topic: String,
12    delivery_url: String,
13    secret: Option<String>,
14}
15#[derive(Default)]
16pub struct WebhookCreateBuilder<R, E, D> {
17    name: Option<String>,
18    status: Option<WebhookStatus>,
19    resource: R,
20    event: E,
21    delivery_url: D,
22    secret: Option<String>,
23}
24pub struct WithResource(Resource);
25pub struct WithEvent(Event);
26pub struct WithUrl(String);
27impl<R, E, D> WebhookCreateBuilder<R, E, D> {
28    /// A friendly name for the webhook.
29    pub fn name(mut self, name: impl Into<String>) -> Self {
30        let _ = self.name.insert(name.into());
31        self
32    }
33    /// Webhook status. Options: active, paused and disabled. Default is active.
34    pub fn status(mut self, status: WebhookStatus) -> Self {
35        let _ = self.status.insert(status);
36        self
37    }
38    /// Webhook resource.
39    pub fn resource(self, resource: Resource) -> WebhookCreateBuilder<WithResource, E, D> {
40        WebhookCreateBuilder {
41            name: self.name,
42            status: self.status,
43            resource: WithResource(resource),
44            event: self.event,
45            delivery_url: self.delivery_url,
46            secret: self.secret,
47        }
48    }
49    /// Webhook event.
50    pub fn event(self, event: Event) -> WebhookCreateBuilder<R, WithEvent, D> {
51        WebhookCreateBuilder {
52            name: self.name,
53            status: self.status,
54            resource: self.resource,
55            event: WithEvent(event),
56            delivery_url: self.delivery_url,
57            secret: self.secret,
58        }
59    }
60    /// The URL where the webhook payload is delivered.
61    pub fn delivery_url(self, url: impl Into<String>) -> WebhookCreateBuilder<R, E, WithUrl> {
62        WebhookCreateBuilder {
63            name: self.name,
64            status: self.status,
65            resource: self.resource,
66            event: self.event,
67            delivery_url: WithUrl(url.into()),
68            secret: self.secret,
69        }
70    }
71    /// Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default is a MD5 hash from the current user's ID
72    pub fn secret(mut self, secret: impl Into<String>) -> Self {
73        let _ = self.secret.insert(secret.into());
74        self
75    }
76}
77impl WebhookCreateBuilder<WithResource, WithEvent, WithUrl> {
78    pub fn build(self) -> WebhookCreate {
79        let topic = format!("{}.{}", self.resource.0, self.event.0);
80        WebhookCreate {
81            name: self.name,
82            status: self.status,
83            topic,
84            delivery_url: self.delivery_url.0,
85            secret: self.secret,
86        }
87    }
88}
89#[skip_serializing_none]
90#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct WebhookUpdate {
92    id: Option<i32>,
93    name: Option<String>,
94    status: Option<WebhookStatus>,
95    topic: Option<String>,
96    delivery_url: Option<String>,
97    secret: Option<String>,
98}
99#[derive(Default)]
100pub struct WebhookUpdateBuilder {
101    id: Option<i32>,
102    name: Option<String>,
103    status: Option<WebhookStatus>,
104    resource: Option<Resource>,
105    event: Option<Event>,
106    delivery_url: Option<String>,
107    secret: Option<String>,
108}
109impl WebhookUpdateBuilder {
110    /// Unique identifier for the resource.
111    pub fn id(mut self, id: i32) -> Self {
112        let _ = self.id.insert(id);
113        self
114    }
115    /// A friendly name for the webhook.
116    pub fn name(mut self, name: impl Into<String>) -> Self {
117        let _ = self.name.insert(name.into());
118        self
119    }
120    /// Webhook status. Options: active, paused and disabled. Default is active.
121    pub fn status(mut self, status: WebhookStatus) -> Self {
122        let _ = self.status.insert(status);
123        self
124    }
125    /// Webhook resource.
126    pub fn resource(mut self, resource: Resource) -> Self {
127        let _ = self.resource.insert(resource);
128        self
129    }
130    /// Webhook event.
131    pub fn event(mut self, event: Event) -> Self {
132        let _ = self.event.insert(event);
133        self
134    }
135    /// The URL where the webhook payload is delivered.
136    pub fn delivery_url(mut self, url: impl Into<String>) -> Self {
137        let _ = self.delivery_url.insert(url.into());
138        self
139    }
140    /// Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default is a MD5 hash from the current user's ID
141    pub fn secret(mut self, secret: impl Into<String>) -> Self {
142        let _ = self.secret.insert(secret.into());
143        self
144    }
145    pub fn build(self) -> Result<WebhookUpdate> {
146        if let Some(resource) = self.resource {
147            let Some(event) = self.event else {
148                return Err(anyhow!("resource set, but event not set!"));
149            };
150            let topic = Some(format!("{resource}.{event}"));
151            Ok(WebhookUpdate {
152                id: self.id,
153                name: self.name,
154                status: self.status,
155                topic,
156                delivery_url: self.delivery_url,
157                secret: self.secret,
158            })
159        } else {
160            Ok(WebhookUpdate {
161                id: self.id,
162                name: self.name,
163                status: self.status,
164                topic: None,
165                delivery_url: self.delivery_url,
166                secret: self.secret,
167            })
168        }
169    }
170}