Edits history of script submission #22505 for ' Add or Update Contact (sendgrid)'

  • bun
    One script reply has been approved by the moderators
    Ap­pro­ved
    import sendgrid from "@sendgrid/client@^7.7.0";
    
    /**
     * According to Sendgrid documentation, this is an asynchronous
     * process and the response will NOT contain immediate feedback,
     * only a `job_id` which then can be used to get the status
     * of the job.
     * The following script from WindmillHub performs this status check:
     * https://hub.windmill.dev/scripts/sendgrid/1449/get-contacts-import-status-sendgrid
     *
     * You can read more of the Sendgrid documentation at
     * https://docs.sendgrid.com/api-reference/contacts/add-or-update-a-contact
     */
    type Sendgrid = {
      token: string;
    };
    export async function main(
      api_token: Sendgrid,
      contacts: {
        email: string;
        custom_fields: Record<string, string | number>;
      }[],
      list_ids?: string[],
    ) {
      sendgrid.setApiKey(api_token.token);
    
      try {
        contacts = contacts.map((c) => {
          return typeof c === "string" ? JSON.parse(c) : c;
        });
      } catch (error) {
        throw Error(`Tried to parse "contacts" argument because 
        it was an array of strings but failed with error:\n${error}`);
      }
    
      const body = removeObjectEmptyFields({
        contacts,
        list_ids,
      });
      const request = {
        url: `/v3/marketing/contacts`,
        method: "PUT",
        body,
      };
    
      try {
        const [_, body] = await sendgrid.request(request);
        return body;
      } catch (error) {
        throw Error("\n" + JSON.stringify(error?.response?.body || error));
      }
    }
    
    function removeObjectEmptyFields(
      object?: Record<string, any>,
      removeEmptyArraysAndObjects = true,
      createNewObject = true,
    ) {
      if (!object || typeof object !== "object") return {}
      const obj = createNewObject ? { ...object } : object
      const emptyValues = [undefined, null, ""]
      for (const key in obj) {
        const value = obj[key]
        if (emptyValues.includes(value)) {
          delete obj[key]
        } else if (typeof value === "object") {
          if (Object.keys(value).length) {
            obj[key] = removeObjectEmptyFields(value, removeEmptyArraysAndObjects, false)
          }
          if (!Object.keys(value).length && removeEmptyArraysAndObjects) {
            delete obj[key]
          }
        }
      }
      return obj
    }
    

    Submitted by hugo989 3 days ago