shopify_client/webhooks/
mod.rs1pub mod types;
2
3use serde_json::Value;
4use types::{
5 CustomersDataRequestPayload, CustomersRedactPayload, ShopRedactPayload, WebhookParseError,
6 WebhookPayload,
7};
8
9pub enum WebhookTopic {
10 CustomersDataRequest,
11 CustomersRedact,
12 ShopRedact,
13}
14
15impl WebhookTopic {
16 pub fn from_header(header: &str) -> Option<Self> {
17 match header.to_lowercase().as_str() {
18 "customers/data_request" => Some(WebhookTopic::CustomersDataRequest),
19 "customers/redact" => Some(WebhookTopic::CustomersRedact),
20 "shop/redact" => Some(WebhookTopic::ShopRedact),
21 _ => None,
22 }
23 }
24}
25
26pub fn parse_webhook(
27 topic: WebhookTopic,
28 payload: &str,
29) -> Result<WebhookPayload, WebhookParseError> {
30 match topic {
31 WebhookTopic::CustomersDataRequest => {
32 serde_json::from_str::<CustomersDataRequestPayload>(payload)
33 .map(WebhookPayload::CustomersDataRequest)
34 .map_err(|e| WebhookParseError::ParseError(e.to_string()))
35 }
36 WebhookTopic::CustomersRedact => serde_json::from_str::<CustomersRedactPayload>(payload)
37 .map(WebhookPayload::CustomersRedact)
38 .map_err(|e| WebhookParseError::ParseError(e.to_string())),
39 WebhookTopic::ShopRedact => serde_json::from_str::<ShopRedactPayload>(payload)
40 .map(WebhookPayload::ShopRedact)
41 .map_err(|e| WebhookParseError::ParseError(e.to_string())),
42 }
43}
44
45pub fn parse_webhook_from_value(
46 topic: WebhookTopic,
47 payload: Value,
48) -> Result<WebhookPayload, WebhookParseError> {
49 match topic {
50 WebhookTopic::CustomersDataRequest => {
51 serde_json::from_value::<CustomersDataRequestPayload>(payload)
52 .map(WebhookPayload::CustomersDataRequest)
53 .map_err(|e| WebhookParseError::ParseError(e.to_string()))
54 }
55 WebhookTopic::CustomersRedact => serde_json::from_value::<CustomersRedactPayload>(payload)
56 .map(WebhookPayload::CustomersRedact)
57 .map_err(|e| WebhookParseError::ParseError(e.to_string())),
58 WebhookTopic::ShopRedact => serde_json::from_value::<ShopRedactPayload>(payload)
59 .map(WebhookPayload::ShopRedact)
60 .map_err(|e| WebhookParseError::ParseError(e.to_string())),
61 }
62}
63
64pub fn parse_webhook_with_header(
65 topic_header: &str,
66 payload: &str,
67) -> Result<WebhookPayload, WebhookParseError> {
68 let topic =
69 WebhookTopic::from_header(topic_header).ok_or(WebhookParseError::UnknownWebhookType)?;
70 parse_webhook(topic, payload)
71}
72
73pub fn parse_webhook_with_header_from_value(
74 topic_header: &str,
75 payload: Value,
76) -> Result<WebhookPayload, WebhookParseError> {
77 let topic =
78 WebhookTopic::from_header(topic_header).ok_or(WebhookParseError::UnknownWebhookType)?;
79 parse_webhook_from_value(topic, payload)
80}
81
82pub fn try_parse_webhook(payload: &str) -> Result<WebhookPayload, WebhookParseError> {
83 if let Ok(data_request) = serde_json::from_str::<CustomersDataRequestPayload>(payload) {
84 return Ok(WebhookPayload::CustomersDataRequest(data_request));
85 }
86
87 if let Ok(customers_redact) = serde_json::from_str::<CustomersRedactPayload>(payload) {
88 return Ok(WebhookPayload::CustomersRedact(customers_redact));
89 }
90
91 if let Ok(shop_redact) = serde_json::from_str::<ShopRedactPayload>(payload) {
92 return Ok(WebhookPayload::ShopRedact(shop_redact));
93 }
94
95 Err(WebhookParseError::UnknownWebhookType)
96}
97
98pub fn try_parse_webhook_from_value(payload: Value) -> Result<WebhookPayload, WebhookParseError> {
99 if let Ok(data_request) = serde_json::from_value::<CustomersDataRequestPayload>(payload.clone())
100 {
101 return Ok(WebhookPayload::CustomersDataRequest(data_request));
102 }
103
104 if let Ok(customers_redact) = serde_json::from_value::<CustomersRedactPayload>(payload.clone())
105 {
106 return Ok(WebhookPayload::CustomersRedact(customers_redact));
107 }
108
109 if let Ok(shop_redact) = serde_json::from_value::<ShopRedactPayload>(payload) {
110 return Ok(WebhookPayload::ShopRedact(shop_redact));
111 }
112
113 Err(WebhookParseError::UnknownWebhookType)
114}