Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v3] Notifications API #4098

Open
wants to merge 98 commits into
base: v3-alpha
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
32839bd
initial notification impl
popaprozac Feb 20, 2025
274511c
update log message
popaprozac Feb 21, 2025
f694ad2
service and minor refactor
popaprozac Feb 22, 2025
cc524d7
update example
popaprozac Feb 22, 2025
87f15ce
refactor
popaprozac Feb 22, 2025
91f1704
cleanup
popaprozac Feb 22, 2025
01fa307
windows impl
popaprozac Feb 23, 2025
c7d54e2
remove app event
popaprozac Feb 23, 2025
7757eae
standalone example
popaprozac Feb 23, 2025
9f39577
add comments
popaprozac Feb 23, 2025
47a0977
add overwrite and remove notification category
popaprozac Feb 23, 2025
6d44068
save notification categories to registry
popaprozac Feb 23, 2025
ab9c460
quick fixes
popaprozac Feb 23, 2025
27e512d
add data option to basic notification
popaprozac Feb 23, 2025
f8647ff
update min macos version
popaprozac Feb 23, 2025
c1230d4
update win impl to match
popaprozac Feb 23, 2025
9eab58f
update comments
popaprozac Feb 23, 2025
cc760a1
test data with toast
popaprozac Feb 23, 2025
978a982
don't add title or body quite yet
popaprozac Feb 23, 2025
bf4222c
update example
popaprozac Feb 24, 2025
c904433
update example
popaprozac Feb 24, 2025
983c25f
rw safety
popaprozac Feb 24, 2025
1e3511c
fix deadlock
popaprozac Feb 24, 2025
3dbf058
update comments
popaprozac Feb 24, 2025
be716fc
fix input id
popaprozac Feb 25, 2025
8da9981
for review
popaprozac Feb 25, 2025
e8ad42a
switch to callback style
popaprozac Feb 25, 2025
8bbe381
Merge branch 'v3-alpha' into notifications_darwin
popaprozac Feb 25, 2025
67adc45
update example
popaprozac Feb 25, 2025
253f672
init linux
popaprozac Feb 25, 2025
135defc
init test linux
popaprozac Feb 25, 2025
7bbc275
fix windows
popaprozac Feb 25, 2025
fa498f1
encode user data on windows
popaprozac Feb 25, 2025
050e4ef
fix default complex action
popaprozac Feb 25, 2025
60c1a86
update example
popaprozac Feb 25, 2025
10ae1f6
export config from app
popaprozac Feb 25, 2025
a4c4ab6
add id to macOS payload
popaprozac Feb 25, 2025
acad85e
update example
popaprozac Feb 25, 2025
60ae0c1
test linux userInfo
popaprozac Feb 26, 2025
47e5b10
add debug
popaprozac Feb 26, 2025
5ad3d73
wrangle variants
popaprozac Feb 26, 2025
e86cf68
linux?
popaprozac Feb 26, 2025
db2cab7
grab icon from app for notifications on windows
popaprozac Feb 26, 2025
e216b3e
set icon
popaprozac Feb 26, 2025
207b162
Merge branch 'notifications_darwin' of github.com:popaprozac/wails in…
popaprozac Feb 26, 2025
3bdb3dd
use app icon
popaprozac Feb 26, 2025
a807c26
better interop with obj-c
popaprozac Feb 27, 2025
ad74972
can you tell i'm not a go programmer?
popaprozac Feb 27, 2025
d9af6de
ignore bindings notification callback
popaprozac Mar 3, 2025
833d8ec
refactor macos
popaprozac Mar 5, 2025
e4ec06a
update example
Mar 14, 2025
1e67e94
rename auth func
popaprozac Mar 15, 2025
1fa6894
//
popaprozac Mar 15, 2025
e46abdc
update example
popaprozac Mar 15, 2025
2cb0dac
set default action id on MATE
popaprozac Mar 15, 2025
6d15f08
Merge branch 'v3-alpha' into notifications_darwin
popaprozac Mar 15, 2025
e810d6a
tidy
popaprozac Mar 15, 2025
e4e24a0
clean
popaprozac Mar 19, 2025
b60ef77
coderabbit impr
popaprozac Mar 19, 2025
ee885fe
fix mem crash
popaprozac Mar 19, 2025
4af058b
more cleanup
popaprozac Mar 20, 2025
58b5c10
Merge branch 'v3-alpha' into notifications_darwin
popaprozac Mar 20, 2025
25256f7
allow only one notification service per app
popaprozac Mar 20, 2025
d98f528
Merge branch 'notifications_darwin' of github.com:popaprozac/wails in…
popaprozac Mar 20, 2025
bd85738
fix err message
popaprozac Mar 20, 2025
c58709c
lock registry access/writes
popaprozac Mar 20, 2025
b1db2bb
add missing error
popaprozac Mar 20, 2025
88f1336
reorg platform impl
popaprozac Mar 20, 2025
94f245f
bug fix
popaprozac Mar 20, 2025
e55bf8d
linux bug fix
popaprozac Mar 20, 2025
9adeef2
fix linux and remove dup code
popaprozac Mar 20, 2025
5dc7bd9
refactor/simplify linux
popaprozac Mar 20, 2025
be1da68
avoid deadlock on win
popaprozac Mar 21, 2025
ef3b7d2
pass service options
popaprozac Mar 22, 2025
81b40d2
ensure exactly one delegate created
popaprozac Mar 22, 2025
f6a5bed
windows err handling
popaprozac Mar 22, 2025
b2b8f14
windows err handling
popaprozac Mar 22, 2025
f870dcc
handle notif content errors
popaprozac Mar 23, 2025
9948cee
monitor dbus connection
popaprozac Mar 23, 2025
ace4f70
fix channel cleanup linux
popaprozac Mar 23, 2025
448c78b
rewrite and simplify linux impl
popaprozac Mar 23, 2025
5ddb27f
move chan creation on macos and handle linux shutdown
popaprozac Mar 23, 2025
a683918
remove deadlock
popaprozac Mar 23, 2025
9a45423
follow dbus spec
popaprozac Mar 24, 2025
7f496c9
fix linux note
popaprozac Mar 24, 2025
1f82166
ensure cat id is set for macOS and other rabbit suggestions
popaprozac Mar 24, 2025
b102279
update example
popaprozac Mar 24, 2025
d25f923
wait on dbus
popaprozac Mar 25, 2025
276c653
update example
popaprozac Mar 25, 2025
7d0f7f4
revert linux wait and update payload on win
popaprozac Mar 25, 2025
af5abda
update example
popaprozac Mar 25, 2025
1db65a8
stage docs
popaprozac Mar 27, 2025
743882a
update docs/changelog
popaprozac Mar 27, 2025
1022f47
fix docs
popaprozac Mar 27, 2025
bd5c82e
fix docs
popaprozac Mar 27, 2025
b313f2c
fix docs
popaprozac Mar 27, 2025
9a41b0c
move icon method, impl interface, check compat, don't panic!
popaprozac Mar 30, 2025
75dbe85
remove comptime check
popaprozac Mar 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/content/docs/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add cancellation support for query methods on `sqlite` service by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067)
- Add prepared statement support to `sqlite` service with JS bindings by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067)
- Add `SetMenu()` on window to allow for setting a menu on a window by [@leaanthony](https://github.com/leaanthony)
- Add Notification support by [@popaprozac] in [#4098](https://github.com/wailsapp/wails/pull/4098)

### Fixed

Expand Down
304 changes: 304 additions & 0 deletions docs/src/content/docs/learn/notifications.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,304 @@
---
title: Notifications
---

import { Tabs, TabItem } from "@astrojs/starlight/components";

## Introduction

Wails provides a comprehensive cross-platform notification system for desktop applications. This service allows you to display native system notifications, with support for interactive elements like action buttons and text input fields.

## Basic Usage

### Creating the Service

First, initialize the notifications service:

```go
import "github.com/wailsapp/wails/v3/pkg/application"
import "github.com/wailsapp/wails/v3/services/notifications"

// Create a new notification service
notifier := notifications.New()

//Register the service with the application
app := application.New(application.Options{
Services: []application.Service{
application.NewService(notifier),
},
})
```

## Notification Authorization

Notifications on macOS require user authorization. Request and check authorization:

```go
authorized, err := notifier.CheckNotificationAuthorization()
if err != nil {
// Handle authorization error
}
if authorized {
// Send notifications
} else {
// Request authorization
authorized, err = notifier.RequestNotificationAuthorization()
}
```
On Windows and Linux this always returns `true`.

## Notification Types

### Basic Notifications

Send a basic notification with a unique id, title, optional subtitle (macOS and Linux), and body text to users:

```go
notifier.SendNotification(notifications.NotificationOptions{
ID: "unique-id",
Title: "New Calendar Invite",
Subtitle: "From: Jane Doe", // Optional
Body: "Tap to view the event",
})

```

### Interactive Notifications
Send a notification with action buttons and text inputs. These notifications require a notification category to be resgistered first:

```go
// Define a unique category id
categoryID := "unique-category-id"

// Define a category with actions
category := notifications.NotificationCategory{
ID: categoryID,
Actions: []notifications.NotificationAction{
{
ID: "OPEN",
Title: "Open",
},
{
ID: "ARCHIVE",
Title: "Archive",
Destructive: true, /* macOS-specific */
},
},
HasReplyField: true,
ReplyPlaceholder: "message...",
ReplyButtonTitle: "Reply",
}

// Register the category
notifier.RegisterNotificationCategory(category)

// Send an interactive notification with the actions registered in the provided category
notifier.SendNotificationWithActions(notifications.NotificationOptions{
ID: "unique-id",
Title: "New Message",
Subtitle: "From: Jane Doe",
Body: "Are you able to make it?",
CategoryID: categoryID,
})
```

## Notification Responses

Process user interactions with notifications:

```go
notifier.OnNotificationResponse(func(result notifications.NotificationResult) {
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)
}

if data, ok := response.UserInfo["sender"].(string); ok {
fmt.Printf("Original sender: %s\n", data)
}

// Emit an event to the frontend
app.EmitEvent("notification", result.Response)
})
```

## Notification Customisation

### Custom Metadata

Basic and interactive notifications can include custom data:

```go
notifier.SendNotification(notifications.NotificationOptions{
ID: "unique-id",
Title: "New Calendar Invite",
Subtitle: "From: Jane Doe", // Optional
Body: "Tap to view the event",
Data: map[string]interface{}{
"sender": "[email protected]",
"timestamp": "2025-03-10T15:30:00Z",
}
})

```

## Platform Considerations

<Tabs>
<TabItem label="macOS" icon="fa-brands:apple">

On macOS, notifications:

- Require user authorization
- Require the app to be notorized for distribution
- Use system-standard notification appearances
- Support `subtitle`
- Support user text input
- Support the `Destructive` action option
- Automatically handle dark/light mode

</TabItem>

<TabItem label="Windows" icon="fa-brands:windows">

On Windows, notifications:

- Use Windows system toast styles
- Adapt to Windows theme settings
- Support user text input
- Support high DPI displays
- Do not support `subtitle`

</TabItem>

<TabItem label="Linux" icon="fa-brands:linux">

On Linux, dialog behaviour depends on the desktop environment:

- Use native notifications when available
- Follow desktop environment theme
- Position according to desktop environment rules
- Support `subtitle`
- Do not support user text input

</TabItem>
</Tabs>

## Best Practices

1. Check and request for authorization:
- macOS requires user authorization

2. Provide clear and concise notifications:
- Use descriptive titles, subtitles, text, and action titles

3. Handle dialog responses appropriately:
- Check for errors in notification responses
- Provide feedback for user actions

4. Consider platform conventions:
- Follow platform-specific notification patterns
- Respect system settings

## Examples

Explore this example:

- [Notifications](/examples/notifications)

## API Reference

### Service Management
| Method | Description |
|--------------------------------------------|-------------------------------------------------------|
| `New()` | Creates a new notifications service |

### Notification Authorization
| Method | Description |
|----------------------------------------------|------------------------------------------------------------|
| `RequestNotificationAuthorization()` | Requests permission to display notifications (macOS) |
| `CheckNotificationAuthorization()` | Checks current notification authorization status (macOS) |

### Sending Notifications
| Method | Description |
|------------------------------------------------------------|---------------------------------------------------|
| `SendNotification(options NotificationOptions)` | Sends a basic notification |
| `SendNotificationWithActions(options NotificationOptions)` | Sends an interactive notification with actions |

### Notification Categories
| Method | Description |
|---------------------------------------------------------------|---------------------------------------------------|
| `RegisterNotificationCategory(category NotificationCategory)` | Registers a reusable notification category |
| `RemoveNotificationCategory(categoryID string)` | Removes a previously registered category |

### Managing Notifications
| Method | Description |
|-------------------------------------------------|---------------------------------------------------------------------|
| `RemoveAllPendingNotifications()` | Removes all pending notifications (macOS and Linux only) |
| `RemovePendingNotification(identifier string)` | Removes a specific pending notification (macOS and Linux only) |
| `RemoveAllDeliveredNotifications()` | Removes all delivered notifications (macOS and Linux only) |
| `RemoveDeliveredNotification(identifier string)`| Removes a specific delivered notification (macOS and Linux only) |
| `RemoveNotification(identifier string)` | Removes a notification (Linux-specific) |

### Event Handling
| Method | Description |
|--------------------------------------------------------------------|-------------------------------------------------|
| `OnNotificationResponse(callback func(result NotificationResult))` | Registers a callback for notification responses |

### Structs and Types

#### NotificationOptions
```go
type NotificationOptions struct {
ID string // Unique identifier for the notification
Title string // Main notification title
Subtitle string // Subtitle text (macOS and Linux only)
Body string // Main notification content
CategoryID string // Category identifier for interactive notifications
Data map[string]interface{} // Custom data to associate with the notification
}
```

#### NotificationCategory
```go
type NotificationCategory struct {
ID string // Unique identifier for the category
Actions []NotificationAction // Button actions for the notification
HasReplyField bool // Whether to include a text input field
ReplyPlaceholder string // Placeholder text for the input field
ReplyButtonTitle string // Text for the reply button
}
```

#### NotificationAction
```go
type NotificationAction struct {
ID string // Unique identifier for the action
Title string // Button text
Destructive bool // Whether the action is destructive (macOS-specific)
}
```

#### NotificationResponse
```go
type NotificationResponse struct {
ID string // Notification identifier
ActionIdentifier string // Action that was triggered
CategoryID string // Category of the notification
Title string // Title of the notification
Subtitle string // Subtitle of the notification
Body string // Body text of the notification
UserText string // Text entered by the user
UserInfo map[string]interface{} // Custom data from the notification
}
```

#### NotificationResult
```go
type NotificationResult struct {
Response NotificationResponse // Response data
Error error // Any error that occurred
}
```
59 changes: 59 additions & 0 deletions v3/examples/notifications/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Welcome to Your New Wails3 Project!

Congratulations on generating your Wails3 application! This README will guide you through the next steps to get your project up and running.

## Getting Started

1. Navigate to your project directory in the terminal.

2. To run your application in development mode, use the following command:

```
wails3 dev
```

This will start your application and enable hot-reloading for both frontend and backend changes.

3. To build your application for production, use:

```
wails3 build
```

This will create a production-ready executable in the `build` directory.

## Exploring Wails3 Features

Now that you have your project set up, it's time to explore the features that Wails3 offers:

1. **Check out the examples**: The best way to learn is by example. Visit the `examples` directory in the `v3/examples` directory to see various sample applications.

2. **Run an example**: To run any of the examples, navigate to the example's directory and use:

```
go run .
```

Note: Some examples may be under development during the alpha phase.

3. **Explore the documentation**: Visit the [Wails3 documentation](https://v3.wails.io/) for in-depth guides and API references.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Double-check documentation URL.

The URL points to the Wails3 documentation which is still in development. Verify that this URL will be valid when the PR is merged.


🌐 Web query:

Is https://v3.wails.io/ a valid and accessible URL for Wails v3 documentation?

💡 Result:

The URL https://v3.wails.io/ does not appear to be valid or referenced in the official Wails v3 documentation. Based on search results, the correct URL for Wails v3 documentation is https://v3alpha.wails.io/, which is actively maintained and referenced in multiple guides and release notes[1][4][7][10][13].

This distinction is important because:

  • All Wails v3 documentation links explicitly use the v3alpha subdomain[1][4][7]
  • The v3alpha prefix reflects the alpha status of the current v3 release[1][6]
  • Official GitHub issues and CLI references specifically use v3alpha URLs[16][17]
  • The main Wails website (wails.io) still references v2 documentation as the primary stable version[5][11]

For developers working with Wails v3, the valid documentation URL is https://v3alpha.wails.io/. This aligns with the project's current pre-release status and matches all official references in March 2025 documentation[1][4][13].

Citations:


Update Documentation URL

The documentation link in v3/examples/notifications/README.md (line 39) currently points to https://v3.wails.io/, which is not valid for Wails v3. Please update it to https://v3alpha.wails.io/ to align with the official, maintained documentation references.


4. **Join the community**: Have questions or want to share your progress? Join the [Wails Discord](https://discord.gg/JDdSxwjhGf) or visit the [Wails discussions on GitHub](https://github.com/wailsapp/wails/discussions).

## Project Structure

Take a moment to familiarize yourself with your project structure:

- `frontend/`: Contains your frontend code (HTML, CSS, JavaScript/TypeScript)
- `main.go`: The entry point of your Go backend
- `app.go`: Define your application structure and methods here
- `wails.json`: Configuration file for your Wails project

## Next Steps

1. Modify the frontend in the `frontend/` directory to create your desired UI.
2. Add backend functionality in `main.go`.
3. Use `wails3 dev` to see your changes in real-time.
4. When ready, build your application with `wails3 build`.

Happy coding with Wails3! If you encounter any issues or have questions, don't hesitate to consult the documentation or reach out to the Wails community.
Loading