1 unstable release
Uses new Rust 2024
| 0.7.4 | Dec 20, 2025 |
|---|
#238 in #notifications
48KB
616 lines
sendgrowl
Send notifications to Growl with multiple host and port support (rust)
🚀 installation
cargo build --release # then use `sendgrowl -h`
or
cargo install sendgrowl
👤 Author
lib.rs:
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)
- ✅ Binary resource deduplication to prevent protocol errors
- ✅ Comprehensive error handling with detailed error types
- ✅ Production-ready with extensive testing
- ✅ No external dependencies (except uuid for unique identifiers)
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 |
Quick Start
use gntp::{GntpClient, NotificationType, Resource, IconMode};
// Create client with DataUrl mode (safest, most compatible)
let mut client = GntpClient::new("My App")
.with_icon_mode(IconMode::DataUrl);
// Load icon from file
let icon = Resource::from_file("icon.png")?;
// Define notification type with icon
let notification = NotificationType::new("alert")
.with_display_name("Alert Notification")
.with_icon(icon);
// Register (must be called first!)
client.register(vec![notification])?;
// Send notification
client.notify("alert", "Hello", "This is a test notification")?;
Icon Delivery Modes
Binary Mode (GNTP Spec Compliant)
let client = GntpClient::new("App")
.with_icon_mode(IconMode::Binary);
Sends icons as binary resources according to GNTP specification. Note: May not work correctly with Growl for Windows due to implementation bugs.
File URL Mode
let client = GntpClient::new("App")
.with_icon_mode(IconMode::FileUrl);
References icons via file:// URLs. Requires icon files to exist on disk.
Data URL Mode (Recommended for Windows)
let client = GntpClient::new("App")
.with_icon_mode(IconMode::DataUrl); // Default
Embeds icons as base64-encoded data URLs. Most compatible across all platforms. No external files required.
Advanced Usage
Creating Resources from Memory
let image_data: Vec<u8> = vec![/* your image bytes */];
let icon = Resource::from_bytes(image_data, "image/png");
Sending Notifications with Options
let options = NotifyOptions::new()
.with_sticky(true)
.with_priority(2)
.with_icon(icon);
client.notify_with_options(
"alert",
"Important",
"This stays on screen",
options
)?;
Multiple Notification Types
let info = NotificationType::new("info")
.with_display_name("Information");
let warning = NotificationType::new("warning")
.with_display_name("Warning");
let error = NotificationType::new("error")
.with_display_name("Error");
client.register(vec![info, warning, error])?;
client.notify("info", "Info", "Something happened")?;
client.notify("warning", "Warning", "Be careful!")?;
client.notify("error", "Error", "Something went wrong!")?;
Remote Notifications
let client = GntpClient::new("Remote App")
.with_host("192.168.1.100")
.with_port(23053);
Debug Mode
let client = GntpClient::new("Debug App")
.with_debug(true); // Prints detailed packet information
Protocol Specification
GNTP requires two separate steps:
- REGISTER - Register your application and notification types (once per connection)
- NOTIFY - Send notifications (multiple times)
You must call register() before calling notify(), otherwise you'll receive a
ProtocolError.
Error Handling
All operations return Result<T, GntpError> with detailed error information:
match client.register(vec![]) {
Ok(_) => println!("Registered successfully"),
Err(GntpError::ConnectionError(msg)) => {
eprintln!("Connection failed: {}", msg);
}
Err(GntpError::IoError(msg)) => {
eprintln!("I/O error: {}", msg);
}
Err(GntpError::ProtocolError(msg)) => {
eprintln!("Protocol error: {}", msg);
}
}
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 (10060).
Solution: Use IconMode::DataUrl (default) which embeds icons as base64 strings.
This bypasses the binary resource issue entirely.
Performance Considerations
- Binary Mode: Smallest packet size, fastest transmission
- File URL Mode: No data in packet, but requires disk access
- Data URL Mode: Larger packets (~33% increase due to base64), but most reliable
For typical notification icons (< 100KB), the performance difference is negligible.
Examples
See the examples directory for:
- Basic notifications
- Notifications with icons
- Multiple notification types
- Remote notifications
- Error handling patterns
License
MIT License - See LICENSE file for details
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Credits
Author: Hadi Cahyadi cumulus13@gmail.com
Dependencies
~2–12MB
~85K SLoC