Skip to content

Commit

Permalink
Merge pull request #168 from jamalsoueidan/webhook-product-update
Browse files Browse the repository at this point in the history
Webhook product update
  • Loading branch information
jamalsoueidan authored Jul 1, 2024
2 parents 3ea52ca + fa2dd11 commit 92e6267
Show file tree
Hide file tree
Showing 16 changed files with 186 additions and 19 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
},
"scripts": {
"tunnel": "ssh -R 80:localhost:7071 serveo.net",
"tunnel2": "ssh -R 80:localhost:7071 nokey@localhost.run",
"prebuild": "npm run clean",
"build": "tsc --project tsconfig.build.json",
"watch": "tsc -w",
Expand Down
18 changes: 17 additions & 1 deletion src/functions/customer/orchestrations/product/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { InvocationContext } from "@azure/functions";
import * as df from "durable-functions";
import { OrchestrationContext } from "durable-functions";
import { activityType } from "~/library/orchestration";
import {
updateArticle,
updateArticleName,
} from "../customer/update/update-article";
import {
updateUserMetaobject,
updateUserMetaobjectName,
Expand Down Expand Up @@ -36,6 +40,12 @@ const orchestrator: df.OrchestrationHandler = function* (
activityType<typeof updatePrice>(input)
);

const article: Awaited<ReturnType<typeof updateArticle>> =
yield context.df.callActivity(
updateArticleName,
activityType<typeof updateArticle>(input)
);

const userField: Awaited<ReturnType<typeof updateUserMetaobject>> =
yield context.df.callActivity(
updateUserMetaobjectName,
Expand All @@ -49,7 +59,13 @@ const orchestrator: df.OrchestrationHandler = function* (
activityType<typeof updateScheduleLocationsField>(input)
);

return { productUpdated, priceUpdated, userField, scheduleLocationsField };
return {
productUpdated,
priceUpdated,
article,
userField,
scheduleLocationsField,
};
};

df.app.orchestration("CustomerProductUpdateOrchestration", orchestrator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,11 @@ export const updateProduct = async ({

categories?.forEach((category) => {
tags.push(`collectionid-${GidFormat.parse(category.id)}`);

category.ruleSet?.rules.forEach((r) => {
tags.push(r.condition);
});
if (category.ruleSet?.rules.length === 1) {
category.ruleSet?.rules.forEach((r) => {
tags.push(r.condition);
});
}
});

await ScheduleModel.updateOne(
Expand All @@ -110,6 +111,7 @@ export const updateProduct = async ({
$set: {
"products.$": {
...product,
active: user.active,
collectionIds:
categories?.map((c) => GidFormat.parse(c.id)) ||
product.collectionIds,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { OrderModel } from "~/functions/order/order.models";
import { Order } from "~/functions/order/order.types";
import { orderWithoutShipping } from "~/functions/webhook/data-order-with-without-shipping";
import { orderWithoutShipping } from "~/functions/webhook/order/data-order-with-without-shipping";
import { createUser } from "~/library/jest/helpers";
import { createLocation } from "~/library/jest/helpers/location";
import { CustomerBookingServiceGetByGroup } from "./get-by-group";
Expand Down
4 changes: 2 additions & 2 deletions src/functions/customer/services/booking/range.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { addMinutes, subMinutes } from "date-fns";
import { OrderModel } from "~/functions/order/order.models";
import { Order } from "~/functions/order/order.types";
import { orderWithShipping } from "~/functions/webhook/data-order-with-shipping";
import { orderWithoutShipping } from "~/functions/webhook/data-order-with-without-shipping";
import { orderWithShipping } from "~/functions/webhook/order/data-order-with-shipping";
import { orderWithoutShipping } from "~/functions/webhook/order/data-order-with-without-shipping";
import { createUser } from "~/library/jest/helpers";
import { createLocation } from "~/library/jest/helpers/location";
import { createShipping } from "~/library/jest/helpers/shipping";
Expand Down
2 changes: 1 addition & 1 deletion src/functions/customer/services/order/get.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { OrderModel } from "~/functions/order/order.models";
import { Order } from "~/functions/order/order.types";
import { orderWithoutShipping } from "~/functions/webhook/data-order-with-without-shipping";
import { orderWithoutShipping } from "~/functions/webhook/order/data-order-with-without-shipping";
import { createUser } from "~/library/jest/helpers";
import { createLocation } from "~/library/jest/helpers/location";
import { createShipping } from "~/library/jest/helpers/shipping";
Expand Down
7 changes: 1 addition & 6 deletions src/functions/openai/services/product-categorize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@ export const OpenAIServiceProductCategorize = async ({
try {
const { data } = await shopifyAdmin().request(COLLECTIONS);

const collections = data?.collections.nodes.filter(
(collection: any) => collection.ruleSet.rules.length == 1
);

// Prepare collections data as context
const collectionsContext = JSON.stringify(collections, null, 2);
const collectionsContext = JSON.stringify(data?.collections.nodes, null, 2);

const content = `
### Product Details:
Expand Down
6 changes: 4 additions & 2 deletions src/functions/webhook-customer.function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ app.http("webhookCustomerUpdate", {
}

return { body: "" };
} catch(err) {
return {body: ""}
} catch (err) {
return { body: "" };
}
},
});
Expand All @@ -150,6 +150,8 @@ app.http("webhookCustomerDelete", {
});

if (response.deletedCount > 0) {
//TODO:
//Delete also his content in shopify?
ScheduleModel.deleteMany({
customerId,
});
Expand Down
4 changes: 2 additions & 2 deletions src/functions/webhook-order.function.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import "module-alias/register";

import {
app,
HttpRequest,
HttpResponseInit,
InvocationContext,
app,
output,
} from "@azure/functions";
import { webhookOrderProcess } from "./webhook/order";
import { webhookOrderProcess } from "./webhook/order/order";

export const orderQueueName = "webhook-order";
export const orderQueueOutput = output.storageQueue({
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
53 changes: 53 additions & 0 deletions src/functions/webhook/product/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { InvocationContext } from "@azure/functions";
import * as df from "durable-functions";
import { OrchestrationContext } from "durable-functions";
import {
updateArticle,
updateArticleName,
} from "~/functions/customer/orchestrations/customer/update/update-article";
import {
updateProduct,
updateProductName,
} from "~/functions/customer/orchestrations/product/update/update-product";
import { activityType } from "~/library/orchestration";

const orchestrator: df.OrchestrationHandler = function* (
context: OrchestrationContext
) {
const input = context.df.getInput() as Input;

const productUpdated: Awaited<ReturnType<typeof updateProduct>> =
yield context.df.callActivity(
updateProductName,
activityType<typeof updateProduct>(input)
);

const article: Awaited<ReturnType<typeof updateArticle>> =
yield context.df.callActivity(
updateArticleName,
activityType<typeof updateArticle>(input)
);

return { productUpdated, article };
};

df.app.orchestration("WebhookUpdateProductOrchestration", orchestrator);

type Input = { customerId: number; productId: number };

export const WebhookUpdateProductOrchestration = async (
input: Input,
context: InvocationContext
): Promise<string> => {
const client = df.getClient(context);
const instanceId: string = await client.startNew(
"WebhookUpdateProductOrchestration",
{
input,
}
);

context.log(`Started orchestration with ID = '${instanceId}'.`);

return instanceId;
};
98 changes: 98 additions & 0 deletions src/functions/webook-product.function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import "module-alias/register";

import { app, HttpRequest, InvocationContext } from "@azure/functions";
import * as df from "durable-functions";
import { connect } from "~/library/mongoose";
import { WebhookUpdateProductOrchestration } from "./webhook/product/update";

type Product = {
admin_graphql_api_id: string;
body_html: string;
created_at: string;
handle: string;
id: number;
product_type: string;
published_at: string;
template_suffix: any;
title: string;
updated_at: string;
vendor: string;
status: string;
published_scope: string;
tags: string;
variants: Array<{
admin_graphql_api_id: string;
barcode: string;
compare_at_price: string;
created_at: string;
fulfillment_service: string;
id: number;
inventory_management: any;
inventory_policy: string;
position: number;
price: string;
product_id: number;
sku: string;
taxable: boolean;
title: string;
updated_at: string;
option1: string;
option2: any;
option3: any;
grams: number;
image_id: any;
weight: number;
weight_unit: string;
inventory_item_id: number;
inventory_quantity: number;
old_inventory_quantity: number;
requires_shipping: boolean;
}>;
options: Array<{
name: string;
id: number;
product_id: number;
position: number;
values: Array<string>;
}>;
images: Array<any>;
image: any;
variant_gids: Array<{
admin_graphql_api_id: string;
updated_at: string;
}>;
};

app.http("webhookProductUpdate", {
methods: ["POST"],
authLevel: "anonymous",
route: "webhooks/product/update",
extraInputs: [df.input.durableClient()],
handler: async (request: HttpRequest, context: InvocationContext) => {
try {
await connect();
const shopifyProduct = (await request.json()) as unknown as Product;
const shouldProcessUpdate = shopifyProduct.tags.includes("update");
const regex = /userid-(\d+)/;
const match = shopifyProduct.tags.match(regex);

if (match && shouldProcessUpdate) {
// The user ID is in the first capturing group
const customerId = match[1];
console.log(`User ID: ${customerId}, - ${shopifyProduct.id}`);

await WebhookUpdateProductOrchestration(
{
customerId: parseInt(customerId),
productId: shopifyProduct.id,
},
context
);
}

return { body: "" };
} catch (err) {
return { body: "" };
}
},
});

0 comments on commit 92e6267

Please sign in to comment.