Digest Action Step

Learn how to use the digest step to aggregate multiple events into a single notification

The digest step allows you to collect multiple events over a specified time period and combine them into a single notification. This is useful for reducing notification fatigue and providing better context to your users.

Example Usage

const { events } = await step.digest('daily-summary', async () => {
  return {
    amount: 1,
    unit: 'days',
  };
});
 
await step.email('digest-email', async () => {
  return {
    subject: `Daily Summary (${events.length} updates)`,
    body: `You have ${events.length} new updates today`,
  };
});

Digest Step Output

PropertyTypeRequiredDescription
amountnumberYesThe number of time units to collect events for
unit'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months'YesThe time unit for the digest period
cronstringNoThe cron expression to use for the digest
digestKeystringNoThe key to use for digesting events

Use either cron or amount-unit. Using both will result in an error.

Digest Step Result

PropertyTypeDescription
eventsDigestEvent[]Array of events collected during the digest period

DigestEvent Type

PropertyTypeDescription
idstringThe unique identifier of the digested event
timeDateThe timestamp when the event was triggered
payloadobjectThe original payload passed to the event

The digest step result can only be used in subsequent steps within the same workflow. You cannot access digest information in step controls.

Using Digest Events

You can use the digested events to create rich, aggregated notifications. Here's an example:

import { ActivityDigestEmail } from './ActivityDigestEmail';
 
const { events } = await step.digest('activity-digest', async () => {
  return {
    amount: 1,
    unit: 'hours',
  };
});
 
await step.email('digest-notification', async () => {
  const activities = events.map((event) => ({
    type: event.payload.type,
    user: event.payload.userName,
    action: event.payload.action,
  }));
 
  return {
    subject: `Activity Summary (${events.length} updates)`,
    body: render(<ActivityDigestEmail activities={activities} />),
  };
});

Cron based digest

You can use cron based digest to digest events based on a cron expression.

const digestedEvents = await step.digest('cron-digest', async () => {
  return {
    cron: '0 0 * * *', // every day at midnight
  };
});

Custom Digest Key

You can use a custom digest key to digest events based on a custom key. By default, events are digested based on the subscriberId. With a custom digest key, events are digested based on the combination of the subscriberId and the digestKey value.

export const customDigestKey = workflow(
  "custom-digest-key",
  async ({ step, payload }) => {
    const { events } = await step.digest("digest-step", async () => {
      return {
        unit: "hours",
        amount: 1,
        digestKey: payload.ticket_id,
      };
    });
 
    console.log("events ==>", events);
 
    // use above events to send email / in-app notification
  },
  {
    payloadSchema: z.object({
      ticket_id: z.string(),
    }),
  }
);

Changes to the workflow content after triggering will not affect existing digested events. The content is determined at the time of event digestion.

On this page