website/docs/guides/notifications.mdx
Wails provides a comprehensive cross-platform notification system for desktop applications. This runtime allows you to display native system notifications with support for interactive elements like action buttons and text input fields.
:::info JavaScript
Notifications are currently unsupported in the JS runtime.
:::
First, initialize the notification system. This should be called during app startup (typically in OnStartup):
err := runtime.InitializeNotifications(a.ctx)
if err != nil {
// Handle initialization error
// On macOS, this may fail if bundle identifier is not set
}
Then, check if notifications are available on the current platform:
if runtime.IsNotificationAvailable(a.ctx) {
// Notifications are supported
// On macOS, this checks for macOS 10.14+
// On Windows and Linux, this always returns true
}
On macOS, you'll need to request permission before sending notifications:
authorized, err := runtime.CheckNotificationAuthorization(a.ctx)
if err != nil {
// Handle authorization error
}
if !authorized {
authorized, err = runtime.RequestNotificationAuthorization(a.ctx)
if err != nil || !authorized {
// Handle permission denial
}
}
On Windows and Linux, authorization is not required as these platforms don't have permission systems.
Send a basic notification with a unique ID, title, optional subtitle (macOS and Linux), and body text:
err := runtime.SendNotification(a.ctx, runtime.NotificationOptions{
ID: "calendar-invite-001",
Title: "New Calendar Invite",
Subtitle: "From: Jane Doe", // Optional - macOS and Linux only
Body: "Tap to view the event",
})
if err != nil {
// Handle error
}
Interactive notifications allow users to respond with button actions or text input. You must first register a notification category that defines the available actions.
Define a category with action buttons and optional text input:
categoryID := "message-category"
category := runtime.NotificationCategory{
ID: categoryID,
Actions: []runtime.NotificationAction{
{
ID: "OPEN",
Title: "Open",
},
{
ID: "ARCHIVE",
Title: "Archive",
Destructive: true, // macOS-specific - shows as red button
},
},
HasReplyField: true,
ReplyPlaceholder: "Type your reply...",
ReplyButtonTitle: "Reply",
}
err := runtime.RegisterNotificationCategory(a.ctx, category)
if err != nil {
// Handle error
}
Send an interactive notification using the registered category. If the category is not found or CategoryID is empty, a basic notification will be sent instead:
err := runtime.SendNotificationWithActions(a.ctx, runtime.NotificationOptions{
ID: "message-001",
Title: "New Message",
Subtitle: "From: John Smith", // Optional - macOS and Linux only
Body: "Hey, are you free for lunch?",
CategoryID: categoryID,
})
if err != nil {
// Handle error
}
Listen for user interactions with notifications by registering a callback:
runtime.OnNotificationResponse(a.ctx, func(result runtime.NotificationResult) {
if result.Error != nil {
// Handle response error
return
}
response := result.Response
fmt.Printf("Notification %s was actioned with: %s\n",
response.ID, response.ActionIdentifier)
if response.ActionIdentifier == "TEXT_REPLY" {
fmt.Printf("User replied: %s\n", response.UserText)
}
// You can also emit events to the frontend
runtime.EventsEmit(a.ctx, "notification", response)
})
Basic and interactive notifications can include custom data that will be returned in the response:
err := runtime.SendNotification(a.ctx, runtime.NotificationOptions{
ID: "event-001",
Title: "Team Meeting",
Subtitle: "In 30 minutes",
Body: "Don't forget your presentation materials!",
Data: map[string]interface{}{
"eventId": "meeting-123",
"startTime": "2024-01-15T14:00:00Z",
"attendees": []string{"[email protected]", "[email protected]"},
"priority": "high",
},
})
// In the response handler:
runtime.OnNotificationResponse(a.ctx, func(result runtime.NotificationResult) {
response := result.Response
if eventId, ok := response.UserInfo["eventId"].(string); ok {
fmt.Printf("Event ID: %s\n", eventId)
}
})
Remove a previously registered notification category:
err := runtime.RemoveNotificationCategory(a.ctx, "message-category")
Control notification visibility:
// Remove a specific pending notification (macOS and Linux only)
err := runtime.RemovePendingNotification(a.ctx, "notification-id")
// Remove all pending notifications (macOS and Linux only)
err = runtime.RemoveAllPendingNotifications(a.ctx)
// Remove a specific delivered notification (macOS and Linux only)
err = runtime.RemoveDeliveredNotification(a.ctx, "notification-id")
// Remove all delivered notifications (macOS and Linux only)
err = runtime.RemoveAllDeliveredNotifications(a.ctx)
// Remove a notification (Linux-specific)
err = runtime.RemoveNotification(a.ctx, "notification-id")