This is the official node.js module for sending notifications with node.js with the Courier REST API.
Courier docs • 3 Different Ways To Send Emails With Node.js
Installation (via npm)
npm install @trycourier/courier
Requirements
You will need to get a Courier API key to get started. You can sign up and create one for free at courier.com.
Getting Started
import { CourierClient } from "@trycourier/courier";
const courier = CourierClient({ authorizationToken: "<AUTH_TOKEN>" });
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"],
},
},
});
const { requestId } = await courier.send({
message: {
to: {
data: {
name: "Jenny",
},
phone_number: "8675309",
},
content: {
title: "Back to the Future",
body: "Oh my {{name}}, we need 1.21 Gigawatts!",
},
routing: {
method: "single",
channels: ["sms"],
},
},
});
const { requestId } = await courier.send({
message: {
to: [
{
user_id: "<USER_ID>",
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"],
},
},
});
const { requestId } = await courier.send({
message: {
template: "<TEMPLATE_OR_EVENT_ID>",
to: {
user_Id: "<USER_ID>",
email: "example@example.com",
phone_number: "555-228-3890",
},
data: {},
},
});
const { requestId } = await courier.send({
message: {
template: "<TEMPLATE_OR_EVENT_ID>",
to: {
list_id: "<LIST_ID>",
},
data: {},
},
});
const { requestId } = await courier.send({
message: {
template: "<TEMPLATE_OR_EVENT_ID>",
to: {
list_pattern: "<PATTERN>",
},
data: {},
},
});
const { requestId } = await courier.send({
message: {
to: [
{
list_pattern: "<PATTERN>",
},
{
list_id: "<LIST_ID>",
},
{
email: "test@email.com"
}
]
},
routing: {
method: "single",
channels: ["email"],
},
},
});
Environment Variables
courier-node
supports credential storage in environment variables. If no authorizationToken
is provided when instantiating the Courier client (e.g., const courier = CourierClient();
), the value in the COURIER_AUTH_TOKEN
env var will be used.
If you need to use a base url other than the default https://api.courier.com, you can set it using the COURIER_BASE_URL
env var.
Advanced Usage
import { CourierClient } from "@trycourier/courier";
const courier = CourierClient({ authorizationToken: "<AUTH_TOKEN>" });
async function run() {
const { requestId } = await courier.send({
message: {
template: "<TEMPLATE_OR_EVENT_ID>",
to: {
user_id: "<RECIPIENT_ID>",
},
data: {},
brand_id: "<BRAND_ID>",
routing: {},
channels: {},
providers: {},
},
});
console.log(requestId);
const messageStatus = await courier.getMessage(requestId);
console.log(messageStatus);
const { results } = await courier.getMessageHistory(requestId);
console.log(results);
const { results } = await courier.getMessageOutput(requestId);
console.log(results);
const { paging, results } = await courier.getMessages();
console.log(results);
const { status: replaceStatus } = await courier.replaceProfile({
recipientId: "<RECIPIENT_ID>",
profile: {
email: "example@example.com",
},
});
console.log(replaceStatus);
const { status: mergeStatus } = await courier.mergeProfile({
recipientId: "<RECIPIENT_ID>",
profile: {
sms: "555-555-5555",
},
});
console.log(mergeStatus);
const { profile } = await courier.getProfile({
recipientId: "<RECIPIENT_ID>",
});
console.log(profile);
const { paging, results } = await courier.getBrands({
cursor: "<CURSOR>",
});
console.log(results);
const brand = await courier.getBrand("<BRAND_ID>");
console.log(brand);
const newBrand = await courier.createBrand({
name: "My Brand",
settings: {
colors: {
primary: "#0000FF",
secondary: "#FF0000",
tertiary: "#00FF00",
},
},
});
console.log(newBrand);
const replacedBrand = await courier.replaceBrand({
id: "<BRAND_ID>",
name: "My New Brand",
settings: {
color: {
primary: "#FF0000",
secondary: "#00FF00",
tertiary: "#0000FF",
},
},
});
console.log(replacedBrand);
await courier.deleteBrand("<BRAND_ID>");
const { paging, items } = await courier.lists.list({
cursor: "<CURSOR>",
});
console.log(items);
const list = await courier.lists.get("<LIST_ID>");
console.log(list);
const replacedList = await courier.lists.put("<LIST_ID>", {
name: "My New List",
});
console.log(replacedList);
await courier.lists.delete("<LIST_ID>");
await courier.lists.restore("<LIST_ID>");
const { paging, items } = await courier.lists.getSubscriptions("<LIST_ID>");
console.log(items);
await courier.lists.putSubscriptions("<LIST_ID>", [
{ recipientId: "RECIPIENT_ID_1" },
{ recipientId: "RECIPIENT_ID_2" },
]);
const { recipient } = courier.lists.subscribe("<LIST_ID>", "<RECIPIENT_ID>");
console.log(recipient);
await courier.lists.unsubscribe("<LIST_ID>", "<RECIPIENT_ID>");
const { paging, items } = await courier.lists.findByRecipientId(
"<RECIPIENT_ID>"
);
console.log(items);
await courier.preferences.put(recipientId, {
notifications: {
"<NOTIFICATION_ID>": { status: "<OPT_IN_STATUS>" },
},
});
const prefs = await courier.preferences.list();
console.log(prefs);
const profilePrefs = await courier.preferences.get(recipientId);
console.log(profilePrefs);
const { runId } = await courier.automations.invokeAdHocAutomation({
automation: {
cancelation_token: "I_AM_TOKEN",
steps: [
{
action: "send",
},
],
},
brand: "BRAND_ID",
data: {
example: "EXAMPLE_DATA",
},
profile: {
email: "foo@bar.com",
},
recipient: "RECIPIENT_ID",
template: "TEMPLATE_NAME_OR_ID",
});
console.log(runId);
const { runId } = await courier.automations.invokeAutomationTemplate({
templateId: "AUTOMATION_TEMPLATE_ID",
brand: "BRAND_ID",
data: {
example: "EXAMPLE_DATA",
},
profile: {
email: "foo@bar.com",
},
recipient: "RECIPIENT_ID",
template: "TEMPLATE_NAME_OR_ID",
});
console.log(runId);
const { paging, results } = await courier.notifications.list({});
console.log(results);
const { blocks, channels } = await courier.notifications.getContent(
"notification1"
);
console.log(blocks);
console.log(channels);
const { blocks, channels } = await courier.notifications.getDraftContent(
"notification1"
);
console.log(blocks);
console.log(channels);
await courier.notifications.postVariations("notification1", {
blocks: [
{
id: "block_1d4c32e0-bca8-43f6-b5d5-8c043199bce6",
type: "text",
locales: {
fr_FR: "block fr 1",
},
},
{
id: "block_6d50a6e3-ecc3-4815-bf51-0202c6bf54e2",
type: "text",
locales: {
fr_FR: "block fr 2",
},
},
],
channels: [
{
id: "channel_1ba46024-f156-4ed7-893b-cb1cdcfbd36e",
type: "email",
locales: {
fr_FR: {
subject: "French Subject",
},
},
},
{
id: "channel_2c2aad1c-30f0-4a55-8d8f-d213f32147bc",
type: "push",
locales: {
fr_FR: {
title: "French Title",
},
},
},
],
});
await courier.notifications.postDraftVariations("notification1", {
blocks: [
{
id: "block_1d4c32e0-bca8-43f6-b5d5-8c043199bce6",
type: "text",
locales: {
fr_FR: "block fr 1",
},
},
{
id: "block_6d50a6e3-ecc3-4815-bf51-0202c6bf54e2",
type: "text",
locales: {
fr_FR: "block fr 2",
},
},
],
channels: [
{
id: "channel_1ba46024-f156-4ed7-893b-cb1cdcfbd36e",
type: "email",
locales: {
fr_FR: {
subject: "French Subject",
},
},
},
{
id: "channel_2c2aad1c-30f0-4a55-8d8f-d213f32147bc",
type: "push",
locales: {
fr_FR: {
title: "French Title",
},
},
},
],
});
const { checks } = await courier.notifications.getSubmissionChecks(
"notification1",
"submission1"
);
console.log(checks);
const { checks } = await courier.notifications.putSubmissionChecks(
"notification1",
"submission1",
{
checks: [
{
id: "check1",
status: "RESOLVED",
type: "custom",
},
],
}
);
console.log(checks);
await courier.notifications.cancelSubmission("notification1", "submission1");
const response = await courier.bulk.createJob({
message: {
event: "RR4NDQ7NZ24A8TKPWVBEDGE15E9A",
},
});
console.log(response);
const response = await courier.bulk.getJob({
jobId: "1-61efe386-6ff57552409e311b7a1f371f",
});
console.log(response);
const response = await courier.bulk.ingestUsers({
jobId: "1-61efe386-6ff57552409e311b7a1f371f",
users: [
{
profile: {
email: "tejas@courier.com",
},
},
],
});
console.log(response);
await courier.bulk.runJob({
jobId: "1-61efe386-6ff57552409e311b7a1f371f",
});
const response = await courier.bulk.getJobUsers({
jobId: "1-61efe386-6ff57552409e311b7a1f371f",
});
console.log(response);
}
run();
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 "@trycourier/courier";
import uuid4 from "uuid4";
const courier = CourierClient();
const idempotencyKey = uuid4();
async function run() {
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,
}
);
console.log(requestId);
}
run();
License
MIT License
Author
Courier (support@courier.com)