Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@uninspired/plunk-client

A TypeScript client for the Plunk HTTP API.

Targets the legacy Plunk API at https://api.useplunk.com (/v1/* routes). Self-hosted instances using the same API shape are also supported.

Automatically parses JSON-encoded contact data fields in responses.

Requirements

  • A runtime that supports fetch, Buffer and async/await (Node.js >= 18, bun or deno, optionally the browser with a buffer polyfill)

Installation

npm install @uninspired/plunk-client

Usage

Initializing the client

import { PlunkApiClient } from "@uninspired/plunk-client";

const PLUNK_BASE_URL = "https://api.useplunk.com";
const PLUNK_API_KEY = "sk_your_secret_key";

const plunkApiClient = new PlunkApiClient(PLUNK_BASE_URL, PLUNK_API_KEY);

For trackEvent, you can also use a public key (pk_*) instead of your secret key:

const trackClient = new PlunkApiClient(PLUNK_BASE_URL, "pk_your_public_key");

Automations

Track an event

const res = await plunkApiClient.trackEvent({
  event: "signed_up",
  email: "user@example.com",
  subscribed: true,
  data: {
    foo: "bar",
  },
});

Transactional

Send an email

You can provide attachments to the email by providing an array of JavaScript File objects. They will automatically be converted to base64 with the necessary metadata.

const attachment = new File([], "test.txt");

const res = await plunkApiClient.sendEmail({
  to: "user@example.com",
  subject: "Hello",
  body: "Hello, this is a test email.",
  subscribed: true,
  name: "John Doe",
  from: "sender@example.com",
  reply: "reply@example.com",
  headers: {
    "X-Custom-Header": "Test",
  },
  attachments: [attachment],
});

// Recipient address is on the nested contact object
const recipient = res.emails[0]?.contact.email;

Campaigns

Campaign style accepts "PLUNK" or "HTML". "PLUNK" is sent to the API as "SANS".

Create a campaign

const res = await plunkApiClient.createCampaign({
  subject: "Hello",
  body: "Hello, this is a test email.",
  recipients: ["user@example.com"],
  style: "PLUNK",
});

Send a campaign

await plunkApiClient.sendCampaign("[CAMPAIGN_ID]", {
  live: true, // Should the campaign be sent to the recipients
  delay: 5, // in minutes
});

Update a campaign

const res = await plunkApiClient.updateCampaign("[CAMPAIGN_ID]", {
  subject: "Hello",
  body: "Hello, this is a test email.",
  recipients: ["user@example.com"],
  style: "PLUNK",
});

Delete a campaign

const res = await plunkApiClient.deleteCampaign("[CAMPAIGN_ID]");

Contacts

Get a contact by ID

interface ContactData {
  foo: string;
}

const res = await plunkApiClient.getContactById<ContactData>("[CONTACT_ID]");

Get all contacts

interface ContactData {
  foo: string;
}

const res = await plunkApiClient.getAllContacts<ContactData>();

Get number of contacts

const res = await plunkApiClient.getNumberOfContacts();

Create a contact

interface ContactData {
  foo: string;
}

const res = await plunkApiClient.createContact<ContactData>({
  email: "user@example.com",
  subscribed: true,
  data: {
    foo: "bar",
  },
});

Subscribe a contact

// Subscribe contact by ID
const res = await plunkApiClient.subscribeContact({ id: "[CONTACT_ID]" });

// Subscribe contact by email
const res = await plunkApiClient.subscribeContact({
  email: "user@example.com",
});

Unsubscribe a contact

// Unsubscribe contact by ID
const res = await plunkApiClient.unsubscribeContact({ id: "[CONTACT_ID]" });

// Unsubscribe contact by email
const res = await plunkApiClient.unsubscribeContact({
  email: "user@example.com",
});

Update a contact

interface ContactData {
  foo: string;
}

const res = await plunkApiClient.updateContact<ContactData>({
  id: "[CONTACT_ID]",
  subscribed: true,
  data: { foo: "bar" },
});

Delete a contact

const res = await plunkApiClient.deleteContact({ id: "[CONTACT_ID]" });

Development

Scripts

bun run build      # Build ESM, CJS, and type declarations
bun run typecheck  # Type-check src and tests
bun test           # Run integration tests against the live API

Integration tests

Tests run against the real Plunk API. Copy .env.example to .env and fill in your credentials:

cp .env.example .env
Variable Description
PLUNK_SECRET_KEY Secret API key (sk_*) for most endpoints
PLUNK_PUBLIC_KEY Public API key (pk_*) for trackEvent tests
PLUNK_BASE_URL API base URL (https://api.useplunk.com)
PLUNK_TEST_EMAIL Inbox used for send/track tests
PLUNK_TEST_FROM Verified sender address for email tests

Features

Providing types for the arbitrary "data" field

Any request or response that contains a "data" field can have its type enforced by providing a type argument to the respective method.

Note: The data is not validated, it is simply typed.

interface ContactData {
  foo: string;
  bar?: string;
}

const res = await plunkApiClient.getContactById<ContactData>("[CONTACT_ID]");

// res.data will be of type ContactData

This will throw a TypeScript error:

interface ContactData {
  foo: string;
}

const res = await plunkApiClient.trackEvent<ContactData>({
  event: "signed_up",
  email: "user@example.com",
  data: {
    bar: "bar",
  },
});

About

A TypeScript client for the useplunk.com HTTP API

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages