2024-03-06 15:42:04 +00:00
|
|
|
use anyhow::Context;
|
|
|
|
use axum::{
|
|
|
|
extract::{Json, State},
|
|
|
|
http::{HeaderMap, StatusCode},
|
|
|
|
};
|
|
|
|
use cynic::{http::SurfExt, MutationBuilder};
|
|
|
|
use saleor_app_sdk::{
|
|
|
|
headers::SALEOR_API_URL_HEADER,
|
|
|
|
webhooks::{
|
|
|
|
utils::{get_webhook_event_type, EitherWebhookType},
|
|
|
|
AsyncWebhookEventType,
|
|
|
|
},
|
|
|
|
};
|
2024-03-14 13:51:55 +00:00
|
|
|
use tracing::{debug, info};
|
2024-03-06 15:42:04 +00:00
|
|
|
|
|
|
|
use crate::{
|
|
|
|
app::{AppError, AppState},
|
|
|
|
queries::{
|
|
|
|
event_products_updated::ProductUpdated,
|
|
|
|
product_metadata_update::{
|
2024-03-14 13:51:55 +00:00
|
|
|
MetadataInput, UpdateProductMetadata, UpdateProductMetadataVariables,
|
2024-03-06 15:42:04 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
pub async fn webhooks(
|
|
|
|
headers: HeaderMap,
|
|
|
|
State(state): State<AppState>,
|
|
|
|
//Will try to convert req body to ProductUpdated type, else returns 400
|
|
|
|
Json(product): Json<ProductUpdated>,
|
|
|
|
) -> Result<StatusCode, AppError> {
|
|
|
|
debug!("/api/webhooks");
|
|
|
|
debug!("req: {:?}", product);
|
|
|
|
debug!("headers: {:?}", headers);
|
|
|
|
|
|
|
|
let url = headers
|
|
|
|
.get(SALEOR_API_URL_HEADER)
|
|
|
|
.context("missing saleor api url header")?;
|
|
|
|
let event_type = get_webhook_event_type(&headers)?;
|
2024-04-03 17:47:23 +00:00
|
|
|
if let EitherWebhookType::Async(a) = event_type {
|
|
|
|
match a {
|
2024-03-06 15:42:04 +00:00
|
|
|
AsyncWebhookEventType::ProductUpdated
|
|
|
|
| AsyncWebhookEventType::ProductCreated
|
|
|
|
| AsyncWebhookEventType::ProductDeleted => {
|
|
|
|
update_product(product, url.to_str()?, state).await?
|
|
|
|
}
|
|
|
|
_ => (),
|
2024-04-03 17:47:23 +00:00
|
|
|
}
|
2024-03-06 15:42:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
info!("got webhooks!");
|
|
|
|
Ok(StatusCode::OK)
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn update_product(
|
|
|
|
product: ProductUpdated,
|
|
|
|
saleor_api_url: &str,
|
|
|
|
state: AppState,
|
|
|
|
) -> anyhow::Result<()> {
|
|
|
|
debug!("Product got changed!");
|
|
|
|
if let Some(product) = product.product {
|
|
|
|
let operation = UpdateProductMetadata::build(UpdateProductMetadataVariables {
|
|
|
|
product_id: &product.id,
|
|
|
|
metadata: Some(vec![MetadataInput {
|
|
|
|
key: "helloloo",
|
|
|
|
value: "hiiiihii",
|
|
|
|
}]),
|
|
|
|
});
|
|
|
|
let saleor_app = state.saleor_app.lock().await;
|
|
|
|
let auth_data = saleor_app.apl.get(saleor_api_url).await?;
|
|
|
|
let result = surf::post(saleor_api_url)
|
|
|
|
.header("Authorization", format!("bearer {}", auth_data.token))
|
|
|
|
.run_graphql(operation)
|
|
|
|
.await;
|
|
|
|
debug!("update product result : {:?}", result);
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|