Integration

One-Ping Node.js Integration Guide

Add multi-channel notifications to your Node.js application in minutes. Send messages to Telegram, Email, Slack, and Discord with a single API call. No SDK required.

Getting Started with One-Ping in Node.js

One-Ping's REST API is designed to work with any HTTP client, which means you can integrate it into your Node.js application without installing a dedicated SDK. Whether you are building an Express server, a Next.js application, a serverless function on AWS Lambda, or a CLI tool, the integration is the same: a single POST request with your message, channels, and recipient.

This guide covers everything you need: basic usage with the built-in fetch API, an axios example, a reusable wrapper class, Express middleware for notification triggers, and best practices for error handling and retries.

Quick Start

Get Your API Key

Sign up at app.one-ping.com, navigate to API Keys, and generate a new key. Store it as an environment variable called ONE_PING_API_KEY in your .env file. Never hardcode API keys in your source code.

Configure Your Channels

In the One-Ping dashboard, set up the channels you want to use: add your Telegram bot token, SMTP credentials, Slack webhook URL, or Discord webhook URL. This only needs to be done once.

Send Your First Notification

Make a POST request to https://api.one-ping.com/send with your message payload. The examples below show you exactly how to do this with fetch and axios.

Basic Example with Fetch

Node.js 18+ includes the built-in fetch API, so you do not need any external dependencies. Here is a complete example that sends a notification to three channels at once:

// send-notification.js
const sendNotification = async (message, channels, recipient) => {
  const response = await fetch('https://api.one-ping.com/send', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${process.env.ONE_PING_API_KEY}`
    },
    body: JSON.stringify({
      message,
      channels,
      recipient
    })
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`One-Ping error: ${error.message}`);
  }

  return response.json();
};

// Usage
await sendNotification(
  'New order #1234 from John Doe - $99.00',
  ['telegram', 'email', 'slack'],
  '[email protected]'
);

Example with Axios

If your project already uses axios or you prefer its API, here is the equivalent example. Install axios first with npm install axios:

const axios = require('axios');

const onePing = axios.create({
  baseURL: 'https://api.one-ping.com',
  headers: {
    'Authorization': `Bearer ${process.env.ONE_PING_API_KEY}`,
    'Content-Type': 'application/json'
  },
  timeout: 10000
});

// Send a notification
const result = await onePing.post('/send', {
  message: 'Server CPU usage exceeded 90%',
  channels: ['telegram', 'discord', 'email'],
  recipient: '[email protected]'
});

console.log('Notification sent:', result.data);

Reusable One-Ping Wrapper Class

For production applications, we recommend wrapping the One-Ping API in a reusable class. This gives you a clean interface, built-in retry logic, and consistent error handling across your entire codebase:

// lib/one-ping.js
class OnePing {
  constructor(apiKey, options = {}) {
    this.apiKey = apiKey;
    this.baseURL = options.baseURL || 'https://api.one-ping.com';
    this.timeout = options.timeout || 10000;
    this.retries = options.retries || 2;
  }

  async send(message, channels, recipient, metadata = {}) {
    let lastError;

    for (let attempt = 0; attempt <= this.retries; attempt++) {
      try {
        const controller = new AbortController();
        const timeoutId = setTimeout(
          () => controller.abort(),
          this.timeout
        );

        const response = await fetch(`${this.baseURL}/send`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${this.apiKey}`
          },
          body: JSON.stringify({ message, channels, recipient, metadata }),
          signal: controller.signal
        });

        clearTimeout(timeoutId);

        if (!response.ok) {
          const err = await response.json();
          throw new Error(err.message || `HTTP ${response.status}`);
        }

        return await response.json();
      } catch (error) {
        lastError = error;
        if (attempt < this.retries) {
          await new Promise(r => setTimeout(r, 1000 * (attempt + 1)));
        }
      }
    }

    throw lastError;
  }

  // Convenience methods
  async toTelegram(message, recipient) {
    return this.send(message, ['telegram'], recipient);
  }

  async toSlack(message, recipient) {
    return this.send(message, ['slack'], recipient);
  }

  async toAll(message, recipient) {
    return this.send(message, ['telegram', 'email', 'slack', 'discord'], recipient);
  }
}

module.exports = OnePing;

// Usage
const OnePing = require('./lib/one-ping');
const ping = new OnePing(process.env.ONE_PING_API_KEY);

await ping.send(
  'User signed up: [email protected]',
  ['telegram', 'slack'],
  '[email protected]'
);

Express Middleware for Notification Triggers

If you are building an Express application, you can create middleware that automatically sends notifications on specific events. This pattern is useful for order processing, user registration, error alerting, and more:

// middleware/notify.js
const OnePing = require('../lib/one-ping');
const ping = new OnePing(process.env.ONE_PING_API_KEY);

// Middleware factory for notification triggers
const notifyOn = (channels, messageBuilder) => {
  return async (req, res, next) => {
    // Store original res.json to intercept the response
    const originalJson = res.json.bind(res);

    res.json = async (data) => {
      // Send the response first
      originalJson(data);

      // Then send notification (non-blocking)
      try {
        const message = messageBuilder(req, data);
        const recipient = req.body.email || req.user?.email;
        await ping.send(message, channels, recipient);
      } catch (err) {
        console.error('Notification failed:', err.message);
      }
    };

    next();
  };
};

module.exports = { notifyOn };

// Usage in routes
const { notifyOn } = require('../middleware/notify');

app.post('/api/orders',
  notifyOn(
    ['telegram', 'email', 'slack'],
    (req, data) => `New order #${data.id} from ${req.body.name} - $${req.body.total}`
  ),
  orderController.create
);

Error Handling Best Practices

Notification delivery should never break your application's main flow. Here are the key patterns for robust error handling when using One-Ping in Node.js:

Fire-and-Forget

For non-critical notifications, send them without awaiting the response. Use .catch() to log errors silently without blocking your main logic.

Retry with Backoff

For critical alerts, implement exponential backoff retries. The wrapper class above includes this pattern with configurable retry count.

Timeout Protection

Always set a timeout on HTTP requests. The AbortController pattern prevents requests from hanging indefinitely if One-Ping is slow to respond.

Queue for High Volume

For high-throughput applications, push notifications to a queue (Redis, Bull, or SQS) and process them in a background worker to avoid blocking your API.

Fire-and-Forget Pattern

// Non-blocking notification - does not slow down your API response
app.post('/api/users/register', async (req, res) => {
  const user = await User.create(req.body);

  // Send notification without awaiting (fire-and-forget)
  ping.send(
    `New user registered: ${user.email}`,
    ['telegram', 'slack'],
    '[email protected]'
  ).catch(err => console.error('Notification failed:', err.message));

  res.json({ success: true, user });
});

Global Error Notification Handler

// Express error handler that notifies your team
app.use(async (err, req, res, next) => {
  // Respond to the client
  res.status(500).json({ error: 'Internal server error' });

  // Notify your team about the error
  await ping.send(
    `Error in ${req.method} ${req.path}:\n${err.message}\n\nStack: ${err.stack?.slice(0, 500)}`,
    ['telegram', 'discord'],
    '[email protected]',
    { severity: 'error', path: req.path }
  ).catch(() => {});
});

Environment variables: Always store your One-Ping API key in environment variables, not in source code. Use a .env file locally with the dotenv package, and configure environment variables in your hosting platform (Vercel, Railway, Render, AWS) for production. See our multi-channel notifications guide for more deployment tips.

TypeScript Support

If your project uses TypeScript, here is a typed version of the One-Ping wrapper with full type definitions:

// lib/one-ping.ts
type Channel = 'telegram' | 'email' | 'slack' | 'discord' | 'whatsapp' | 'sms';

interface SendOptions {
  message: string;
  channels: Channel[];
  recipient: string;
  metadata?: Record<string, string>;
}

interface SendResponse {
  success: boolean;
  id: string;
  channels_sent: Channel[];
}

class OnePing {
  private apiKey: string;
  private baseURL: string;

  constructor(apiKey: string, baseURL = 'https://api.one-ping.com') {
    this.apiKey = apiKey;
    this.baseURL = baseURL;
  }

  async send(options: SendOptions): Promise<SendResponse> {
    const response = await fetch(`${this.baseURL}/send`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.apiKey}`
      },
      body: JSON.stringify(options)
    });

    if (!response.ok) {
      throw new Error(`One-Ping error: ${response.status}`);
    }

    return response.json() as Promise<SendResponse>;
  }
}

export default OnePing;

Common Integration Scenarios

Ready to simplify your notifications?

Start free with 100 messages/month. No credit card required.

Get started free