shopify_api 0.9.6

Shopify API client
Documentation
use super::{Customer, InventoryItem, InventoryLevel, ShopifyWebhook};
use crate::Shopify;
use serde_json;
use std::future::Future;
use std::sync::Arc;
use tokio::sync::Mutex;
use warp::http::StatusCode;
use warp::{Filter, Rejection};

impl Shopify {
    #[cfg(feature = "warp-wrapper")]
    pub fn warp_wrapper<F, Fut, T>(
        path: &str,
        shopify_filter: Arc<Mutex<Shopify>>,
        extra_data: T,
        callback: F,
    ) -> warp::filters::BoxedFilter<(impl warp::Reply,)>
    where
        T: Clone + Send + Sync + 'static,
        F: Fn(ShopifyWebhook, Arc<Mutex<Shopify>>, T) -> Fut + Clone + Send + Sync + 'static,
        Fut: Future<Output = Result<(), String>> + Send,
    {
        let path_clone = path.to_string();

        warp::path(path_clone)
            .and(warp::post())
            .and(warp::any().map(move || shopify_filter.clone()))
            .and(warp::any().map(move || extra_data.clone()))
            .and(warp::header::<String>("x-shopify-hmac-sha256"))
            .and(warp::header::<String>("X-Shopify-Topic"))
            .and(warp::body::bytes())
            .and_then(
                move |shopify: Arc<Mutex<Shopify>>,
                      extra: T,
                      header: String,
                      topic: String,
                      body: bytes::Bytes| {
                    let callback_clone = callback.clone();
                    async move {
                        let is_valid = shopify.lock().await.verify_hmac(&body, &header);

                        if !is_valid {
                            return Ok::<_, Rejection>(warp::reply::with_status(
                                warp::reply::html("Invalid HMAC"),
                                StatusCode::BAD_REQUEST,
                            ));
                        }

                        let str_body = std::str::from_utf8(&body).unwrap();

                        log::debug!("Received webhook topic: {} with body {}", topic, str_body);

                        let webhook_data: ShopifyWebhook = match topic.as_str() {
                            "inventory_items/create" => ShopifyWebhook::InventoryItemCreate(
                                crate::utils::deserialize_from_str::<InventoryItem>(str_body)
                                    .unwrap(),
                            ),
                            "inventory_items/update" => ShopifyWebhook::InventoryItemUpdate(
                                crate::utils::deserialize_from_str::<InventoryItem>(str_body)
                                    .unwrap(),
                            ),
                            "inventory_items/delete" => ShopifyWebhook::InventoryItemDelete(
                                crate::utils::deserialize_from_str::<InventoryItem>(str_body)
                                    .unwrap(),
                            ),
                            "inventory_levels/connect" => ShopifyWebhook::InventoryLevelConnect(
                                crate::utils::deserialize_from_str::<InventoryLevel>(str_body)
                                    .unwrap(),
                            ),
                            "inventory_levels/disconnect" => {
                                ShopifyWebhook::InventoryLevelDisconnect(
                                    crate::utils::deserialize_from_str::<InventoryLevel>(str_body)
                                        .unwrap(),
                                )
                            }
                            "inventory_levels/update" => ShopifyWebhook::InventoryLevelUpdate(
                                crate::utils::deserialize_from_str::<InventoryLevel>(str_body)
                                    .unwrap(),
                            ),
                            "customers/create" => ShopifyWebhook::CustomersCreate(
                                crate::utils::deserialize_from_str::<Customer>(str_body).unwrap(),
                            ),
                            "customers/update" => ShopifyWebhook::CustomersUpdate(
                                crate::utils::deserialize_from_str::<Customer>(str_body).unwrap(),
                            ),
                            "orders/create" => ShopifyWebhook::OrdersCreate(
                                crate::utils::deserialize_from_str(str_body).unwrap(),
                            ),
                            "orders/updated" => ShopifyWebhook::OrdersUpdated(
                                crate::utils::deserialize_from_str(str_body).unwrap(),
                            ),
                            _ => ShopifyWebhook::Other((
                                topic,
                                serde_json::from_str(str_body).unwrap(),
                            )),
                        };

                        match callback_clone(webhook_data, shopify.clone(), extra.clone()).await {
                            Ok(_) => Ok(warp::reply::with_status(
                                warp::reply::html("Success"),
                                StatusCode::OK,
                            )),
                            Err(_e) => {
                                let custom_error = warp::reject::reject();
                                Err(custom_error)
                            }
                        }
                    }
                },
            )
            .boxed()
    }
}