0.2.4 • Published 2 years ago

@fern-api/courier v0.2.4

Weekly downloads
-
License
-
Repository
github
Last release
2 years ago

Courier Node Library

Courier: Your Complete Communication Stack

npm shield fern shield

The Courier Node.js library provides access to the Courier API from JavaScript/TypeScript.

Documentation

API reference documentation is available here.

Installation

npm install --save @fern-api/courier
# or
yarn add @fern-api/courier

Usage

Try it out

import { CourierClient } from "@fern-api/courier";

const courier = new CourierClient();

const { requestId } = await courier.send({
  message: {
    to: {
      data: {
        name: "Marty",
      },
      email: "marty_mcfly@email.com",
    },
    content: {
      title: "Back to the Future",
      body: "Oh my {{name}}, we need 1.21 Gigawatts!",
    },
    routing: {
      method: "single",
      channels: ["email"],
    },
  },
});

Authentication

The client will read the environment variableCOURIER_AUTH_TOKEN by default, but you can also manually specify your token.

import { CourierClient } from "@fern-api/courier";

const courier = new CourierClient({
  token: "ey...." // defaults to process.env["COURIER_AUTH_TOKEN"]
});

Handling errors

When the API returns a non-success status code (4xx or 5xx response), a subclass of CourierError will be thrown:

import { CourierError } from "@fern-api/courier";

try {
    await courier.send(/* ... */);
} catch (err) {
    if (err instanceof CourierError) {
        console.log(err.statusCode);
        console.log(err.message);
        console.log(err.body);
    }
}

Idempotency

For POST methods, you can supply an idempotencyKey in the config parameter to ensure the idempotency of the API Call. We recommend that you use a V4 UUID for the key. Keys are eligible to be removed from the system after they're at least 24 hours old, and a new request is generated if a key is reused after the original has been removed. For more info, see Idempotent Requests in the Courier documentation.

import { CourierClient } from "@fern-api/courier";
import uuid4 from "uuid4";

const courier = CourierClient();
const idempotencyKey = uuid4();

const { requestId } = await courier.send(
  {
    template: "<TEMPLATE_OR_EVENT_ID>",
    to: {
      user_id: "<USER_ID>",
      email: "example@example.com",
      phone_number: "555-867-5309",
    },
    data: {
      world: "JavaScript!",
    },
  },
  {
    idempotencyKey: uuid4(),
  }
);

Retries

408 Request Timeout, 409 Conflict, 429 Rate Limit, and >=500 Internal errors will be retried twice default. Errors will be retried with exponential backoff.

You can use the maxRetries option to configure this behavior.

import { CourierClient } from "@fern-api/courier";

const courier = new CourierClient({
  maxRetries: 0 // disable retries
});

const courier = courier.send({...}, {
  maxRetries: 3 // enable 3 retries with exponential backoff for this request
});

Examples

Below are example code snippets of using the SDK.

Message an SMS recipient

const { requestId } = await courier.send({
  message: {
    to: {
      data: {
        name: "Marty",
      },
      email: "marty_mcfly@email.com",
    },
    content: {
      title: "Back to the Future",
      body: "Oh my {{name}}, we need 1.21 Gigawatts!",
    },
    routing: {
      method: "single",
      channels: ["email"],
    },
  },
});

Message various recipients

const { requestId } = await courier.send({
  message: {
    to: [
      {
        user_id: "<USER_ID>", // usually your system's User ID associated to a Courier profile
        email: "test@email.com",
        data: {
          name: "some user's name",
        },
      },
      {
        email: "marty@email.com",
        data: {
          name: "Marty",
        },
      },
      {
        email: "doc_brown@email.com",
        data: {
          name: "Doc",
        },
      },
      {
        phone_number: "8675309",
        data: {
          name: "Jenny",
        },
      },
    ],
    content: {
      title: "Back to the Future",
      body: "Oh my {{name}}, we need 1.21 Gigawatts!",
    },
    routing: {
      method: "all",
      channels: ["sms", "email"],
    },
  },
});

Send a message supporting email & SMS

const { requestId } = await courier.send({
  message: {
    template: "<TEMPLATE_OR_EVENT_ID>", // get from the Courier UI
    to: {
      user_id: "<USER_ID>", // usually your system's User ID
      email: "example@example.com",
      phone_number: "555-228-3890",
    },
    data: {}, // optional variables for merging into templates
  },
});

Send a message to a list

const { requestId } = await courier.send({
  message: {
    template: "<TEMPLATE_OR_EVENT_ID>", // get from the Courier UI
    to: {
      list_id: "<LIST_ID>", // e.g. your Courier List Id
    },
    data: {}, // optional variables for merging into templates
  },
});

Send a message to a pattern

const { requestId } = await courier.send({
  message: {
    template: "<TEMPLATE_OR_EVENT_ID>", // get from the Courier UI
    to: {
      list_pattern: "<PATTERN>", // e.g. example.list.*
    },
    data: {}, // optional variables for merging into templates
  },
});

Send a message that expires after timeout

const { requestId } = await courier.send({
  message: {
    to: {
      data: {
        name: "Marty",
      },
      email: "marty_mcfly@email.com",
    },
    content: {
      title: "Back to the Future",
      body: "Oh my {{name}}, we need 1.21 Gigawatts!",
    },
    routing: {
      method: "single",
      channels: ["email"],
    },
    timeout: {
      message: 3600000, // 1 hour in milliseconds
    },
  },
});
=

Send a message with a Trace ID

const { requestId } = await courier.send({
  message: {
    to: {
      data: {
        name: "Marty",
      },
      email: "marty_mcfly@email.com",
    },
    content: {
      title: "Back to the Future",
      body: "Oh my {{name}}, we need 1.21 Gigawatts!",
    },
    routing: {
      method: "single",
      channels: ["email"],
    },
    metadata: {
      trace_id: "ravenclaw-for-the-win",
    },
  },
});

Beta status

This SDK is in beta, and there may be breaking changes between versions without a major version update. Therefore, we recommend pinning the package version to a specific version in your package.json file. This way, you can install the same version each time without breaking changes unless you are intentionally looking for the latest version.

Contributing

While we value open-source contributions to this SDK, this library is generated programmatically. Additions made directly to this library would have to be moved over to our generation code, otherwise they would be overwritten upon the next generated release. Feel free to open a PR as a proof of concept, but know that we will not be able to merge it as-is. We suggest opening an issue first to discuss with us!

On the other hand, contributions to the README are always very welcome!

0.2.4

2 years ago

0.2.3

2 years ago

0.2.2

2 years ago

0.1.18

2 years ago

0.1.16

2 years ago

0.1.15

2 years ago

0.1.14

2 years ago

0.1.13

2 years ago

0.1.12

2 years ago

0.1.11

2 years ago

0.1.9

2 years ago

0.1.8

2 years ago

0.1.6

2 years ago

0.1.5

2 years ago

0.1.4

2 years ago

0.1.3

2 years ago

0.1.1

2 years ago

0.1.0

2 years ago

0.0.9

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago