Introduction

Pingui Alert is a lightweight notification service that allows you to send alerts to your Telegram account directly from your code. It's designed to be dead simple to use, with zero configuration required on your server.

System Architecture

Pingui Alert uses a queue-based architecture to ensure reliable alert delivery:

๐Ÿ—๏ธ Architecture Flow:
API Request โ†’ Validation โ†’ Redis Queue โ†’ Worker โ†’ Telegram

Core Components

  • REST API: Receives alerts and enqueues them
  • Redis Queue: Stores pending alerts (max 500 alerts)
  • Queue Worker: Processes alerts at 1 msg/second (Telegram safe limit)
  • Scheduled Jobs: Automatic maintenance tasks
  • Telegram Bot: Interface for managing integrations

Automatic Jobs

The system runs scheduled maintenance tasks:

  • Rate Limit Reset (00:00 daily): Resets daily alert counter to 10 for all users
  • Database Backup (03:00 daily): Creates automatic SQLite database backups
โš ๏ธ Important: Redis is required for Pingui Alert to function. The queue system depends on Redis to store and process alerts. Make sure you have Redis running before starting the application if you are self-hosting it.

Setup & Authentication

To start sending alerts, you need to obtain an API Key from our Telegram bot.

  1. Open Telegram and search for @PinguiAlertBot (or your hosted bot instance).
  2. Start a chat and send the command /start to register.
  3. Send the command /temporal_token to get a temporary access token. (Once you create your first integration, you will get a new permanent token)
  4. Use the API to create your first integration and start sending alerts.
Note: The service is completely free. The 10 alerts per day limit helps prevent service degradation due to Telegram API rate limits and server capacity constraints on @PinguiAlertBot. If your instance is self-hosted, you can increase the limit by setting the MAX_ALERTS environment variable.

The Commandments

To keep Pingui Alert useful and stable for everyone, we adhere to a strict set of rules. Follow these commandments to ensure the best experience.

๐Ÿ“œ The Golden Rule: Pingui Alert is for actionable, critical incidents. It is not a logging service.
  1. I. Critical Use Only
    You shall use it only for critical alerts that must be corrected immediately. Design your system to trigger these alerts sparinglyโ€”only once per incident type (avoid alert storms).
  2. II. Production Standards
    If you send errors from your API using our bot, you must follow production best practices. Ensure your error handling is robust before piping it to an alert.
  3. III. Self-Host for Customization
    If you require any customization (no matter how simple), you shall use the self-hosted option. You can host Pingui Alert anywhere; we suggest a VPS or a local server due to its minimal resource footprint, but cloud options are also valid.
  4. IV. Actionable Alerts
    You shall ensure every alert is actionable. Every alert should prompt a specific, immediate response.
  5. V. No Data Leakage
    You shall not send sensitive user data (PII), identifiers, or secrets in your alerts. Keep messages safe and compliant.
  6. VI. Fail Safely
    You shall implement error handling so that a failed alert notification never crashes your main application. The alert service failure should be silent to your end users.

Self-Hosting

Pingui Alert is fully open source and can be self-hosted for complete control over your alerting infrastructure.

Prerequisites

  • Node.js: v20 or higher
  • pnpm: v9 or higher
  • Redis: For queue system (local or hosted)
  • Telegram Bot Token: Create via @BotFather

Quick Setup

git clone https://github.com/juanvidev1/pingui-alert
cd pingui-alert
pnpm install

# Configure environment
cp .env.example .env
# Edit .env with your values

# Run in development
pnpm run dev

# Or build for production
pnpm run build
pnpm run start

Environment Variables

# Required
BOT_TOKEN=your_telegram_bot_token
JWT_SECRET=your_jwt_secret
REDIS_URL=redis://localhost:6379

# Optional
MAX_ALERTS=100  # Customize daily limit
MAX_QUEUE_SIZE=500
SEND_DELAY_MS=1000

Monitoring & Logs

Pingui Alert provides comprehensive logging and monitoring capabilities:

Log Files

  • logs/info.log: General events and processed alerts
  • logs/error.log: Application errors and send failures
  • logs/jobs.log: Scheduled job execution

Monitoring Commands

# View alerts in real time
tail -f logs/info.log | grep "Sending alert"

# Monitor errors
tail -f logs/error.log

# Check job status
tail -f logs/jobs.log

# Redis queue size
redis-cli LLEN pingui:queue:alerts

System Metrics

Track system usage and performance with built-in metrics:

GET /api/metrics

Available Metrics

  • Total Integrations: Number of registered integrations
  • Total Sent Alerts: Cumulative alerts delivered
  • Total Errors: Failed alert attempts
  • Last Updated: Metrics freshness timestamp

Example Response

{
  "totalIntegrations": 1234,
  "totalSentAlerts": 45678,
  "totalErrors": 23,
  "metrics": [
    {
      "totalIntegrations": 1234,
      "totalSentAlerts": 45678,
      "totalErrors": 23,
      "updatedAt": "2025-01-01T12:00:00Z"
    }
  ]
}

Production Usage

When using Pingui Alert in production environments, follow these best practices to ensure optimal service quality for everyone.

โš ๏ธ Important: If you're using the hosted @PinguiAlertBot instance in production, please reserve it exclusively for critical alerts (e.g., system failures, security incidents, critical errors). This helps maintain service availability for all users.

Recommended Production Setup

For production workloads with frequent notifications, we recommend one of these approaches:

  • Self-Host Your Instance: Deploy your own Pingui Alert server and bot. This gives you full control over rate limits and ensures dedicated resources.
  • Use for Critical Alerts Only: If using @PinguiAlertBot, implement filtering logic to send only high-priority notifications (failures, errors, security events).
  • Implement Batching: Group multiple non-critical alerts into periodic summary messages instead of sending individual notifications.

API Reference

Here you can find the API reference for the Pingui Alert service.

Send an Alert

Send a POST request to the /alert endpoint to deliver a message.

Send an Alert

Send a POST request to the /alert endpoint to deliver a message.

POST /alert

Headers

Header Value Description
Authorization Bearer <YOUR_API_KEY> Your permanent JWT token received from /createIntegration endpoint.
Content-Type application/json Required.

Body

{
    "title": "Your title here",
    "message": "Your message here",
    "chatId": "The telegram chat id where the alert will be sent"
  }

Example (cURL)

curl -X POST https://pingui-alert.dev/api/alert \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"title": "Your title here", "message": "Your message here", "chatId": "The telegram chat id where the alert will be sent"}'

Create Integration

Create a new integration for a specific chat using the temporal token. The scope is a string open to the user criteria

POST /createIntegration

Headers

Header Value Description
Authorization Bearer <TEMPORAL_TOKEN> The temporal token received from the /temporal_token command.
Content-Type application/json Required.

Body

{
  "chatId": 123456789,
  "scope": "prod"
}

Example (cURL)

curl -X POST https://pingui-alert.dev/api/createIntegration \
  -H "Authorization: Bearer YOUR_TEMPORAL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"chatId": 123456789, "scope": "prod"}'

Get Integration

Retrieve details about a specific integration.

Get Integration

Retrieve details about a specific integration.

GET /integrations/:chatId

Headers

Header Value Description
Authorization Bearer <YOUR_API_KEY> Your JWT token (API Key).

Example (cURL)

curl -X GET https://pingui-alert.dev/api/integrations/123456789 \
    -H "Authorization: Bearer YOUR_API_KEY"

Update Rate Limit

Update the rate limit for a specific integration.

POST /updateRateLimit

Headers

Header Value Description
Authorization Bearer <YOUR_API_KEY> Your JWT token (API Key).
Content-Type application/json Required.

Body

{
    "chatId": 123456789,
    "rateLimit": 50
  }

Example (cURL)

curl -X POST https://pingui-alert.dev/api/updateRateLimit \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"chatId": 123456789, "rateLimit": 50}'

Alert Members

Send an alert to all active members of your integration.

Alert Members

Sends an alert to all active members linked to your integration.

POST /alert/members

Headers

Header Value Description
Authorization Bearer <YOUR_API_KEY> Your permanent JWT token.
Content-Type application/json Required.

Body

{
  "chatId": 123456789,
  "title": "Deployment Alert",
  "message": "Production deployment failed."
}

Response

{
  "message": "Alert enqueued to members",
  "succesNotifications": 3,
  "totalMembers": 4
}

Example (cURL)

curl -X POST https://pingui-alert.dev/api/alert/members \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"chatId": 123456789, "title": "Deployment Alert", "message": "Production deployment failed."}'

Get Integration Members

Retrieve all members linked to an integration.

Get Integration Members

GET /integration-members?chatId=:chatId

Headers

Header Value Description
Authorization Bearer <YOUR_API_KEY> Your JWT token (API Key).

Query Parameters

Parameter Description
chatId Your Telegram chat ID (owner).

Example (cURL)

curl -X GET "https://pingui-alert.dev/api/integration-members?chatId=123456789" \
  -H "Authorization: Bearer YOUR_API_KEY"

Change Member Status

Enable or disable a member from receiving alerts.

Change Member Status

POST /change-member-status

Headers

Header Value Description
Authorization Bearer <YOUR_API_KEY> Your JWT token (API Key).
Content-Type application/json Required.

Body

{
  "chatId": 987654321,
  "integrationId": 1,
  "activeMember": false
}

Example (cURL)

curl -X POST https://pingui-alert.dev/api/change-member-status \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"chatId": 987654321, "integrationId": 1, "activeMember": false}'

Revoke Integration

Revoke (deactivate) an integration.

Revoke Integration

Revoke (deactivate) an existing integration.

POST /revokeIntegration

Headers

Header Value Description
Authorization Bearer <YOUR_API_KEY> Your JWT token (API Key).
Content-Type application/json Required.

Body

{
    "chatId": 123456789
  }

Example (cURL)

curl -X POST https://pingui-alert.dev/api/revokeIntegration \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"chatId": 123456789}'

Telegram Bot Commands

All interactions with Pingui Alert start from the Telegram bot. Below is the full reference for available commands.

๐Ÿ“Œ Note for members: If you are going to join an integration as a member (not the owner), you must run /start on the bot first so the system can register your chat ID before you can receive alerts.

General Commands

/help

Returns a link to the official documentation.

/help

Returns a link to the official documentation.

/help

Response: A message with the link to https://pingui-alert.dev/docs.

/get_me

Returns your Telegram chat ID. You will need this to send alerts via the API.

/get_me

Returns your Telegram chat ID. You will need this value as the chatId field in all API requests.

/get_me

Response: Your user id is: 123456789

/temporal_token

Generates a short-lived token (5 min) to create your first integration.

/temporal_token

Generates a temporary JWT token valid for 5 minutes. Use it immediately with the POST /createIntegration endpoint to get your permanent API key.

/temporal_token

Response: This is your temporal token, it will expire in 5 minutes: <token>

Member Commands

/join <code>

Join an integration as a member using an invite code.

/join <code>

Joins an existing integration as a member. The invite code must be provided by the integration owner via /create_invite.

โš ๏ธ Prerequisite: You must have run /start on the bot at least once before using this command, otherwise the system won't be able to register you.
/join ABC123

Response: Joined successfully

Owner-Only Commands

These commands require an active integration and are restricted to the integration owner.

/join_owner

Adds yourself (the owner) as a member of your own integration.

/join_owner

Registers the integration owner as a member so they also receive alerts sent to POST /alert/members.

/join_owner

/create_invite

Generates an invite code to share with people you want to add as members.

/create_invite

Creates a new invite code for your integration. Share this code with anyone you want to add as a member โ€” they must use /join <code> to join.

/create_invite

Response: The code for joining the integration alerts is ABC123

/get_members

Opens a panel to view and manage your integration members.

/get_members

Returns a list of all members in your integration and opens a web panel to enable or disable them.

/get_members

Response: A message with an inline button to open the members management panel.

NPM Package

If you are using Node.js or TypeScript, we recommend using our official package in case you just want to send alerts using Pingui Alert server. Rate limit and quota are handled by the server and you need to still use the endpoint createIntegration to get your permanent API KEY.

Installation

npm install pingui-alert

Usage

  1. Follow the steps in the Create Integration section to get your permanent API KEY.
  2. On the public bot use the command /get_me to get your chatId.
  3. Use the API KEY and chatId in the code below:
import { PinguiAlert } from 'pingui-alert-sdk';

const pinguiAlert = new PinguiAlert({
  chatId: process.env.PINGUI_ALERT_CHAT_ID,
  token: process.env.PINGUI_ALERT_API_KEY,
});

// Optional: Validate integration status before sending an alert. This checks if the integration is active and has quota.
const pinguiStatus = await pinguiAlert.validateStatus();
console.log('Pingui Alert status:', pinguiStatus); // Example response: { active: true, remainingAlerts: 9 }

// This method allows you to send an alert. The first parameter is the message to be sent. The second parameter is optional and can be used to set a title for the alert
await pinguiAlert.send('Database backup completed successfully! โœ…', 'Job Completed');

Use Cases

Here are some clear examples of how to apply Pingui Alert in real-world scenarios, strictly adhering to the Commandments.

1. Critical Error Monitoring (Payment Gateway)

Scenario: A user's payment fails due to a server-side 500 error.
Commandments Applied: I (Critical Use Only), V (No Data Leakage).

payment.controller.ts
try {
  await processPayment(orderId, amount);
} catch (error) {
  // โŒ BAD: Sending the full error stack or user PII
  // await client.send(`Payment failed for user ${user.email}: ${error.stack}`);

  // โœ… GOOD: Actionable, specific, safe
  logger.error(error); // Log details locally
  await client.send(
    `๐Ÿšจ Critical: Payment Gateway Failure\n` +
    `Gateway: Stripe\n` +
    `OrderId: ${orderId}\n` +
    `Action: Check Stripe Status & Logs immediately.`
  );
}

2. System Resource Monitoring

Scenario: Server disk space is dangerously low.
Commandments Applied: I (Critical Use Only), IV (Actionable).

health-check.sh
#!/bin/bash
USAGE=$(df / | grep / | awk '{ print $5 }' | sed 's/%//g')

# Only alert if usage is > 90% (Critical)
if [ "$USAGE" -gt 90 ]; then
  curl -X POST https://pingui-alert.dev/api/alert \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "alert": "๐Ÿ’พ Server Disk Critical\nUsage is at '"$USAGE"'%.\nClean up logs or expand volume NOW."
    }'
fi

3. Security Incidents

Scenario: Multiple failed login attempts detected from a single IP (Brute Force).
Commandments Applied: I (Critical), V (No PII).

auth.middleware.ts
if (failedAttempts > 10) {
  // Block IP logic...

  // Alert Security Team
  await client.send(
    `๐Ÿ›ก๏ธ Security Alert: Brute Force Detected\n` +
    `IP: ${req.ip}\n` +
    `Attempts: ${failedAttempts}\n` +
    `Action: IP has been temporarily banned. Verify traffic source.`
  );
}

4. Background Job Failures

Scenario: A nightly backup job fails.
Commandments Applied: IV (Actionable), VI (Fail Safely).

backup-cron.ts
job.on('failed', async (err) => {
  try {
    await client.send(
      `๐Ÿ’ฅ Backup Job Failed\n` +
      `Job: nightly_db_backup\n` +
      `Error: Connection timeout\n` +
      `Action: Manually retry backup via admin panel.`
    );
  } catch (alertError) {
    // Fail safely - do not crash the worker if alert fails
    console.error('Failed to send alert:', alertError);
  }
});