GNTP - Growl Notification Transport Protocol Client
A robust, production-ready Rust implementation of the Growl Notification Transport Protocol (GNTP) for sending desktop notifications to Growl-compatible clients across multiple platforms.
✨ Features
- ✅ Full GNTP 1.0 protocol implementation
- ✅ Multiple icon delivery modes (Binary, File URL, Data URL/Base64)
- ✅ Windows Growl compatibility with automatic workarounds
- ✅ Cross-platform support (Windows, macOS, Linux, Android)
- ✅ Binary resource deduplication to prevent protocol errors
- ✅ Comprehensive error handling with detailed error types
- ✅ Production-ready with extensive documentation
- ✅ Zero external dependencies (except
uuidfor unique identifiers) - ✅ Multiple notification types per application
- ✅ Priority levels (-2 to 2)
- ✅ Sticky notifications
📦 Installation
Add to your Cargo.toml:
[]
= "0.1.5"
Requirements
You need a GNTP-compatible notification client:
- Windows: Growl for Windows
- macOS: Growl for Mac (legacy) or compatible client
- Linux: Snarl or compatible GNTP daemon
- Android: Googling :)
Default server: localhost:23053
🚀 Quick Start
# Build library only (no CLI) `sendgrowl`
# Build dengan CLI tool (sendgrowl)
# Test sendgrowl
# more options
use ;
🎯 Icon Delivery Modes
DataUrl Mode (Recommended - Default)
Embeds icons as base64-encoded data URLs. Most compatible across all platforms, especially Windows.
let client = new
.with_icon_mode;
Pros:
- ✅ Works on all platforms
- ✅ No external files required
- ✅ Bypasses Growl for Windows binary resource bug
Cons:
- ⚠️ Larger packet size (~33% increase due to base64)
Binary Mode (GNTP Spec Compliant)
Sends icons as binary resources according to GNTP specification.
let client = new
.with_icon_mode;
Pros:
- ✅ Smallest packet size
- ✅ Fastest transmission
- ✅ GNTP spec compliant
Cons:
- ❌ Broken on Growl for Windows (causes timeout)
FileUrl Mode
References icons via file:// URLs. Requires icon files to exist on disk.
let client = new
.with_icon_mode;
Pros:
- ✅ No data in packet
- ✅ Good for shared icons
Cons:
- ⚠️ Requires files on disk
- ⚠️ Path must be accessible to Growl server
🖼️ Working with Icons
From File
let icon = from_file?;
From Memory
let image_data: = load_icon_from_memory;
let icon = from_bytes;
Supported Formats
- PNG (
.png) - Recommended - JPEG (
.jpg,.jpeg) - GIF (
.gif) - BMP (
.bmp) - ICO (
.ico) - SVG (
.svg) - WebP (
.webp)
📋 Advanced Usage
Multiple Notification Types
let info = new
.with_display_name;
let warning = new
.with_display_name;
let error = new
.with_display_name;
client.register?;
client.notify?;
client.notify?;
client.notify?;
Notification Options
use NotifyOptions;
let options = new
.with_sticky // Stays on screen until dismissed
.with_priority; // Emergency priority
client.notify_with_options?;
Remote Notifications
let client = new
.with_host
.with_port;
Android Notifications with Retry
Android devices may have network delays. Use retry mechanism:
# sendgrowl with retry
Or in Rust code with manual retry:
let mut client = new
.with_host
.with_icon_mode;
for attempt in 1..=3
Debug Mode
let client = new
.with_debug; // Prints detailed packet information
🐛 Windows Compatibility Notes
Growl for Windows has a known bug where it doesn't properly handle binary resources according to the GNTP specification. When the server receives binary data, it may not respond, causing timeout errors (error code 10060).
Solution: Use IconMode::DataUrl (default) which embeds icons as base64 strings. This bypasses the binary resource issue entirely.
📊 Platform Compatibility
| Platform | Binary Mode | File URL | Data URL | Recommended |
|---|---|---|---|---|
| Windows (Growl for Windows) | ⚠️ Buggy | ✅ Works | ✅ Best | DataUrl |
| macOS (Growl) | ✅ Works | ✅ Works | ✅ Works | Binary |
| Linux (Growl-compatible) | ✅ Works | ✅ Works | ✅ Works | Binary |
Buggy: most tests pass
🔧 Error Handling
match client.register
📚 Examples
Run examples with:
# Basic notification
# Notification with icon
# Notification with full path icon
# Multiple notification types
# Remote notifications
GROWL_HOST=192.168.1.100
# Android notifications with retry
ANDROID_HOST=192.168.1.50
# Error handling patterns
Basic Notification
use ;
With Icon
use ;
let mut client = new;
// Load application icon
if let Ok = from_file
let notification = new;
client.register?;
client.notify?;
With Options (Priority & Sticky)
use ;
let mut client = new;
let notification = new;
client.register?;
let options = new
.with_sticky
.with_priority;
client.notify_with_options?;
Multiple Notification Types
let mut client = new;
let notifications = vec!;
client.register?;
client.notify?;
client.notify?;
client.notify?;
Protocol Details
GNTP requires two separate steps:
- REGISTER - Register your application and notification types (once at startup)
- NOTIFY - Send notifications (multiple times)
Icons are sent as binary resources with unique identifiers, not as file paths.
Error Handling
match client.register
Running Examples
# Basic example
# With icon
# Multiple notification types
# With options (priority, sticky)
# Error handling
📄 License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Resources
👤 Author
🙏 Acknowledgments
- Based on the GNTP specification by The Growl Project
- Inspired by various GNTP client implementations
📖 Resources
Note: This is a production-ready library with comprehensive Windows compatibility. If you encounter any issues, please open an issue on GitHub.
