webflow / js-webflow-api

Node.js SDK for the Webflow Data API
https://www.npmjs.com/package/webflow-api
285 stars 92 forks source link

Custom fields are not inserted into function createItem() #120

Open lalalilalalai opened 4 months ago

lalalilalalai commented 4 months ago

Version: "webflow-api": "^2.0.0"

Code: index.ts:

import {Items} from "webflow-api/api/resources/collections/resources/items/client/Client";

declare global {
    namespace Express {
        interface Request {
            rawBody: Buffer
        }
    }
}

import * as functions from "firebase-functions";
import Stripe from "stripe";
import {toSlug} from "./utils/utils";
import express = require("express");
import {Webflow} from "webflow-api";
import ExtendedCollectionItemFieldData from "./webflow/ExtendedCollectionItemFieldData";

const accessToken = "token";
const stripe = new Stripe("sk_test_", {apiVersion: "2023-10-16"});
const endpointSecret = "whsec_";
const collectionId = "65ddbfa206ec63a1e30afc07";
const someOptions = {
  accessToken: accessToken,
};
const items = new Items(someOptions);
const app = express();
app.post("/webhook",
  express.raw({type: "application/json"}),
  async function(request: express.Request, response: express.Response): Promise<void> {
    const sig = request.headers["stripe-signature"] as string;

    let event: Stripe.Event;

    try {
      event = stripe.webhooks.constructEvent(request.rawBody, sig, endpointSecret);
    } catch (err: any) {
      // On error, log and return the error message
      console.log(`❌ Error message: ${err.message}`);
      functions.logger.error(`❌ Error message: ${err.message}`);
      response.status(400).send(`Webhook Error: ${err.message}`);
      return;
    }

    console.log("✅ Success:", event.id);

    switch (event.type) {
    case "product.created": {
      functions.logger.log("Product created event received!");

      // eslint-disable-next-line max-len
      const productCreated: Stripe.Product = event.data.object as Stripe.Product;

      functions.logger.log(`Product: ${JSON.stringify(productCreated)}`);

      const newItem: Webflow.CollectionItem & { fieldData?: ExtendedCollectionItemFieldData } = {
        id: productCreated.id,
        fieldData: {
          "name": productCreated.name,
          "slug": toSlug(productCreated.name),
          "available": productCreated.active,
          "quantity": null,
          "price": productCreated.default_price,
          "stripe-product-id": productCreated.id,
          "description": productCreated.description,
          "currency": "usd",
          "payment-link": null,
          "img-url": productCreated.images.at(0) || null,
        },
        isArchived: false,
        isDraft: false,
      };

      // items.createItem(collectionId, newItem).then(() => {
      //   functions.logger.info("Item created in Webflow!");
      //   console.log("Item created in Webflow!");
      // }
      items.createItem(collectionId,
        {
          id: productCreated.id,
          fieldData: {
            "name": productCreated.name,
            "slug": toSlug(productCreated.name),
            // "active": productCreated.active,
            "available": productCreated.active,
            "quantity": null,
            "price": productCreated.default_price,
            "stripe-product-id": productCreated.id,
            "description": productCreated.description,
            "currency": "usd",
            "payment-link": null,
            "img-url": productCreated.images.at(0) || null,
          },
        }
      ).then(() => {
        functions.logger.info("Item created in Webflow!");
        console.log("Item created in Webflow!");
      }
      ).catch((err) => {
        functions.logger.error(`Error creating item in Webflow: ${err}`);
        console.error(`Error creating item in Webflow: ${err}`);
      });

      break;
    }
    case "price.created": {
      // TODO
      const priceCreated: Stripe.Price = event.data.object as Stripe.Price;
      console.log(`Wow price was created! ${priceCreated.id}`);
      break;
    }
    case "product.updated": {
      // TODO
      // eslint-disable-next-line max-len
      const productUpdated: Stripe.Product = event.data.object as Stripe.Product;
      console.log(`Wow product was updated! ${productUpdated.id}`);
      break;
    }
    default:
      console.warn(`Unhandled event type ${event.type}`);
    }
    // Return a 200 response to acknowledge receipt of the event
    response.send({received: true});
  });

app.get("/hello", function(request: express.Request, response: express.Response) {
  response.send("Hello World!");
});

// Export the Express app as a Cloud Function named "api"
exports.api = functions.https.onRequest(app);

interface ExtendedCollectionItemFieldData:

import {CollectionItemFieldData} from "webflow-api/api";
import Stripe from "stripe";

interface ExtendedCollectionItemFieldData extends CollectionItemFieldData {
    // active: boolean;
    available: boolean;
    quantity: number | null;
    price?: string | Stripe.Price | null | undefined;
    "stripe-product-id": string;
    description: string | null;
    currency: string | null;
    "payment-link": string | null;
    "img-url": string | null;
}

export default ExtendedCollectionItemFieldData;

Steps to Reproduce:

  1. trigger /webhook with event "product.created"

Actual Result: Custom fields are not inserted into function createItem(), so in collection there are items with only filled name and slug collection_id: 65ddbfa206ec63a1e30afc07 and if the custom field in CMS is required, item fails to create:

>  Error creating item in Webflow: Error: BadRequestError
>  Status code: 400
>  Body: {
>    "message": "Validation Error: Field 'currency': Field is required",
>    "code": "validation_error",
>    "externalReference": null,
>    "details": []
>  }

Expected Result: Custom fields are inserted into function createItem()

ivarvermeulen commented 4 months ago

I can confirm it will only process name and slug when calling createItem, all custom fields are ignored. Version 2.0.0 of the npm package

ivarvermeulen commented 4 months ago

I've fixed the issue in this PR: https://github.com/webflow/js-webflow-api/pull/121 however this probably isn't the way to go as the sources I've changed should be generated from your API, but for anyone looking for a quick fix, you can run npm install https://github.com/The-Any-Thing/js-webflow-api

lalalilalalai commented 4 months ago

Thanks! :)