npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

z-deduper

v1.0.3

Published

This library will allow you to build a Custom Zapier deduper for your advanced polling triggers use cases in your Zapier app.

Downloads

79

Readme

Custom Zapier Deduper

This library will allow you to build a Custom Zapier deduper for your advanced polling triggers use cases in your Zapier app.

Installation

$ yarn add z-deduper

Usage

z-deduper uses the Zapier Storage REST API behind the scenes to implement a custom deduper that will allow a polling trigger to compare the current API response records with the records that were cached by the deduper in order to determine which ones are new records and which ones are only updated records when the API doesn't include any timestamps to indicate when a record has been created or updated.

To get started, you'll need to create an instance of z-deduper, you can do it like so:

const { getDeduper } = require("z-deduper");

const deduper = getDeduper("your_zap_id_goes_here");

Basically, the deduper should only run when the zap is enabled. You will need to take care of a few cases to get it to work properly.

Initializing the deduper

When the zap is turned on, Zapier will start populating its internal deduper and bundle.meta.isPopulatingDedupe will be set to true. At this point, you will have to initialize the deduper with as many records as possible (See the examples below).

// ...

const contacts = await fetchContacts(z);

if (bundle.meta.isPopulatingDedupe) {
  // Initialize the custom deduper
  await deduper.initialize(contacts);
}

// ...

Loading a sample

When the user is testing the trigger, Zapier will run the trigger to fetch some samples. In this case, bundle.meta.isLoadingSample will be set to true and the deduper should be bypassed.

const contacts = await fetchContacts(z);

if (bundle.meta.isLoadingSample) {
  // When the deduper cache is empty, it will actually return all the records
  const changes = deduper.findChanges(contacts);
  return changes.all;
}

When the zap is polling for data

When a polling interval comes around, the trigger should load the deduper cache first, call the findChanges method on the current API response records, and finally, it must call persistChanges to update the deduper cache.

findChanges method will return an object containing the following items:

  • created: An array containing the newly created records only.
  • updated: A an array containing the updated records only.
  • all: A combination of created and updated.
const contacts = await fetchContacts(z);

await deduper.load();
const changes = deduper.findChanges(contacts);
await deduper.persistChanges(contacts);

return changes.created; // or changes.updated;

Example 01: New Contact

Here's a quick example showing how to use the custom deduper to detect new records.

const zapier = require("zapier-platform-core");
const { getDeduper } = require("z-deduper");
const { apiUrl } = require("../config");

/**
 * Fetch a list of the contacts
 *
 * @param {zapier.ZObject} z
 */
async function fetchContacts(z) {
  // Make the request
  const response = await z.request({
    method: "GET",
    url: apiUrl,
  });
  const contacts = response.json;
  return contacts;
}

/**
 * On Contact Created
 *
 * @param {zapier.ZObject} z
 * @param {zapier.Bundle} bundle
 */
const perform = async (z, bundle) => {
  const zapId = bundle.meta.zap.id;
  if (!zapId) {
    throw new Error("Zap ID is required for the custom deduper to work");
  }
  // Get an instance of the custom deduper
  const deduper = getDeduper(zapId);

  // Fetch contacts from the API
  const contacts = await fetchContacts(z);

  if (bundle.meta.isPopulatingDedupe) {
    // Initialize the custom deduper
    await deduper.initialize(contacts);

    // Pass these to the Zapier Deduper
    const changes = deduper.findChanges(contacts);
    return changes.all;
  }

  if (bundle.meta.isLoadingSample) {
    const changes = deduper.findChanges(contacts);
    return changes.all;
  }

  // If we get here, it means that the zap is enabled
  // The follwing will run on each polling interval
  await deduper.load();
  const changes = deduper.findChanges(contacts);
  await deduper.persistChanges(contacts);

  // Returns only the newly created records
  return changes.created;
};

Example 02: Updated Contact

In this example, the deduper will help in detecting which contacts have been updated even though the contacts don't have any timestamps.

const zapier = require("zapier-platform-core");
const { getDeduper } = require("z-deduper");
const { apiUrl } = require("../config");

/**
 * Fetch a list of the contacts
 *
 * @param {ZObject} z
 */
async function fetchContacts(z) {
  // Make the request
  const response = await z.request({
    method: "GET",
    url: apiUrl,
  });
  const contacts = response.json;
  return contacts;
}

/**
 * On Contact updated
 *
 * @param {zapier.ZObject} z
 * @param {zapier.Bundle} bundle
 */
const perform = async (z, bundle) => {
  const zapId = bundle.meta.zap.id;
  if (!zapId) {
    throw new Error("Zap ID is required for the custom deduper to work");
  }
  // Get an instance of the custom deduper
  const deduper = getDeduper(zapId);

  // Fetch contacts from the API
  const contacts = await fetchContacts(z);

  if (bundle.meta.isPopulatingDedupe) {
    // Initialize the custom deduper
    await deduper.initialize(contacts);

    // Pass these to the Zapier Deduper
    const changes = deduper.findChanges(contacts);
    return changes.all;
  }

  if (bundle.meta.isLoadingSample) {
    const changes = deduper.findChanges(contacts);
    return changes.all;
  }

  // If we get here, it means that the zap is enabled
  // The follwing will run on each polling interval
  await deduper.load();
  const changes = deduper.findChanges(contacts);
  await deduper.persistChanges(contacts);

  // Returns only the updated records
  return changes.updated;
};

As you might have already noticed, both examples are very similar. The only difference is that the "New Contact" trigger will return changes.created whereas "Update Contact" will return changes.updated.

License

MIT