Expand description
§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); // DefaultEmbeds 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
Structs§
- Gntp
Client - GNTP client for sending notifications to Growl
- Notification
Type - Notification type definition
- Notify
Options - Options for sending notifications
- Resource
- Binary resource (icon) with multiple delivery options