Postmark Node.js Client Library

repository·main·Indexed 18 days ago

https://github.com/activecampaign/postmark.js

Official Node.js client library for the Postmark HTTP API (version 5.1.0). It enables Node.js applications to send and parse emails, manage bulk email requests, and query message tracking data. The library requires Node.js v18.0.0 or higher due to its reliance on the native Fetch API. It includes comprehensive support for API error handling via PostmarkError, custom fetch implementations for corporate proxies, and detailed filtering parameters for outbound and inbound messages.

Tokens
7.5K
Snippets
30
Records
33
Agent score
63%

What's inside postmark.js

  1. Check Node.js version requirements

    main

    The library requires a minimum Node.js version of v18.0.0 because it relies on the native Fetch API and has no runtime dependencies.

    Version Compatibility:

    • Node 18–20: The Fetch API is available but may emit an ExperimentalWarning: The Fetch API is an experimental feature from the Node runtime.
    • Node 21+: The global Fetch API is stable.
    • Node < 18: You must use older versions of the library:
      • Use 4.x.x for Node versions between 14 and 18.
      • Use 3.x.x for Node versions < 14.
  2. Configure a custom fetch client or proxy

    main

    The library uses Node's built-in fetch (undici), which does not automatically respect HTTP_PROXY, HTTPS_PROXY, or NO_PROXY environment variables. To run behind a corporate egress proxy, you must provide a custom fetch implementation via the fetch option in the ServerClient constructor. You can use an undici ProxyAgent for this purpose. This option can also be used to inject mock fetch implementations for testing.

    import { ServerClient } from "postmark";
    import { ProxyAgent } from "undici";
    
    const dispatcher = new ProxyAgent("http://proxy.internal:8080");
    
    const client = new ServerClient("server-token", {
        fetch: (input, init) => fetch(input, { ...init, dispatcher }),
    });
  3. Use a custom fetch implementation for proxies

    main

    Node's built-in fetch (undici) does not automatically respect HTTP_PROXY, HTTPS_PROXY, or NO_PROXY environment variables. To route Postmark requests through a corporate egress proxy or to customize the transport layer, you must provide a custom FetchImplementation via the Configuration object.

    A FetchImplementation follows the standard fetch signature: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>

    import { ClientOptions } from 'postmark';
    
    // Example: Using a custom fetch implementation (e.g., one configured with a ProxyAgent)
    const customFetch: ClientOptions.FetchImplementation = async (input, init) => {
      // Your custom proxy/transport logic here
      return fetch(input, init);
    };
    
    const config = new ClientOptions.Configuration(
      true, 
      undefined, 
      undefined, 
      customFetch
    );
  4. Handle Postmark API errors

    main

    When using the Postmark library, errors returned from the API follow a specific hierarchy. All errors inherit from PostmarkError, which contains a code (application-specific error code) and a statusCode (HTTP status code).

    Error Hierarchy

    • PostmarkError: The base class for all errors.
      • HttpError: Errors resulting from HTTP communication issues.
        • InvalidAPIKeyError: Occurs when the provided API key is incorrect.
        • InternalServerError: Occurs when Postmark encounters an internal error.
        • ServiceUnavailablerError: Occurs when the service is temporarily unavailable.
        • RateLimitExceededError: Occurs when you have exceeded your API rate limits.
        • UnknownError: A fallback for unexpected HTTP errors.
        • ApiInputError: Errors caused by invalid input data.
          • InactiveRecipientsError: Specifically for errors involving inactive email addresses.
          • InvalidEmailRequestError: Specifically for malformed email requests.
  5. Configure the Postmark Client via Configuration

    main

    The ClientOptions.Configuration class allows you to customize the transport and connection settings for the Postmark client. This is particularly useful for setting custom timeouts, changing the request host, or routing traffic through a proxy.

    Available configuration properties:

    • useHttps: Boolean indicating whether to use HTTPS.
    • requestHost: A custom string for the request host.
    • timeout: A number representing the request timeout.
    • fetch: A custom FetchImplementation to override the default fetch behavior (e.g., to support corporate proxies).
    import { ClientOptions } from 'postmark';
    
    const config = new ClientOptions.Configuration(
      true,           // useHttps
      'api.custom.com', // requestHost
      5000,           // timeout in ms
      customFetchFn   // fetch implementation
    );
  6. Configure BounceFilteringParameters for bounce data queries

    main

    Use the BounceFilteringParameters class to specify filters when retrieving bounce data. This class extends FilteringParameters, meaning it includes pagination options like count and offset.

    Available filtering properties:

    • type: Filter by BounceType.
    • inactive: Boolean to filter for inactive bounces.
    • emailFilter: A string to filter by email address.
    • tag: Filter by a specific tag.
    • messageID: Filter by a specific Postmark Message ID.
    • fromDate: A date string to filter bounces from a certain point.
    • toDate: A date string to filter bounces up to a certain point.
    • messageStream: Filter by a specific message stream name.
    import { BounceFilteringParameters } from 'postmark';
    // Note: BounceType must be imported from './Bounce'
    
    const params = new BounceFilteringParameters(
      100,               // count (default: 100)
      0,                 // offset (default: 0)
      BounceType.Hard,   // type
      false,             // inactive
      'user@example.com', // emailFilter
      'my-tag',          // tag
      'message-id-123', // messageID
      '2023-01-01',      // fromDate
      '2023-12-31',      // toDate
      'outbound-stream'  // messageStream
    );
  7. Filter outbound message tracking (Opens and Clicks)

    main

    Use OutboundMessageTrackingFilteringParameters, OutboundMessageOpensFilteringParameters, or OutboundMessageClicksFilteringParameters to query tracking data. These classes allow deep filtering based on client information (name, company, family), operating system details (name, family, company), platform, and geographic location (country, region, city).

    import { OutboundMessageOpensFilteringParameters } from 'postmark';
    
    const params = new OutboundMessageOpensFilteringParameters(
      100, // count
      0,   // offset
      'user@example.com', // recipient
      'open-tag', // tag
      'Chrome', // client_name
      undefined, // client_company
      undefined, // client_family
      'Windows', // os_name
      'Windows', // os_family
      'Microsoft', // os_company
      'desktop', // platform
      'US', // country
      'California', // region
      'San Francisco', // city
      'outbound-stream' // messageStream
    );
  8. Handle Postmark errors

    main

    All error types thrown by the client are available via the Errors export. Use these to perform type-guarded error handling when catching exceptions from client methods.

    import { Errors } from 'postmark';
    
    try {
      await client.sendEmail(...);
    } catch (error) {
      if (error instanceof Errors.SomeSpecificError) {
        // Handle specific error
      }
    }
  9. Extract inactive recipients from InactiveRecipientsError

    main

    If you catch an InactiveRecipientsError, you can access the recipients property to get a list of the specific email addresses that were flagged as inactive by the Postmark API. The error automatically parses these addresses from the error message using internal regex patterns.

    try {
      await postmarkClient.sendEmail(...);
    } catch (error) {
      if (error instanceof InactiveRecipientsError) {
        console.log('The following recipients are inactive:', error.recipients);
        // error.recipients is a string[]
      }
    }
  10. Filter inbound messages

    main

    Use InboundMessagesFilteringParameters to query inbound messages. Supports pagination via count and offset (defaulting to 100 and 0 respectively). Filtering options include mailboxHash, recipient, fromEmail, tag, status, fromDate, toDate, and subject.

    import { InboundMessagesFilteringParameters, InboundMessageStatus } from 'postmark';
    
    const params = new InboundMessagesFilteringParameters(
      10, // count
      0,  // offset
      'hash_abc123', // mailboxHash
      'recipient@example.com', // recipient
      undefined, // fromEmail
      'inbound-tag', // tag
      InboundMessageStatus.Processed, // status
      '2023-01-01', // fromDate
      undefined, // toDate
      undefined  // subject
    );
  11. Filter outbound messages

    main

    Use OutboundMessagesFilteringParameters to query outbound messages. This class supports pagination via count and offset (defaulting to 100 and 0 respectively) and allows filtering by recipient, sender, tags, status, date ranges, subject, and message stream. It also supports arbitrary metadata filtering using keys prefixed with metadata_ via index signature access.

    import { OutboundMessagesFilteringParameters, OutboundMessageStatus } from 'postmark';
    
    const params = new OutboundMessagesFilteringParameters(
      50, // count
      0,  // offset
      'user@example.com', // recipient
      undefined, // fromEmail
      'welcome-tag', // tag
      OutboundMessageStatus.Sent, // status
      '2023-01-01', // fromDate
      '2023-12-31', // toDate
      'Hello World', // subject
      'outbound-stream' // messageStream
    );
    
    // You can also add custom metadata filters
    params['metadata_custom_id'] = '12345';