@choochmeque/tauri-plugin-notifications-api 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 - Present Tauri Apps Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,550 @@
1
+ [![NPM Version](https://img.shields.io/npm/v/@choochmeque%2Ftauri-plugin-notifications-api)](https://www.npmjs.com/package/@choochmeque/tauri-plugin-notifications-api)
2
+ [![Crates.io Version](https://img.shields.io/crates/v/tauri-plugin-notifications)](https://crates.io/crates/tauri-plugin-notifications)
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
4
+
5
+ # Tauri Plugin Notifications
6
+
7
+ A Tauri v2 plugin for sending system notifications on desktop and mobile platforms. Send toast notifications (brief auto-expiring OS window elements) to your user with support for rich content, scheduling, actions, and channels.
8
+
9
+ ## Features
10
+
11
+ - Send simple and rich notifications
12
+ - Schedule notifications for specific dates or recurring intervals
13
+ - Interactive notifications with custom actions
14
+ - Notification channels (Android) for organized notifications
15
+ - Manage pending and active notifications
16
+ - Support for attachments, icons, and custom sounds
17
+ - Inbox and large text notification styles
18
+ - Group notifications with summary support
19
+ - Permission management
20
+ - Real-time notification events
21
+
22
+ ## Platform Support
23
+
24
+ - **macOS**: Native notification center integration
25
+ - **Windows**: Windows notification system
26
+ - **Linux**: notify-rust with desktop notification support
27
+ - **iOS**: User Notifications framework
28
+ - **Android**: Android notification system with channels
29
+
30
+ ## Installation
31
+
32
+ Install the JavaScript package:
33
+
34
+ ```bash
35
+ npm install @choochmeque/tauri-plugin-notifications-api
36
+ # or
37
+ yarn add @choochmeque/tauri-plugin-notifications-api
38
+ # or
39
+ pnpm add @choochmeque/tauri-plugin-notifications-api
40
+ ```
41
+
42
+ Add the plugin to your Tauri project's `Cargo.toml`:
43
+
44
+ ```toml
45
+ [dependencies]
46
+ tauri-plugin-notifications = "0.1"
47
+ ```
48
+
49
+ Configure the plugin permissions in your `capabilities/default.json`:
50
+
51
+ ```json
52
+ {
53
+ "permissions": [
54
+ "notifications:default"
55
+ ]
56
+ }
57
+ ```
58
+
59
+ Register the plugin in your Tauri app:
60
+
61
+ ```rust
62
+ fn main() {
63
+ tauri::Builder::default()
64
+ .plugin(tauri_plugin_notifications::init())
65
+ .run(tauri::generate_context!())
66
+ .expect("error while running tauri application");
67
+ }
68
+ ```
69
+
70
+ ## Usage
71
+
72
+ ### JavaScript/TypeScript
73
+
74
+ #### Basic Notifications
75
+
76
+ ```typescript
77
+ import {
78
+ isPermissionGranted,
79
+ requestPermission,
80
+ sendNotification
81
+ } from '@choochmeque/tauri-plugin-notifications-api';
82
+
83
+ // Check and request permission
84
+ let permissionGranted = await isPermissionGranted();
85
+ if (!permissionGranted) {
86
+ const permission = await requestPermission();
87
+ permissionGranted = permission === 'granted';
88
+ }
89
+
90
+ // Send simple notification
91
+ if (permissionGranted) {
92
+ sendNotification('Hello from Tauri!');
93
+
94
+ // Or with more details
95
+ sendNotification({
96
+ title: 'TAURI',
97
+ body: 'Tauri is awesome!'
98
+ });
99
+ }
100
+ ```
101
+
102
+ #### Rich Notifications
103
+
104
+ ```typescript
105
+ import { sendNotification } from '@choochmeque/tauri-plugin-notifications-api';
106
+
107
+ // Notification with icon and sound
108
+ await sendNotification({
109
+ id: 1,
110
+ title: 'New Message',
111
+ body: 'You have a new message from John',
112
+ icon: 'message_icon',
113
+ sound: 'notification_sound',
114
+ autoCancel: true
115
+ });
116
+
117
+ // Large text notification
118
+ await sendNotification({
119
+ id: 2,
120
+ title: 'Article',
121
+ body: 'New article available',
122
+ largeBody: 'This is a much longer text that will be displayed when the user expands the notification...',
123
+ summary: 'Read more'
124
+ });
125
+
126
+ // Inbox style notification
127
+ await sendNotification({
128
+ id: 3,
129
+ title: 'Email',
130
+ body: '3 new emails',
131
+ inboxLines: [
132
+ 'Alice: Meeting at 3pm',
133
+ 'Bob: Project update',
134
+ 'Charlie: Lunch tomorrow?'
135
+ ]
136
+ });
137
+ ```
138
+
139
+ #### Scheduled Notifications
140
+
141
+ ```typescript
142
+ import { sendNotification, Schedule } from '@choochmeque/tauri-plugin-notifications-api';
143
+
144
+ // Schedule notification for specific date
145
+ await sendNotification({
146
+ title: 'Reminder',
147
+ body: 'Time for your meeting!',
148
+ schedule: Schedule.at(new Date(2024, 0, 15, 14, 30))
149
+ });
150
+
151
+ // Repeating notification
152
+ await sendNotification({
153
+ title: 'Daily Reminder',
154
+ body: 'Don\'t forget to exercise!',
155
+ schedule: Schedule.at(new Date(2024, 0, 15, 9, 0), true)
156
+ });
157
+
158
+ // Schedule with interval
159
+ await sendNotification({
160
+ title: 'Break Time',
161
+ body: 'Time to take a break!',
162
+ schedule: Schedule.interval({
163
+ hour: 1
164
+ })
165
+ });
166
+
167
+ // Schedule every X units
168
+ import { ScheduleEvery } from '@choochmeque/tauri-plugin-notifications-api';
169
+
170
+ await sendNotification({
171
+ title: 'Hourly Update',
172
+ body: 'Checking in every hour',
173
+ schedule: Schedule.every(ScheduleEvery.Hour, 1)
174
+ });
175
+ ```
176
+
177
+ #### Interactive Notifications with Actions
178
+
179
+ ```typescript
180
+ import {
181
+ sendNotification,
182
+ registerActionTypes,
183
+ onAction
184
+ } from '@choochmeque/tauri-plugin-notifications-api';
185
+
186
+ // Register action types
187
+ await registerActionTypes([{
188
+ id: 'message-actions',
189
+ actions: [
190
+ {
191
+ id: 'reply',
192
+ title: 'Reply',
193
+ input: true,
194
+ inputPlaceholder: 'Type your reply...',
195
+ inputButtonTitle: 'Send'
196
+ },
197
+ {
198
+ id: 'mark-read',
199
+ title: 'Mark as Read'
200
+ },
201
+ {
202
+ id: 'delete',
203
+ title: 'Delete',
204
+ destructive: true
205
+ }
206
+ ]
207
+ }]);
208
+
209
+ // Send notification with actions
210
+ await sendNotification({
211
+ title: 'New Message',
212
+ body: 'You have a new message',
213
+ actionTypeId: 'message-actions'
214
+ });
215
+
216
+ // Listen for action events
217
+ const unlisten = await onAction((notification) => {
218
+ console.log('Action performed on notification:', notification);
219
+ });
220
+
221
+ // Stop listening
222
+ unlisten();
223
+ ```
224
+
225
+ #### Notification Channels (Android)
226
+
227
+ ```typescript
228
+ import {
229
+ createChannel,
230
+ channels,
231
+ removeChannel,
232
+ Importance,
233
+ Visibility
234
+ } from '@choochmeque/tauri-plugin-notifications-api';
235
+
236
+ // Create a notification channel
237
+ await createChannel({
238
+ id: 'messages',
239
+ name: 'Messages',
240
+ description: 'Notifications for new messages',
241
+ importance: Importance.High,
242
+ visibility: Visibility.Private,
243
+ sound: 'message_sound',
244
+ vibration: true,
245
+ lights: true,
246
+ lightColor: '#FF0000'
247
+ });
248
+
249
+ // Send notification to specific channel
250
+ await sendNotification({
251
+ channelId: 'messages',
252
+ title: 'New Message',
253
+ body: 'You have a new message'
254
+ });
255
+
256
+ // List all channels
257
+ const channelList = await channels();
258
+
259
+ // Remove a channel
260
+ await removeChannel('messages');
261
+ ```
262
+
263
+ #### Managing Notifications
264
+
265
+ ```typescript
266
+ import {
267
+ pending,
268
+ active,
269
+ cancel,
270
+ cancelAll,
271
+ removeActive,
272
+ removeAllActive
273
+ } from '@choochmeque/tauri-plugin-notifications-api';
274
+
275
+ // Get pending notifications
276
+ const pendingNotifications = await pending();
277
+
278
+ // Cancel specific pending notifications
279
+ await cancel([1, 2, 3]);
280
+
281
+ // Cancel all pending notifications
282
+ await cancelAll();
283
+
284
+ // Get active notifications
285
+ const activeNotifications = await active();
286
+
287
+ // Remove specific active notifications
288
+ await removeActive([
289
+ { id: 1 },
290
+ { id: 2, tag: 'message' }
291
+ ]);
292
+
293
+ // Remove all active notifications
294
+ await removeAllActive();
295
+ ```
296
+
297
+ #### Notification Events
298
+
299
+ ```typescript
300
+ import { onNotificationReceived } from '@choochmeque/tauri-plugin-notifications-api';
301
+
302
+ // Listen for notifications received
303
+ const unlisten = await onNotificationReceived((notification) => {
304
+ console.log('Notification received:', notification);
305
+ });
306
+
307
+ // Stop listening
308
+ unlisten();
309
+ ```
310
+
311
+ ### Rust
312
+
313
+ ```rust
314
+ use tauri_plugin_notifications::{NotificationExt, Schedule, ScheduleEvery};
315
+
316
+ // Send simple notification
317
+ app.notification()
318
+ .builder()
319
+ .title("Hello")
320
+ .body("This is a notification from Rust!")
321
+ .show()?;
322
+
323
+ // Send rich notification
324
+ app.notification()
325
+ .builder()
326
+ .id(1)
327
+ .title("New Message")
328
+ .body("You have a new message")
329
+ .icon("message_icon")
330
+ .sound("notification_sound")
331
+ .auto_cancel()
332
+ .show()?;
333
+
334
+ // Scheduled notification
335
+ app.notification()
336
+ .builder()
337
+ .title("Reminder")
338
+ .body("Time for your meeting!")
339
+ .schedule(Schedule::at(date_time, false, false))
340
+ .show()?;
341
+
342
+ // Notification with attachments
343
+ use tauri_plugin_notifications::Attachment;
344
+
345
+ app.notification()
346
+ .builder()
347
+ .title("Photo Shared")
348
+ .body("Check out this image!")
349
+ .attachment(Attachment {
350
+ id: "image1".to_string(),
351
+ url: "file:///path/to/image.jpg".to_string(),
352
+ })
353
+ .show()?;
354
+ ```
355
+
356
+ ## API Reference
357
+
358
+ ### `isPermissionGranted()`
359
+ Checks if the permission to send notifications is granted.
360
+
361
+ **Returns:** `Promise<boolean>`
362
+
363
+ ### `requestPermission()`
364
+ Requests the permission to send notifications.
365
+
366
+ **Returns:** `Promise<'granted' | 'denied' | 'default'>`
367
+
368
+ ### `sendNotification(options: Options | string)`
369
+ Sends a notification to the user. Can be called with a simple string for the title or with a detailed options object.
370
+
371
+ **Parameters:**
372
+ - `options`: Notification options or title string
373
+ - `id`: Notification identifier (32-bit integer)
374
+ - `channelId`: Channel identifier (Android)
375
+ - `title`: Notification title
376
+ - `body`: Notification body
377
+ - `schedule`: Schedule for delayed or recurring notifications
378
+ - `largeBody`: Multiline text content
379
+ - `summary`: Detail text for large notifications
380
+ - `actionTypeId`: Action type identifier
381
+ - `group`: Group identifier
382
+ - `groupSummary`: Mark as group summary (Android)
383
+ - `sound`: Sound resource name
384
+ - `inboxLines`: Array of lines for inbox style (max 5)
385
+ - `icon`: Notification icon
386
+ - `largeIcon`: Large icon (Android)
387
+ - `iconColor`: Icon color (Android)
388
+ - `attachments`: Array of attachments
389
+ - `extra`: Extra payload data
390
+ - `ongoing`: Non-dismissible notification (Android)
391
+ - `autoCancel`: Auto-cancel on click
392
+ - `silent`: Silent notification (iOS)
393
+ - `visibility`: Notification visibility
394
+ - `number`: Number of items (Android)
395
+
396
+ ### `registerActionTypes(types: ActionType[])`
397
+ Register actions that are performed when the user clicks on the notification.
398
+
399
+ **Parameters:**
400
+ - `types`: Array of action type objects with:
401
+ - `id`: Action type identifier
402
+ - `actions`: Array of action objects
403
+ - `id`: Action identifier
404
+ - `title`: Action title
405
+ - `requiresAuthentication`: Requires device unlock
406
+ - `foreground`: Opens app in foreground
407
+ - `destructive`: Destructive action style
408
+ - `input`: Enable text input
409
+ - `inputButtonTitle`: Input button label
410
+ - `inputPlaceholder`: Input placeholder text
411
+
412
+ ### `pending()`
413
+ Retrieves the list of pending notifications.
414
+
415
+ **Returns:** `Promise<PendingNotification[]>`
416
+
417
+ ### `cancel(notifications: number[])`
418
+ Cancels the pending notifications with the given list of identifiers.
419
+
420
+ ### `cancelAll()`
421
+ Cancels all pending notifications.
422
+
423
+ ### `active()`
424
+ Retrieves the list of active notifications.
425
+
426
+ **Returns:** `Promise<ActiveNotification[]>`
427
+
428
+ ### `removeActive(notifications: Array<{ id: number; tag?: string }>)`
429
+ Removes the active notifications with the given list of identifiers.
430
+
431
+ ### `removeAllActive()`
432
+ Removes all active notifications.
433
+
434
+ ### `createChannel(channel: Channel)`
435
+ Creates a notification channel (Android).
436
+
437
+ **Parameters:**
438
+ - `channel`: Channel configuration
439
+ - `id`: Channel identifier
440
+ - `name`: Channel name
441
+ - `description`: Channel description
442
+ - `sound`: Sound resource name
443
+ - `lights`: Enable notification light
444
+ - `lightColor`: Light color
445
+ - `vibration`: Enable vibration
446
+ - `importance`: Importance level (None, Min, Low, Default, High)
447
+ - `visibility`: Visibility level (Secret, Private, Public)
448
+
449
+ ### `removeChannel(id: string)`
450
+ Removes the channel with the given identifier.
451
+
452
+ ### `channels()`
453
+ Retrieves the list of notification channels.
454
+
455
+ **Returns:** `Promise<Channel[]>`
456
+
457
+ ### `onNotificationReceived(callback: (notification: Options) => void)`
458
+ Listens for notification received events.
459
+
460
+ **Returns:** `Promise<PluginListener>` with `unlisten()` method
461
+
462
+ ### `onAction(callback: (notification: Options) => void)`
463
+ Listens for notification action performed events.
464
+
465
+ **Returns:** `Promise<PluginListener>` with `unlisten()` method
466
+
467
+ ## Platform Differences
468
+
469
+ ### Desktop (macOS, Windows, Linux)
470
+ - Uses native notification systems
471
+ - Actions support varies by platform
472
+ - Limited scheduling capabilities on some platforms
473
+ - Channels not applicable (Android-specific)
474
+
475
+ ### iOS
476
+ - Requires permission request
477
+ - Rich notifications with attachments
478
+ - Action support with input options
479
+ - Silent notifications available
480
+ - Group notifications (thread identifiers)
481
+
482
+ ### Android
483
+ - Notification channels required for Android 8.0+
484
+ - Full scheduling support
485
+ - Rich notification styles (inbox, large text)
486
+ - Ongoing notifications for background tasks
487
+ - Detailed importance and visibility controls
488
+ - Custom sounds, vibration, and lights
489
+
490
+ ## Platform Setup
491
+
492
+ ### iOS Setup
493
+
494
+ 1. The plugin automatically configures notification capabilities
495
+ 2. Add notification sounds to your Xcode project if needed:
496
+ - Add sound files to your iOS project
497
+ - Place in app bundle
498
+ - Reference by filename (without extension)
499
+
500
+ ### Android Setup
501
+
502
+ 1. The plugin automatically includes required permissions
503
+ 2. For custom sounds:
504
+ - Place sound files in `res/raw/` folder
505
+ - Reference by filename (without extension)
506
+ 3. For custom icons:
507
+ - Place icons in `res/drawable/` folder
508
+ - Reference by filename (without extension)
509
+
510
+ ## Testing
511
+
512
+ ### Desktop
513
+ - Notifications appear in the system notification center
514
+ - Test different notification types and interactions
515
+ - Verify notification persistence and dismissal
516
+
517
+ ### iOS
518
+ - Test on physical devices (simulator support is limited)
519
+ - Request permissions before sending notifications
520
+ - Test scheduled notifications with different intervals
521
+ - Verify action handling and notification grouping
522
+
523
+ ### Android
524
+ - Create and test notification channels
525
+ - Test different importance levels and visibility settings
526
+ - Verify scheduled notifications work with device sleep
527
+ - Test ongoing notifications for background tasks
528
+ - Verify notification styles (inbox, large text, etc.)
529
+
530
+ ## Troubleshooting
531
+
532
+ ### Notifications not appearing
533
+ - Verify permissions are granted
534
+ - On Android, ensure notification channel exists
535
+ - Check system notification settings
536
+ - Verify notification ID is unique
537
+
538
+ ### Scheduled notifications not firing
539
+ - Check device power settings (battery optimization)
540
+ - On Android, use `allowWhileIdle` for critical notifications
541
+ - Verify schedule time is in the future
542
+
543
+ ### Actions not working
544
+ - Ensure action types are registered before sending notification
545
+ - Verify action IDs match between registration and handling
546
+ - Check platform-specific action support
547
+
548
+ ## License
549
+
550
+ [MIT](LICENSE)