New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

segflow

Package Overview
Dependencies
Maintainers
0
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

segflow

latest
npmnpm
Version
0.0.26
Version published
Maintainers
0
Created
Source

Segflow: Zero to Hero Guide

What is Segflow?

Segflow lets you write marketing automation flows in pure code. Instead of clicking through complex UIs, you can:

  • Define user segments with SQL queries
  • Write campaign logic in TypeScript
  • Create email templates in React
  • Deploy everything with Git

Think "Infrastructure as Code", but for marketing automation. See the example in examples/segflow.config.ts for a complete example.

Key Concepts

Segments = SQL Queries

Define user groups with the full power of SQL:

segments: {
  'big-spenders': {
    evaluator: (db) => db
      .select({ id: schema.users.id })
      .from(schema.users)
      .innerJoin(schema.events, eq(schema.events.userId, schema.users.id))
      .where(eq(schema.events.name, 'purchase'))
      .groupBy(schema.users.id)
      .having(sql`sum(${schema.events.attributes}->'$.amount') > 1000`)
  }
}

Campaigns = Generator Functions

Write complex flows with regular TypeScript:

campaigns: {
  'onboarding': {
    segments: ['new-users'],
    behavior: 'static',
    flow: function* (ctx, rt) {
      yield rt.sendEmail('welcome');
      yield rt.wait({ days: 1 });
      
      if (!ctx.user.profileCompleted) {
        yield rt.sendEmail('complete-profile-reminder');
        yield rt.wait({ days: 3 });
      }
      
      yield rt.wait({ days: 3 });
      yield rt.sendEmail('feature-highlights');
    }
  }
}

Templates = React Components

Design emails with familiar tools:

templates: {
  'welcome': {
    subject: (user) => `Welcome ${user.name}!`,
    component: ({ user }) => (
      <Html>
        <Head />
        <Tailwind>
          <Body>
            <Preview className="text-blue-600">Welcome aboard!</Preview>
            <Text className="text-slate-600">Thanks for joining us {user.name}!</Text>
            <Button href="https://example.com/get-started">
              Get Started
            </Button>
          </Body>
        </Tailwind>
      </Html>
    )
  }
}

Transactions = Event-Triggered Emails

While campaigns are for ongoing flows, transactions are for immediate, event-triggered emails. Think order confirmations, password resets, or welcome emails that need to go out right when something happens:

transactions: {
  'purchase-confirmation': {
    event: 'purchase',  // Triggered when 'purchase' event is emitted
    subject: (user) => `Order Confirmed, ${user.name}!`,
    component: ({ user }) => (
      <Html>
        <Head />
        <Tailwind>
          <Body>
            <Preview>Thanks for your order!</Preview>
            <Text className="text-slate-600">Hi {user.name}, we've received your purchase.</Text>
          </Body>
        </Tailwind>
      </Html>
    )
  },
  'password-reset': {
    event: 'reset_password_requested',
    subject: (user) => `Reset Your Password`,
    component: ({ user, event }) => (
      <Html>
        <Head />
        <Tailwind>
          <Body>
            <Preview>Reset your password</Preview>
            <Text className="text-slate-600">Click the link below to reset your password:</Text>
            <Button href={event.resetLink}>
              Reset Password
            </Button>
          </Body>
        </Tailwind>
      </Html>
    )
  }
}

To trigger a transactional email, just emit the corresponding event:

// This will instantly send the purchase confirmation email
await client.emit('user123', 'purchase', {
  orderId: 'ord_123',
  amount: 99.99
});

// This will instantly send the password reset email
await client.emit('user123', 'reset_password_requested', {
  resetLink: 'https://example.com/reset/abc123'
});

The key differences between transactions and campaigns:

  • Timing: Transactions send immediately when events occur, campaigns run based on segments
  • Repetition: Transactions send once per event, campaigns can have multiple steps
  • Purpose: Transactions are for immediate responses to user actions, campaigns are for ongoing engagement

5-Minute Quick Start

Let's build a simple winback campaign that emails users who haven't logged in recently, with exponential backoff between attempts.

1. Install Segflow

bun install segflow

2. Create a minimal config

// segflow.config.ts
import type { SegflowConfig } from 'segflow';
import { eq, sql } from 'drizzle-orm';

// Define your user properties
interface UserAttributes {
  email: string;
  name: string;
  lastLoginAt: string;
}

const config: SegflowConfig<UserAttributes> = {
  emailProvider: {
    config: {
      name: "postmark",
      apiKey: process.env.POSTMARK_API_KEY!
    },
    fromAddress: "hello@example.com"
  },

  // Define email templates with React
  templates: {
    'winback': {
      subject: (user) => `We miss you ${user.name}!`,
      component: ({ user }) => (
        <div>
          <h1>Come back and visit us!</h1>
          <p>Hi {user.name}, we noticed you haven't logged in since {user.lastLoginAt}</p>
        </div>
      )
    }
  },

  // Define user segments with SQL
  segments: {
    'inactive-users': {
      evaluator: (db) => db
        .select({ id: schema.users.id })
        .from(schema.users)
        .where(sql`${schema.users.attributes}->>'$.lastLoginAt' < NOW() - INTERVAL 30 DAY`)
    }
  },

  // Define campaign logic with TypeScript
  campaigns: {
    'winback-campaign': {
      segments: ['inactive-users'],
      behavior: 'dynamic',  // Auto-exits when user becomes active again
      flow: function* (ctx, rt) {
        // Send 10 emails with exponential backoff
        for (let i = 0; i < 10; i++) {
          yield rt.sendEmail('winback');
          yield rt.wait({ days: 2 ** i }); // Wait 1, 2, then 4 days
        }
      }
    }
  }
};

export default config;

3. Deploy your automation

bun segflow push

4. Track user activity

import { Client } from 'segflow/client';

const client = await Client.initialize({
  url: 'http://localhost:3000',
  apiKey: 'your-api-key'
});

// Create/update users
await client.createUser('user123', {
  email: 'jane@example.com',
  name: 'Jane',
  lastLoginAt: new Date().toISOString()
});

// Track events
await client.emit('user123', 'login');

That's it! Segflow will automatically:

  • Identify users who haven't logged in for 30+ days
  • Add them to the winback campaign
  • Send emails with increasing delays
  • Remove users from the campaign if they log in again

FAQs

Q: How often do campaigns run?
A: Campaigns run in real-time. As soon as a user enters a segment, they start receiving the campaign. For dynamic campaigns, users exit immediately when they no longer match the segment criteria.

Q: How do you prevent duplicate sends?
A: Segflow tracks each user's progress through campaigns in its database. Users can only be at one step in a campaign at a time.

Q: What databases are supported?
A: Segflow uses MySQL to track its own state. Your application can use any database - you just need to send user events to Segflow via its API.

Q: What email providers are supported?
A: Currently Postmark and Amazon SES. Adding new providers is straightforward through the open-source codebase.

FAQs

Package last updated on 18 Nov 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts