callmebot-notifier
v1.10.2
Published
Typed notification library for Node.js with WhatsApp, Telegram, Signal, Email, Discord, Slack, Google Chat, and Microsoft Teams.
Downloads
611
Maintainers
Readme
callmebot-notifier
Multi-channel notification delivery for Node.js. Send alerts to WhatsApp, Telegram, Web Push, Discord, Slack, Teams, Google Chat and Email with retry, fallback and severity routing.
CallMeBot is not the official WhatsApp API. Use this package for personal and low-risk notifications.
Subpath imports
Use HTTP-only entrypoints for Cloudflare Workers, edge runtimes, and serverless environments:
import { whatsapp } from "callmebot-notifier/whatsapp";
import { telegram } from "callmebot-notifier/telegram";import { telegram } from "callmebot-notifier/telegram";
export default {
async fetch(_request: Request, env: { TELEGRAM_BOT_TOKEN: string; TELEGRAM_CHAT_ID: string }) {
const channel = telegram({
botToken: env.TELEGRAM_BOT_TOKEN,
chatId: env.TELEGRAM_CHAT_ID
});
await channel.send("Hello from Cloudflare Workers");
return new Response("sent");
}
};Additional entrypoints are available from callmebot-notifier/core, /email, /webpush, and /express.
The email, webpush, and express entrypoints are Node-specific.
The root import remains fully supported for backward compatibility.
Donation:
You can buy me a coffee or two if you find helpfull my node.
If you buy me a coffee I would like to thank you in advance for your donation.
Supported Channels
- WhatsApp via CallMeBot
- Telegram
- Web Push
- Discord
- Slack
- Google Chat
- Microsoft Teams
- Signal (via
signal-cli-rest-api)
Features
| Feature | Supported | | ---------------------- | --------- | | WhatsApp via CallMeBot | Yes | | Telegram | Yes | | Web Push | Yes | | Discord | Yes | | Slack | Yes | | Google Chat | Yes | | Microsoft Teams | Yes | | Signal via signal-cli | Yes | | Email | Yes | | Retry | Yes | | Fallback | Yes | | Severity routing | Yes | | Templates | Yes | | Express API | Yes | | GitHub Action | Yes |
Install
npm install callmebot-notifierQuick Start
PHONE=393331112223
APIKEY=your-callmebot-apikey
TELEGRAM_BOT_TOKEN=1234567980:XXXX5x0XX2XxxXxx1XXXxxXxXXxXX6X-Tho
TELEGRAM_CHAT_ID=990099009
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...
GCHAT_WEBHOOK_URL=https://chat.googleapis.com/v1/spaces/.../messages?key=...&token=...
TEAMS_WEBHOOK_URL=https://...
SIGNAL_API_URL=http://localhost:8080
SIGNAL_NUMBER=+391234567890
SIGNAL_RECIPIENTS=+399876543210
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
[email protected]
SMTP_PASS=xxxx xxxx xxxx xxxx
[email protected]
[email protected]import { fromEnv } from "callmebot-notifier";
const notifier = fromEnv();
await notifier.send("Deployment done");Basic notify()
import { notify, whatsapp, telegram } from "callmebot-notifier";
await notify({
channels: [
whatsapp({ phone: process.env.PHONE ?? "", apikey: process.env.APIKEY ?? "" }),
telegram({
botToken: process.env.TELEGRAM_BOT_TOKEN ?? "",
chatId: process.env.TELEGRAM_CHAT_ID ?? ""
})
],
message: "Server is down"
});Web Push
Create VAPID keys once, keep private key server-side, and store each browser subscription in your application database. Then pass one subscription to webpush():
import { webpush } from "callmebot-notifier";
const channel = webpush({
subscription, // Browser PushSubscription serialized with JSON.stringify()
vapidDetails: {
subject: "mailto:[email protected]",
publicKey: process.env.VAPID_PUBLIC_KEY ?? "",
privateKey: process.env.VAPID_PRIVATE_KEY ?? ""
},
ttl: 60,
urgency: "high"
});
await channel.send("Deployment complete");See Web Push setup for browser subscription and service-worker setup.
Fallback Example
import { notify, whatsapp, telegram } from "callmebot-notifier";
await notify({
primary: whatsapp({ phone: process.env.PHONE ?? "", apikey: process.env.APIKEY ?? "" }),
fallback: telegram({
botToken: process.env.TELEGRAM_BOT_TOKEN ?? "",
chatId: process.env.TELEGRAM_CHAT_ID ?? ""
}),
message: "Server is down"
});Severity Routing
import { notify, whatsapp, telegram, email, gchat, teams } from "callmebot-notifier";
await notify({
routes: {
info: [
telegram({
botToken: process.env.TELEGRAM_BOT_TOKEN ?? "",
chatId: process.env.TELEGRAM_CHAT_ID ?? ""
})
],
warn: [gchat({ webhookUrl: process.env.GCHAT_WEBHOOK_URL ?? "" })],
critical: [
whatsapp({ phone: process.env.PHONE ?? "", apikey: process.env.APIKEY ?? "" }),
teams({ webhookUrl: process.env.TEAMS_WEBHOOK_URL ?? "" }),
email({
host: process.env.SMTP_HOST ?? "",
port: Number(process.env.SMTP_PORT || 587),
secure: process.env.SMTP_SECURE === "true",
user: process.env.SMTP_USER ?? undefined,
pass: process.env.SMTP_PASS ?? undefined,
from: process.env.EMAIL_FROM ?? "",
to: process.env.EMAIL_TO ?? ""
})
]
},
message: {
title: "CPU high",
message: "Load spike on api-1",
severity: "critical"
}
});Templates
import { notify, whatsapp } from "callmebot-notifier";
await notify.alert(
{
title: "Deploy",
message: "Application deployed",
source: "GitHub Actions"
},
{
channels: [whatsapp({ phone: process.env.PHONE ?? "", apikey: process.env.APIKEY ?? "" })]
}
);
await notify.incident(
{
title: "Database down",
message: "Primary DB unavailable",
source: "api"
},
{
channels: [whatsapp({ phone: process.env.PHONE ?? "", apikey: process.env.APIKEY ?? "" })]
}
);Retry Policy
import { notify, whatsapp, telegram, email } from "callmebot-notifier";
await notify({
channels: [
whatsapp({ phone: process.env.PHONE ?? "", apikey: process.env.APIKEY ?? "" }),
telegram({
botToken: process.env.TELEGRAM_BOT_TOKEN ?? "",
chatId: process.env.TELEGRAM_CHAT_ID ?? ""
}),
email({
host: process.env.SMTP_HOST ?? "",
port: Number(process.env.SMTP_PORT || 587),
secure: process.env.SMTP_SECURE === "true",
user: process.env.SMTP_USER ?? undefined,
pass: process.env.SMTP_PASS ?? undefined,
from: process.env.EMAIL_FROM ?? "",
to: process.env.EMAIL_TO ?? ""
})
],
message: "Build failed",
retry: { attempts: 3, delayMs: 1000 }
});Hooks
import { notify, whatsapp } from "callmebot-notifier";
const channel = whatsapp({ phone: process.env.PHONE ?? "", apikey: process.env.APIKEY ?? "" });
await notify({
channels: [channel],
message: "Release done",
logLevel: "info",
onResult: (result) => {
console.log("notify.result", result);
},
onError: (error, context) => {
console.error("notify.error", { error, ...context });
}
});Express Usage
import { createExpressApp, FallbackChannel, whatsapp, telegram } from "callmebot-notifier";
const app = createExpressApp(
new FallbackChannel([
whatsapp({ phone: process.env.PHONE ?? "", apikey: process.env.APIKEY ?? "" }),
telegram({
botToken: process.env.TELEGRAM_BOT_TOKEN ?? "",
chatId: process.env.TELEGRAM_CHAT_ID ?? ""
})
])
);
app.listen(3000);GitHub Action
Use published action:
- uses: F3rr1gn0/callmebot-notifier-action@v1
with:
message: "Build done"
channel: "telegram"
env:
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}Secrets to set in consumer repo:
TELEGRAM_BOT_TOKEN
TELEGRAM_CHAT_ID
PHONE
APIKEY
DISCORD_WEBHOOK_URL
SLACK_WEBHOOK_URL
GCHAT_WEBHOOK_URL
TEAMS_WEBHOOK_URL
SMTP_HOST
SMTP_PORT
SMTP_SECURE
SMTP_USER
SMTP_PASS
EMAIL_FROM
EMAIL_TOSmoke flow:
name: smoke-action
on:
workflow_dispatch:
jobs:
smoke:
runs-on: ubuntu-latest
steps:
- uses: F3rr1gn0/callmebot-notifier-action@v1
with:
message: "Smoke from GitHub Action"
channel: "telegram"
env:
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}Failure flow:
name: smoke-action-failure
on:
workflow_dispatch:
jobs:
smoke:
runs-on: ubuntu-latest
steps:
- run: exit 1
- if: ${{ failure() }}
uses: F3rr1gn0/callmebot-notifier-action@v1
with:
message: "Build failed"
channel: "telegram"
env:
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}Setup Guides
- CallMeBot WhatsApp
- Telegram bot and chat
- Web Push
- Discord webhook
- Slack webhook
- Google Chat webhook
- Microsoft Teams webhook
- Signal
- Email with Gmail
MCP Server Example
Expose send_notification to Claude Desktop, Cursor, or another MCP client:
Environment Variables
Common variables:
PHONEAPIKEYTELEGRAM_BOT_TOKENTELEGRAM_CHAT_IDVAPID_PUBLIC_KEYVAPID_PRIVATE_KEYDISCORD_WEBHOOK_URLSLACK_WEBHOOK_URLGCHAT_WEBHOOK_URLTEAMS_WEBHOOK_URLSIGNAL_API_URLSIGNAL_NUMBERSIGNAL_RECIPIENTSSMTP_HOSTSMTP_PORTSMTP_SECURESMTP_USERSMTP_PASSEMAIL_FROMEMAIL_TO
Result Shape
notify() returns:
type NotifyResult = {
ok: boolean;
deliveredBy?: string;
attempts: Array<{
channel: string;
ok: boolean;
attempt: number;
error?: string;
}>;
};Helper:
import { summarizeNotifyResult } from "callmebot-notifier";
const summary = summarizeNotifyResult(result);Notes and Limitations
- CallMeBot is a third-party WhatsApp bridge, not the official WhatsApp API
- Intended for personal or low-risk alerts
- Discord and Slack use webhook URLs only
- Web Push subscriptions belong to browsers; store them in your app and remove subscriptions that return
404or410 fromEnv()is the quickest way to bootstrap a notifier from environment variables- Email examples assume Gmail app passwords
- Coverage report is generated by
npm run test:coverage
Roadmap
- ntfy
- Pushover
- Mattermost
- Matrix
License
MIT
