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

@vivianhealth/braze-segment-debounce

v1.0.8

Published

Segment utilities to debounce data before it reaches the Braze destination

Downloads

787

Readme

braze-segment-debounce

Segment utilities to debounce (dedupe) data before it reaches the Braze destination

Introduction

Segment provides an integration with Braze, among others, to allow users to easily send data to both platforms using a reduced number API calls and library/package installations. Although this is of great efficiency, it has the drawback of sending every data point to Braze. Braze charges $$ for each of these data points, even if the data points have not changed from the previous version. The goal of this package is to provide an easy way for Segment/Braze customers to only send data points that are new or have changed, savings lots of $$ in the process.

Although Segment provides a Braze Debounce Identify option on its dashboard under Source -> [Source Name] -> Settings -> Analytics.js, this option does not include debouncing against multiple previous payloads. The Middleware and examples provided by Braze also suffer from the same problem. The biggest advantage of this package is that it stores multiple, previous payloads to debounce against, greatly saving on costs as compared to the current solutions.

This package and its examples focus on the identify call sent to Segment/Braze since it's the most frequently used and the one most likely to incur costs, but the functions can be applied to any call type.

Usage

braze-segment-debounce supports debouncing for both browser and server. Only JavaScript/NodeJS is supported on the server side. The mechanisms for browser and server are similar but have a few, important distinctions. The package exposes three main functions, debouncePayloads (base), debouncePayloadSync (browser), debouncePayload (server).

Base

debouncePayloads is a base function used by browser and server which takes two payloads and runs them through the debouncing algorithm.

Arguments

  • previousPayload: the first payload to compare
  • nextPayload: the other payload to compare
  • getPayloadProperty: a function to help retrieve the basic values of the payload: userId, anonymousId and traits. This is needed because the Segment Analytics.js middleware, used in browser, nests the payload inside an obj object. But, this is is not true for the server side. The function can simply be lodash's _get for server or _get(payload, `obj.${prop}`)forbrowser.

Returns

  • { nextPayload || null, newOrUpdatedTraits || null } where nextPayload is the payload to send to Segment/Braze and newOrUpdatedTraits are any updates to the traits for that payload that should be included before it is sent.

Example

import { debouncePayloads } from '@vivianhealth/braze-segment-debounce';

const { nextPayload, newOrUpdatedTraits } = debouncePayloads(
  previousPayload,
  sanitizedPayload,
  (payload, prop) => _get(payload, `obj.${prop}`),
);
if (nextPayload) {
  const debouncedPayload = {
    ...nextPayload,
    obj: {
      ...nextPayload.obj,
      traits: newOrUpdatedTraits || nextPayload.obj.traits,
    },
  };
  // do something smart with `debouncedPayload`
}

Note

debouncePayloads does not need to be used in most cases, but is exposed to provide the user with flexibility if she/he needs to expand/replace the functionality provided by browser and server.

Browser

The integration of the frontend portion of this package with Segment is achieved via the Analytics.js Source Middleware. Please note that this integration has been tested in production using Analytics 2.0 and we don't recommend using the previous version of Analytics.js.

debouncePayloadSync provides a full solution that integrates with the Analytics.js Source Middleware to debounce data before it is sent to the Braze destination. It stores previous payloads in localStorage, or a similar solution which you can override, and compares the payload provided by this middleware against the previous versions so that it only sends new or updated traits.

Arguments

  • payload: the data provided by the middleware
  • options.fetchPayload: an optional function to override localStorage.getItem
  • options.persistPayload: an optional function to override localStorage.setItem

Returns

  • nextPayload || null: the debounced payload to send to Braze. If null, there is no new or updated data to send.

Example

import { debouncePayloadSync } from '@vivianhealth/braze-segment-debounce/browser';

const _identifyDebounceSourceMiddleware = ({ payload, next, integrations }) => {
  // TODO filter Braze integration, called `AppBoy`
  if (payload.type() !== 'identify') {
    next(payload);
    return;
  }
  const identifyPayload = debouncePayloadSync(payload);
  if (identifyPayload) {
    next(identifyPayload);
  }
};
analytics.addSourceMiddleware(_identifyDebounceSourceMiddleware);

Server

debouncePayload is meant to work with anayltics-node. It does not require middleware like the frontend but it does rely on a caching or storage mechanism that the user provides. Similar to browser, it stores previous payloads using the storage mechanism, and compares the payload to be sent to Segment/Braze against the previous versions so that it only sends new or updated traits.

Arguments

  • payload: the data to be sent to Segment/Braze
  • fetchPayload: a function to retrieve previous payloads
  • persistPayload: a function to store previous payloads
  • options.serializePayload: an optional function to override the default serializer
  • options.deserializePayload: an optional function to override the default deserializer

Returns

  • nextPayload || null: the debounced payload to send to Braze. If null, there is no new or updated data to send.

Example

import _isNil from 'lodash/isNil';
import Analytics from 'analytics-node';
import memjs from 'memjs';
import { debouncePayload } from '@vivianhealth/braze-segment-debounce/server';

const segmentWriteKey = 'YOUR-SEGMENT-WRITE-KEY';
const analytics = new Analytics(segmentWriteKey);
const cache = memjs.Client.create();
const fetchPayload = async (k) => cache.get(k);
const persistPayload = async (k, v) => {
  await cache.set(k, v, { expires: 3600 });
};

const identifyWithDebounce = async (payload) => {
  // TODO filter Braze integration, called `AppBoy`, if possible
  const identifyPayload = await debouncePayload(
    payload,
    fetchPayload,
    persistPayload,
  );
  if (!_isNil(identifyPayload)) {
    return analytics.identify(identifyPayload);
  }
  return null;
};

TODO

  • [ ] Add details on how to debounce payload only for Braze, known as AppBoy in the integration.