npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@createsend/client

v0.1.1

Published

A modern, typed, promise based wrapper of the Campaign Monitor API.

Downloads

59

Readme

@createsend/client

A modern, typed, promise-based wrapper for the Campaign Monitor API, written in TypeScript.

This package is compatible with the latest version (v3.3) of the CreateSend API.

It will be updated for versions going forward, but may not be compatible with previous versions.

Getting started

Installation

Node 18+

We try to use the native Node fetch API in Node 18 to keep the dependencies to a minimum. If you are using Node 18+ (or using Node 16.15+/17.15+ with the --experimental-fetch flag) you can install @createsend/client like you would any other NPM package.

Yarn

> yarn add @createsend/client

you can also safely run (which will ensure the optional dependency node-fetch is ignored)

> yarn add --ignore-optional @createsend/client

NPM

> npm install @createsend/client

Older Node Versions (incl. 12, 14, 16)

The native fetch API is not included in older versions of Node. To use this package, all you need to do is have node-fetch installed in your project as well. node-fetch is listed as an optional dependency of this project, so your npm client should resolve and install it by default. But to be extra safe it's recommended to explicitly install node-fetch as a dependency also. We specify node-fetch@^2.6.9 as the newer node-fetch@3 has dropped support for CJS. If you are using ESM in your project you can safely install the latest version of node-fetch. If you don't know what that means, install the version shown below.

Yarn

> yarn add @createsend/client node-fetch@^2.6.9

NPM

> npm install @createsend/client node-fetch@^2.6.9

For a full example of a project setup with an older Node version see the node-fetch sample.

Usage

Instatiate an instance of the api by specifying your ApiKey (either the account-wide or client-specific key).

import {CreateSend, CreateSendErrorCode} from '@createsend/client';

const apiKey = process.env.CM_API_KEY ?? '';
const createSend = CreateSend({apiKey});

// you can also use an OAuth access token, instead of an api key!
const accessToken = process.env.CM_ACCESS_TOKEN ?? '';
const createSendUsingOAuth = CreateSend({accessToken});

const clientsResponse = await createSend.account.getClients();
if (!clientsReponse.success) {
    if (countriesResponse.data.code === CreateSendErrorCode.InvalidOAuthToken) {
        console.log('That\'s the wrong token!');
        process.exit(1);
    }

    console.log(`unknown error: ${countriesResponse.data.message}`, countriesResponse.data.code);
    process.exit(1);
}

console.log(clientsResponse.data) // [{"clientId": "a1a1a1", "name": "Bob's Burgers"}, {"clientId": "b1b1b1", "name": "Bob's Marketing Agency"}] ;

Handling Responses

All methods will return a CreateSendResponse. All responses have 2 properties: success (boolean) and status (number). success = true indicates the request recieved a response with a 2xx status code (the actual status code will be surfaced in the status) value.

There are 2 types of CreateSendResponse - CreateSendSuccessResponse and CreateSendErrorResponse.

If CreateSendResponse.success is true, CreateSendResponse.data will have the JSON response from the server if provided (some routes such as deleting / updating a resource don't have a response).

If CreateSendResponse.success is false, CreateSendResponse.data will be an object consisting of 2 fields code and message. code is an enum value CreateSendErrorCode. It can be used to handle specific server side errors. A full list of errors can be found in the API Documentation.

const createClient = async () => {
    const createClientResponse = await createSend.clients.create({timeZone: 'Australia',
        country: '(GMT+10:00) Canberra, Melbourne, Sydney'});

    // first check if the response was successful. If you are using TypeScript, it won't let you access the `createClientResponse.data` value without this check.
    if (!createClientResponse.success) {
        // handle any specific errors like this
        if (createClientResponse.data.code === CreateSendErrorCode.EmptyCompanyName) {
            console.log('Company name not provided');
            return;
        }

        console.log(`unknown error: ${countriesResponse.data.message}`, countriesResponse.data.code);
        return;
    }

    // if we get here, the call was successful! we can now access the clientId at `createClientResponse.data`;
    console.log(`Client created. ClientId = ${createClientResponse.data}`);
}

Casing

The Campaign Monitor API uses PascalCase for property names. To better fit with your JS/TS applications, this wrapper uses camelCase for both request and response objects. Keep that in mind when viewing the docs.

e.g. when viewing the docs the AddSingleSubscriber request looks like

{
    "EmailAddress": "[email protected]",
    "Name": "New Subscriber",
}

But in our wrapper you'll want to do:

cs.subscribers.addSingleSubscriber(listId, {emailAddress: "[email protected]", name: "New Subscriber"});

This is the same for both request and response objects.

The other change to look out for is acronyms like ID, URL or IP. To follow camelCase convetions we translate this to Id, Url, Ip. So in the API docs CampaignID becomes campaignId.

See more usage examples in the samples directory.

OAuth

OAuth authentication flow is supported through this wrapper. See the API docs for a full explanation of the OAuth process.

import {CreateSendOAuth, CreateSend} from '@createsend/client';
import {CreateSendOAuthScope} from '@createsend/client/dist/cjs/models/oauth.js';

const oAuth = CreateSendOAuth();
const oAuthClientId = '1234' // your app's clientId.

const url = oauth.buildAuthorizationUrl(oAuthClientId, {
    type: 'web_server',
    scopes: [CreateSendOAuthScope.AdministerAccount],
    redirectUri: 'https://example/oauth/complete',
});

// redirect user to URL, a `code` will be provided in the query params.

const code = `code_sent_to_your_webserver`;
   
const oAuthResponse = await oauth.getToken('125838', {
        clientSecret: 'shhh',
        code,
        redirectUri: 'https://example/oauth/complete',
    });

if (!res.success) {
    console.log('oh no!', res.data);
    throw new Error("bad_ex");
}

console.log(res.data) // {"access_token": "abc", expiresIn: 12600, "refresh_token": "bca"} ;

const cs = CreateSend({accessToken: res.data.access_token});

Not supported

  • Frameable endpoints

All other routes documented at https://www.campaignmonitor.com/api/ are supported.