Implement product deletion
This commit is contained in:
@@ -32,6 +32,18 @@ export class ProductRecords {
|
|||||||
return row as ProductRecord | undefined;
|
return row as ProductRecord | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteFromWebflow(webflowProductId: number) {
|
||||||
|
this.db.run(`
|
||||||
|
DELETE FROM product_records WHERE webflowProductId = ?
|
||||||
|
`, [webflowProductId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteFromPrintful(printfulProductId: number) {
|
||||||
|
this.db.run(`
|
||||||
|
DELETE FROM product_records WHERE printfulProductId = ?
|
||||||
|
`, [printfulProductId]);
|
||||||
|
}
|
||||||
|
|
||||||
add(record: ProductRecord): void {
|
add(record: ProductRecord): void {
|
||||||
this.db.run(`
|
this.db.run(`
|
||||||
INSERT OR IGNORE INTO product_records (webflowProductId, printfulProductId)
|
INSERT OR IGNORE INTO product_records (webflowProductId, printfulProductId)
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ const server = Bun.serve({
|
|||||||
try {
|
try {
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
// ADD/UPDATE
|
// ADD/UPDATE
|
||||||
case Printful.Webhook.Event.ProductUpdated:
|
case Printful.Webhook.Event.ProductUpdated: {
|
||||||
const printfulProduct = await Printful.getSyncProduct(payload.data.sync_product.id)
|
const printfulProduct = await Printful.getSyncProduct(payload.data.sync_product.id);
|
||||||
const productRecord = productRecords.findFromPrintful(payload.data.sync_product.id)
|
const productRecord = productRecords.findFromPrintful(payload.data.sync_product.id);
|
||||||
|
|
||||||
if (productRecord) {
|
if (productRecord) {
|
||||||
await Webflow.updateProduct(printfulProduct, productRecords);
|
await Webflow.updateProduct(printfulProduct, productRecords);
|
||||||
@@ -30,11 +30,14 @@ const server = Bun.serve({
|
|||||||
await Webflow.createProduct(printfulProduct, productRecords);
|
await Webflow.createProduct(printfulProduct, productRecords);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
// DELETE
|
// DELETE
|
||||||
case Printful.Webhook.Event.ProductDeleted:
|
case Printful.Webhook.Event.ProductDeleted: {
|
||||||
|
await Webflow.deleteProduct(payload.data.sync_product.id, productRecords);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (error){
|
catch (error){
|
||||||
console.error(error);
|
console.error(error);
|
||||||
Response.error();
|
Response.error();
|
||||||
|
|||||||
+31
-8
@@ -2,9 +2,18 @@ import { ProductRecords } from "./data/product-records";
|
|||||||
import { Printful } from "./printful"
|
import { Printful } from "./printful"
|
||||||
|
|
||||||
export namespace Webflow {
|
export namespace Webflow {
|
||||||
export const API_URL = `https://api.webflow.com/v2/sites/${Bun.env.WEBFLOW_SITE_ID}`;
|
export const API_SITES_URL = `https://api.webflow.com/v2/sites/${Bun.env.WEBFLOW_SITE_ID}`;
|
||||||
|
export const API_COLLECTIONS_URL = `https://api.webflow.com/v2/collections/${Bun.env.WEBFLOW_COLLECTION_ID}`;
|
||||||
|
|
||||||
const formatSlug = name => name.replaceAll(" ", "-").replaceAll("/", "").toLowerCase();
|
const formatSlug = (name: string): string => {
|
||||||
|
return name
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/[^a-z0-9-_]/g, '-') // replace illegal chars with dashes
|
||||||
|
.replace(/^-+/, '') // remove leading dashes
|
||||||
|
.replace(/-+$/, '') // remove trailing dashes
|
||||||
|
.replace(/--+/g, '-') // collapse multiple dashes
|
||||||
|
.replace(/^([^a-z0-9_])/, '_$1'); // if it starts with an invalid char, prefix underscore
|
||||||
|
};
|
||||||
|
|
||||||
namespace Products {
|
namespace Products {
|
||||||
export interface Sku {
|
export interface Sku {
|
||||||
@@ -43,6 +52,21 @@ export namespace Webflow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function deleteProduct(printfulProductId: number, productRecords: ProductRecords) {
|
||||||
|
const webflowProductId = productRecords.findFromPrintful(printfulProductId)?.webflowProductId;
|
||||||
|
if (webflowProductId){
|
||||||
|
const res = await fetch(`${Webflow.API_COLLECTIONS_URL}/items/${webflowProductId}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": `bearer ${Bun.env.WEBFLOW_AUTH}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({})
|
||||||
|
});
|
||||||
|
productRecords.deleteFromWebflow(webflowProductId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function updateProduct(printfulProduct: Printful.Products.SyncProduct, productRecords: ProductRecords) {
|
export async function updateProduct(printfulProduct: Printful.Products.SyncProduct, productRecords: ProductRecords) {
|
||||||
const webflowProductId = productRecords.findFromPrintful(printfulProduct.result.sync_product.id)?.webflowProductId;
|
const webflowProductId = productRecords.findFromPrintful(printfulProduct.result.sync_product.id)?.webflowProductId;
|
||||||
if (!webflowProductId) {
|
if (!webflowProductId) {
|
||||||
@@ -79,7 +103,7 @@ export namespace Webflow {
|
|||||||
const foundColors = Array.from(new Set(variantColors));
|
const foundColors = Array.from(new Set(variantColors));
|
||||||
const foundSizes = Array.from(new Set(variantSizes));
|
const foundSizes = Array.from(new Set(variantSizes));
|
||||||
|
|
||||||
let updateProductResponse = await fetch(`${Webflow.API_URL}/products/${webflowProductId}`, {
|
let updateProductResponse = await fetch(`${Webflow.API_SITES_URL}/products/${webflowProductId}`, {
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -117,7 +141,7 @@ export namespace Webflow {
|
|||||||
});
|
});
|
||||||
updateProductResponse = await updateProductResponse.json();
|
updateProductResponse = await updateProductResponse.json();
|
||||||
|
|
||||||
const getProductResponse = await fetch(`${Webflow.API_URL}/products/${webflowProductId}`, {
|
const getProductResponse = await fetch(`${Webflow.API_SITES_URL}/products/${webflowProductId}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": `bearer ${Bun.env.WEBFLOW_AUTH}`
|
"Authorization": `bearer ${Bun.env.WEBFLOW_AUTH}`
|
||||||
@@ -128,7 +152,7 @@ export namespace Webflow {
|
|||||||
for (let i = 0; i < webflowProduct["skus"].length; ++i) {
|
for (let i = 0; i < webflowProduct["skus"].length; ++i) {
|
||||||
const webflowSkuId = variantExternalIds[i];
|
const webflowSkuId = variantExternalIds[i];
|
||||||
|
|
||||||
const res = await fetch(`${Webflow.API_URL}/products/${webflowProductId}/skus/${webflowSkuId}`, {
|
const res = await fetch(`${Webflow.API_SITES_URL}/products/${webflowProductId}/skus/${webflowSkuId}`, {
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -170,7 +194,7 @@ export namespace Webflow {
|
|||||||
const foundSizes = Array.from(new Set(printfulVariants.map(v => v.size)));
|
const foundSizes = Array.from(new Set(printfulVariants.map(v => v.size)));
|
||||||
|
|
||||||
// CREATE WEBFLOW PRODUCT
|
// CREATE WEBFLOW PRODUCT
|
||||||
let addProductResponse = await fetch(`${Webflow.API_URL}/products`, {
|
let addProductResponse = await fetch(`${Webflow.API_SITES_URL}/products`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -216,7 +240,7 @@ export namespace Webflow {
|
|||||||
const printfulProductId = printfulProduct.result.sync_product.id;
|
const printfulProductId = printfulProduct.result.sync_product.id;
|
||||||
|
|
||||||
// CREATE WEBFLOW PRODUCT SKUs
|
// CREATE WEBFLOW PRODUCT SKUs
|
||||||
let createSkuResponse = await fetch(`${Webflow.API_URL}/products/${webflowProductId}/skus`, {
|
let createSkuResponse = await fetch(`${Webflow.API_SITES_URL}/products/${webflowProductId}/skus`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -231,7 +255,6 @@ export namespace Webflow {
|
|||||||
const responseSkus = [addProductResponse["sku"], ...createSkuResponse["skus"]];
|
const responseSkus = [addProductResponse["sku"], ...createSkuResponse["skus"]];
|
||||||
|
|
||||||
// SYNC WEBFLOW/PRINTFUL PRODUCT AND VARIANT IDs
|
// SYNC WEBFLOW/PRINTFUL PRODUCT AND VARIANT IDs
|
||||||
console.log(`Hitting: ${Printful.API_URL}/store/products/${printfulProductId}`);
|
|
||||||
let modifyPrintfulProductResponse = await fetch(`${Printful.API_URL}/store/products/${printfulProductId}`, {
|
let modifyPrintfulProductResponse = await fetch(`${Printful.API_URL}/store/products/${printfulProductId}`, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
Reference in New Issue
Block a user