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
- User registration: Send a welcome message via Email and notify your team on Slack when a new user signs up
- E-commerce orders: Alert your fulfillment team on Telegram and send order confirmations to customers via Email
- Error monitoring: Push application errors and exceptions to your dev team on Discord and Telegram in real time
- Payment processing: Send payment confirmations through multiple channels when Stripe or PayPal webhooks fire
- Cron job results: Report the status of scheduled tasks and background jobs to your ops channel on Slack
- Security alerts: Notify administrators on Telegram and Email when suspicious login attempts or permission changes occur