Skip to main content

Notifications multi-canaux : Email, Slack, Telegram, Discord, WhatsApp, Teams, Ntfy, Mattermost, Rocket.Chat, Pushover en une ligne

Project description

notifyall ๐Ÿ””

PyPI version Downloads Python 3.9+ License: MIT Buy Me a Coffee GitHub Sponsors Ko-fi

notifyall is a multi-channel notification library for Python. It lets you send alerts and messages to 10 different platforms โ€” Slack, Telegram, Discord, Email, and more โ€” with a single unified API. It is cross-platform, requires Python 3.9+, and has zero external dependencies.

โšก Installation

Install notifyall directly from PyPI with a single command. No extra dependencies are required โ€” everything works out of the box with a standard Python installation (3.9 and above).

pip install notifyall

To upgrade to the latest published version if you already have notifyall installed:

pip install --upgrade notifyall

To verify the installation was successful and check the installed version:

python -c "import notifyall; print(notifyall.__version__)"

Message Templates

Message templates let you define a message pattern once and fill in the dynamic values at send time using standard Python string formatting with named placeholders. This is useful when the structure of your message is always the same but the values change โ€” deployment reports, job completions, daily summaries. It keeps your notification messages consistent and readable across your entire codebase without having to manually format strings everywhere.

n.notify_template(
    "๐Ÿš€ Version {version} deployed to {env} by {user}",
    version="2.1.0",
    env="production",
    user="alice"
)

Conditional Sending

.notify_if() is a convenience method that combines a condition check and a notification send into a single line. Instead of wrapping every notification in an if statement, you pass the condition directly as the first argument. If the condition is False, nothing is sent and no error is raised. This keeps monitoring code clean and readable, especially when you have many threshold checks in a row.

cpu_usage = 95
n.notify_if(cpu_usage > 90, f"High CPU usage: {cpu_usage}%", title="โš ๏ธ Warning")


disk_free = 500
n.notify_if(disk_free < 1000, "Disk almost full!", title="๐Ÿ”ด Critical")

Delayed and Repeated Sending

Sometimes you need to send a notification after a certain delay โ€” for example, after a long-running background job completes, or as a scheduled reminder. .notify_scheduled() fires the message after a specified number of seconds without blocking your main program execution. .notify_repeat() is designed for recurring reminders โ€” it sends the same message a specified number of times with a fixed interval between each send, also completely non-blocking. Both methods run in background threads so your program continues executing normally while the notifications are being sent.

# Send in 30 seconds (non-blocking)
n.notify_scheduled("Scheduled task completed", delay_seconds=30)


# Send 3 times every 5 minutes (non-blocking)
n.notify_repeat("Reminder: meeting in 15 minutes", times=3, interval=300)

Hooks (before / after / error)

Hooks are callback functions that notifyall calls automatically at specific moments in the notification lifecycle. The before hook is called just before sending begins, giving you the opportunity to log the outgoing message or modify it. The after hook is called once all channels have responded, giving you a summary of what succeeded and what failed. The error hook is called specifically when a channel fails, so you can handle failures independently from successes โ€” for example, by alerting a fallback channel or writing to a log file. Hooks are completely optional and do not affect the sending process itself.

def before_send(message, title):
    print(f"[notifyall] Sending: {title} โ€” {message}")


def after_send(message, title, results):
    ok = sum(1 for r in results if r.get("status") == "ok")
    print(f"[notifyall] {ok}/{len(results)} channels OK")


def on_error(result):
    print(f"[notifyall] Error on {result['channel']}: {result['error']}")


n.on("before", before_send)
n.on("after",  after_send)
n.on("error",  on_error)

Automatic Retry

Network failures are temporary by nature โ€” a webhook endpoint might be briefly unreachable due to a server restart, a rate limit, or a transient network issue. The automatic retry system handles this transparently: when a send fails, notifyall waits a configurable number of seconds and tries again, up to a maximum number of attempts. This dramatically improves reliability in unstable network environments without requiring any extra logic in your code. Retry is available directly on individual channel objects via .send_with_retry().

from notifyall.channels import SlackChannel


ch = SlackChannel(webhook_url="...")
result = ch.send_with_retry("Important message", retries=3, delay=2.0)
# Retries up to 3 times with 2 seconds between attempts

Statistics

The statistics system gives you a real-time overview of your notifier's activity. After sending any number of notifications, you can call .stats() to get a breakdown of how many messages were sent, how many succeeded, how many failed, and your overall success rate. This is useful for monitoring the health of your notification system itself โ€” if your success rate drops below 100%, you know something is wrong with one of your channels and can investigate before a critical alert gets lost.

n.notify("Deployment 1")
n.notify("Deployment 2")
n.notify("Deployment 3")


print(n.stats())
# {
#   "total_sends": 9,
#   "success": 9,
#   "errors": 0,
#   "success_rate": "100.0%",
#   "notifications_sent": 3,
#   "channels_configured": 3
# }

History and Export

Every notification sent through the notifier is automatically recorded in an in-memory history log. Each entry includes the timestamp, the title, the message, and the result for each channel. You can inspect the history at any time to audit what was sent and when, filter only the failed notifications for debugging, or export the entire history to a JSON file for long-term storage or external analysis. The history can also be cleared at any point to free memory or start a fresh recording session.

# View the last 5 notifications
for entry in n.history[-5:]:
    print(f"[{entry['timestamp']}] {entry['title']} โ€” {entry['message']}")


# View failed notifications only
for entry in n.failed_notifications():
    print(entry)


# Export full history to JSON
n.export_history("notifications.json")


# Clear history
n.clear_history()

๐Ÿ”ง Channel Configuration

Email (Gmail, Outlook, etc.)

The email channel uses Python's built-in smtplib to send notifications via any standard SMTP server โ€” Gmail, Outlook, Yahoo, or your own self-hosted mail server. You configure it with your SMTP credentials and the sender/recipient addresses. Beyond plain text messages, the email channel supports HTML formatting for rich layouts, and bulk sending to multiple recipients in a single call. TLS encryption is supported and recommended for all production use.

from notifyall.channels import EmailChannel


ch = EmailChannel(
    smtp_host="smtp.gmail.com",
    smtp_port=587,
    username="me@gmail.com",
    password="app_password",
    from_addr="me@gmail.com",
    to_addr="recipient@email.com",
    use_tls=True
)


ch.send("Hello!", title="Email Test")
ch.send_html("<h1>Hello</h1><p>HTML message</p>", title="HTML Email")
ch.send_to_multiple("Grouped message", ["alice@mail.com", "bob@mail.com"])

๐Ÿ’ก For Gmail, enable 2-step verification and create an app password in your Google account settings.


Slack

The Slack channel sends messages to any Slack workspace via an Incoming Webhook URL. You can customize the bot's display name and avatar emoji. For basic use, .send() posts a plain text message. For teams that need rich formatting, .send_blocks() accepts a full Slack Block Kit payload, giving you headers, bold text, sections, dividers, buttons, and any other layout element that the Slack API supports.

from notifyall.channels import SlackChannel


ch = SlackChannel(
    webhook_url="https://hooks.slack.com/services/XXX/YYY/ZZZ",
    username="notifyall",
    icon_emoji=":bell:"
)


ch.send("Deployment successful", title="Prod")


# With Block Kit (advanced formatting)
ch.send_blocks([
    {"type": "header", "text": {"type": "plain_text", "text": "๐Ÿš€ Alert"}},
    {"type": "section", "text": {"type": "mrkdwn", "text": "*Deployment* successful โœ…"}}
])

๐Ÿ’ก Create an Incoming Webhook on api.slack.com/apps.


Telegram

The Telegram channel sends messages to any Telegram chat, group, or channel via the Telegram Bot API. You configure it with a bot token (obtained from @BotFather) and a chat ID. It supports HTML and Markdown formatting for styled messages, link preview control, and several advanced methods: sending photos with captions, sending file attachments, and even creating polls directly in the chat โ€” all without leaving your Python code.

from notifyall.channels import TelegramChannel


ch = TelegramChannel(
    bot_token="123456789:ABCdefGHIjklMNOpqrSTUvwxYZ",
    chat_id="-100123456789",
    parse_mode="HTML",
    disable_preview=True
)


ch.send("Hello from notifyall!", title="Test")
ch.send_photo("https://example.com/image.png", caption="Today's chart")
ch.send_document("https://example.com/report.pdf", caption="Monthly report")
ch.send_poll("Are you satisfied?", ["Yes", "No", "Maybe"])

๐Ÿ’ก Create a bot with @BotFather on Telegram to get your token.


Discord

The Discord channel sends messages to any Discord server channel via a webhook URL. You can set a custom bot username and avatar image. For basic alerts, .send() sends a plain text message. For more professional looking notifications, .send_embed() lets you build a rich embed with a title, description, color, structured fields displayed side by side, a footer, and a thumbnail image โ€” the same format used by most Discord bots and integrations.

from notifyall.channels import DiscordChannel


ch = DiscordChannel(
    webhook_url="https://discord.com/api/webhooks/XXX/YYY",
    username="notifyall",
    avatar_url="https://example.com/avatar.png"
)


ch.send("Simple message")


# Rich embed
ch.send_embed(
    title="Deployment Report",
    description="Version 2.0 is now live",
    color=0x00ff00,
    fields=[
        {"name": "Environment", "value": "Production", "inline": True},
        {"name": "Duration", "value": "2m 34s", "inline": True}
    ],
    footer="notifyall v0.3.0",
    thumbnail_url="https://example.com/logo.png"
)

๐Ÿ’ก Create a webhook in your Discord server settings โ†’ Integrations.


Ntfy (100% free, no account)

Ntfy is a completely free, open-source push notification service that requires absolutely no account and no sign-up. You choose a topic name (a unique string that acts like a channel identifier), configure the channel with that topic, and subscribe to it on your phone using the ntfy app. Notifications arrive as native push notifications on Android and iOS. It is by far the easiest channel to set up for personal projects and self-hosted infrastructure. You can also self-host the ntfy server for maximum privacy.

from notifyall.channels import NtfyChannel


ch = NtfyChannel(
    topic="my-secret-topic-xyz",
    server="https://ntfy.sh",
    priority="high"
)
ch.send("Free push notification!", title="Ntfy Test")

๐Ÿ’ก Install the ntfy app on your phone and subscribe to your topic. No account required.


Microsoft Teams

The Microsoft Teams channel sends messages to any Teams channel via an Incoming Webhook connector. Plain text messages work out of the box with .send(). For enterprise use cases where more structured information is needed, .send_card() generates a rich adaptive card with a title, a description message, and a table of key-value facts โ€” useful for deployment reports, incident summaries, or any structured status update that needs to be clearly readable in a busy Teams channel.

from notifyall.channels import TeamsChannel


ch = TeamsChannel(webhook_url="https://outlook.office.com/webhook/...")


ch.send("Simple message", title="Alert")


# Rich card with facts
ch.send_card(
    title="Deployment Report",
    message="Version 2.0 deployed successfully",
    facts=[
        {"name": "Environment", "value": "Production"},
        {"name": "Duration", "value": "2 minutes"}
    ],
    color="00FF00"
)

๐Ÿ’ก Create an Incoming Webhook in your Teams channel connectors.


Mattermost

Mattermost is a self-hosted, open-source alternative to Slack widely used in enterprise and privacy-sensitive environments. The Mattermost channel works exactly like the Slack channel โ€” you provide a webhook URL, optionally set a target channel and bot username, and send messages normally. This makes it easy to migrate existing Slack integrations to Mattermost without changing any of your notification logic.

from notifyall.channels import MattermostChannel


ch = MattermostChannel(
    webhook_url="https://your-instance.mattermost.com/hooks/XXX",
    channel="alerts",
    username="notifyall"
)
ch.send("Deployment successful", title="Prod")

Rocket.Chat

Rocket.Chat is another popular self-hosted team messaging platform used heavily in DevOps and open-source communities. The Rocket.Chat channel connects via an Incoming Webhook and lets you set a custom display alias and emoji icon for the bot. It integrates seamlessly with existing Rocket.Chat workspaces and supports the same message format as other webhook-based channels.

from notifyall.channels import RocketChatChannel


ch = RocketChatChannel(
    webhook_url="https://your-instance.rocket.chat/hooks/XXX",
    alias="notifyall",
    emoji=":bell:"
)
ch.send("System alert", title="Monitoring")

WhatsApp (via Twilio)

The WhatsApp channel sends messages to any WhatsApp number using the Twilio API. Because WhatsApp does not offer a direct public API for programmatic messaging, Twilio acts as the intermediary. You need a Twilio account, an approved WhatsApp sender number, and the recipient's WhatsApp number. Twilio offers a free sandbox for testing before going live. This channel is ideal for reaching non-technical stakeholders who prefer WhatsApp over developer-focused platforms.

from notifyall.channels import WhatsAppChannel


ch = WhatsAppChannel(
    account_sid="ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    auth_token="your_auth_token",
    from_number="whatsapp:+14155238886",
    to_number="whatsapp:+33612345678"
)
ch.send("Critical alert!", title="Monitoring")

๐Ÿ’ก Requires a Twilio account. A free sandbox is available for testing.


Pushover

Pushover is a dedicated push notification service for developers that delivers native notifications to iOS and Android devices with fine-grained control over priority, sound, and device targeting. You register an application on pushover.net to get an app token, then use your personal user key to receive notifications on your devices. The PRIORITY_HIGH setting makes the notification bypass quiet hours and sound even when the device is silenced โ€” useful for truly critical alerts.

from notifyall.channels import PushoverChannel


ch = PushoverChannel(
    app_token="azGDORePK8gMaC0QOYAMyEEuzJnyUi",
    user_key="uQiRzpo4DXghDmr9QzzfQu27cmVRsG",
    priority=PushoverChannel.PRIORITY_HIGH,
    sound="siren"
)
ch.send("Server is down!", title="๐Ÿšจ CRITICAL")

๐Ÿ’ก Create an application on pushover.net to get your app token.


๐Ÿ› ๏ธ Real-World Use Cases

Server Monitoring

This example uses the psutil library to read real-time system metrics and sends alerts only when thresholds are exceeded. The key advantage of using notifyall here is that a single call to .notify_if() handles both the condition check and the multi-channel delivery โ€” no boilerplate, no nested if blocks. Run this script as a cron job or a background daemon to get proactive alerts before a server problem becomes a full outage.

import psutil
from notifyall import Notifier
from notifyall.channels import TelegramChannel, SlackChannel


n = Notifier(default_title="๐Ÿ–ฅ๏ธ Monitoring")
n.add(TelegramChannel(bot_token="...", chat_id="..."))
n.add(SlackChannel(webhook_url="..."))


cpu = psutil.cpu_percent()
mem = psutil.virtual_memory().percent
disk = psutil.disk_usage("/").percent


n.notify_if(cpu > 90,  f"Critical CPU usage: {cpu}%")
n.notify_if(mem > 85,  f"High RAM usage: {mem}%")
n.notify_if(disk > 95, f"Disk almost full: {disk}%")

CI/CD Pipeline

Integrating notifyall into a CI/CD pipeline gives your whole team instant visibility into deployments without having to check a dashboard. The try/except pattern shown here covers the two most important cases: a successful deployment sends a templated success message with the version and environment filled in automatically, while any unexpected exception triggers a critical alert with the full error message so you can diagnose the problem immediately.

from notifyall import Notifier
from notifyall.channels import SlackChannel, TeamsChannel


n = Notifier()
n.add(SlackChannel(webhook_url="..."))
n.add(TeamsChannel(webhook_url="..."))


try:
    deploy()
    n.notify_template("โœ… v{version} deployed to {env}!", version="2.0", env="prod")
except Exception as e:
    n.notify_level("critical", f"Deployment failed: {e}")

Daily Automated Report

Using the schedule library alongside notifyall, you can build a fully automated reporting system that runs indefinitely and delivers a daily digest to your inbox and your phone at a specific time every morning. The report content can be anything โ€” database queries, API calls, file statistics โ€” just build the message string and pass it to .notify(). The schedule.every().day.at() syntax makes the timing human-readable and easy to adjust.

import schedule
import time
from notifyall import Notifier
from notifyall.channels import EmailChannel, TelegramChannel


n = Notifier(default_title="๐Ÿ“Š Daily Report")
n.add(EmailChannel(...))
n.add(TelegramChannel(...))


def report():
    n.notify("Today's sales: โ‚ฌ1,234\nNew customers: 42\nResolved tickets: 18")


schedule.every().day.at("08:00").do(report)


while True:
    schedule.run_pending()
    time.sleep(60)

Trading Alert

In algorithmic trading, speed and reliability of alerts are critical. This example shows a price monitoring function that fires a notification the moment a target price is reached. Using notifyall here means the alert is simultaneously delivered to Telegram for mobile visibility and Discord for team awareness, with a single function call. The .notify_if() pattern keeps the alert logic minimal so it can be called on every price tick without adding latency.

from notifyall import Notifier
from notifyall.channels import TelegramChannel, DiscordChannel


n = Notifier(default_title="๐Ÿ“ˆ Trading Bot")
n.add(TelegramChannel(bot_token="...", chat_id="..."))
n.add(DiscordChannel(webhook_url="..."))


def check_price(symbol, price, target):
    n.notify_if(
        price >= target,
        f"{symbol} reached โ‚ฌ{price} (target: โ‚ฌ{target}) ๐ŸŽฏ",
        title="Buy Signal"
    )

๐Ÿงช Tests

The test suite covers all channels, all sending methods, and all edge cases. Run it with pytest before contributing or after modifying the source code to make sure everything still works as expected.

pip install pytest
pytest tests/

โœ… Zero External Dependencies

notifyall uses only the Python standard library. This means you never have to worry about dependency conflicts, security vulnerabilities in third-party packages, or broken installs. Every feature โ€” HTTP requests, email sending, parallel threads, JSON serialization โ€” is implemented using modules that ship with every Python installation, with no external packages required at runtime.

Module Usage
smtplib Sending emails
urllib HTTP requests to APIs
json Payload serialization
threading Non-blocking parallel sending
base64 Basic authentication (WhatsApp)
time Retry, delays, timestamps
os .env file loading

๐Ÿค Contributing

Contributions are welcome!

  1. Fork the project
  2. Create a branch (git checkout -b feature/new-channel)
  3. Commit your changes (git commit -m "feat: add XYZ channel")
  4. Push your branch (git push origin feature/new-channel)
  5. Open a Pull Request

Contribution ideas:

  • New channel (Pushbullet, Signal, Matrix, Gotify...)
  • More unit tests
  • Integration with Python standard logging
  • Async/await support

โ˜• Support the Project

notifyall is 100% free and open source (MIT). If this library saves you time, buying me a coffee is always appreciated! ๐Ÿ™

Platform Link
โ˜• Buy Me a Coffee buymeacoffee.com/your-username
๐Ÿต Ko-fi ko-fi.com/your-username

Your support helps:

  • ๐Ÿ”ง Maintain and fix the library
  • โž• Add new channels
  • ๐Ÿ“– Improve documentation
  • โšก Build new features

Thanks to all contributors and supporters ๐Ÿ’™


๐Ÿ“„ License

MIT โ€” Free to use in personal and commercial projects.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

notifyall-0.4.3-py3-none-any.whl (15.4 kB view details)

Uploaded Python 3

File details

Details for the file notifyall-0.4.3-py3-none-any.whl.

File metadata

  • Download URL: notifyall-0.4.3-py3-none-any.whl
  • Upload date:
  • Size: 15.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for notifyall-0.4.3-py3-none-any.whl
Algorithm Hash digest
SHA256 e5127e640d138c55d925b8bca11d071bd38229fa68098b64bc6944cb2a7fd4c5
MD5 998cac2fe9401d410ccd04963d87eb73
BLAKE2b-256 16297ced03f00201671fa4f6158e5ac90121aa0cae04a4c7f2eab151164d4610

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page