Metadata-Version: 2.4
Name: notifyall
Version: 0.4.0
Summary: Notifications multi-canaux : Email, Slack, Telegram, Discord, WhatsApp, Teams, Ntfy, Mattermost, Rocket.Chat, Pushover en une ligne
License-Expression: MIT
Project-URL: Homepage, https://github.com/votre-pseudo/notifyall
Project-URL: Issues, https://github.com/votre-pseudo/notifyall/issues
Project-URL: Changelog, https://github.com/votre-pseudo/notifyall/blob/main/CHANGELOG.md
Project-URL: Funding, https://github.com/sponsors/votre-pseudo
Project-URL: Buy Me a Coffee, https://buymeacoffee.com/votre-pseudo
Keywords: notification,slack,telegram,discord,whatsapp,teams,ntfy,mattermost,rocketchat,pushover,email,alert,monitoring
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Communications
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"


> 💡 Each digest key (`"errors"`, `"warnings"`, etc.) has its own independent buffer. Calling `flush_digest()` clears the buffer after sending.


---


### Message Templates


```python
n.notify_template(
    "🚀 Version {version} deployed to {env} by {user}",
    version="2.1.0",
    env="production",
    user="alice"
)
```


---


### Conditional Sending


```python
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


```python
# 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)


```python
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


```python
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


```python
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


```python
# 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.)


```python
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


```python
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](https://api.slack.com/apps).


---


### Telegram


```python
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](https://t.me/BotFather) on Telegram to get your token.


---


### Discord


```python
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)


```python
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](https://ntfy.sh) app on your phone and subscribe to your topic. No account required.


---


### Microsoft Teams


```python
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


```python
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


```python
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)


```python
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](https://twilio.com) account. A free sandbox is available for testing.


---


### Pushover


```python
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](https://pushover.net) to get your app token.


---


## 🛠️ Real-World Use Cases


### Server Monitoring


```python
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


```python
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


```python
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


```python
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


```bash
pip install pytest
pytest tests/
```


---


## ✅ Zero External Dependencies


`notifyall` uses **only the Python standard library**:


| 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](https://buymeacoffee.com/keyzen07) |
| 🍵 Ko-fi | [ko-fi.com/your-username](https://ko-fi.com/keyzen07) |


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.
