Skip to main content

shiny-notifications

Cross-platform local notification management for .NET MAUI apps using Shiny, supporting scheduled, repeating, and geofence-triggered notifications with channels, badges, and interactive actions.

Zur Installation springen

Quellinformationen

Repository
shinyorg/skills
Letzte Quellaktivität
15. August 2026 um 17:13
Erkannte Sprache von SKILL.md
Englisch
Sterne
4
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
2 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
shiny-notifications
description
Cross-platform local notification management for .NET MAUI apps using Shiny, supporting scheduled, repeating, and geofence-triggered notifications with channels, badges, and interactive actions.
auto_invoke
true
triggers
["local notifications","notification manager","notification channel","notification delegate","push notification","scheduled notification","geofence notification","repeating notification","badge count","notification actions","Shiny.Notifications","INotificationManager","INotificationDelegate","notification permission","notification sound","reminders AI tools","Shiny.Notifications.Extensions.AI","AddNotificationAITools","NotificationAITools","ReminderAICapabilities","channel importance"]
# Shiny Notifications ## When to Use This Skill Use this skill when the user needs to: - Send local notifications (immediate, scheduled, repeating, or geofence-triggered) - Manage notification channels with importance levels, sounds, and actions - Handle notification tap responses and interactive action buttons - Request notification permissions on iOS and Android - Manage app icon badge counts - Configure platform-specific notification behavior (Android ongoing, iOS subtitles, etc.) ## Library Overview | Item | Value | |---|---| | **NuGet Package** | `Shiny.Notifications` (iOS, Mac Catalyst, Android, macOS, Windows); `Shiny.Notifications.Linux` (Linux) | | **Primary Namespace** | `Shiny.Notifications` | | **Registration Namespace** | `Shiny` (extension methods on `IServiceCollection`) | | **Platforms** | iOS, Mac Catalyst, Android, macOS, Windows, Linux | | **Dependencies** | `Shiny.Core`, `Shiny.Locations`, `Shiny.Support.Repositories` | ### Linux Linux notifications ship in a separate package, `Shiny.Notifications.Linux`. They are delivered via the freedesktop `org.freedesktop.Notifications` D-Bus service (GNOME, KDE, XFCE, etc.) and support the same `INotificationManager` API surface as the other platforms. Scheduled notifications are tracked **in-process only** — there is no OS-level scheduler like BGTaskScheduler or WorkManager, so the host process must be running for a scheduled notification to fire. Channels are exposed but only a subset of freedesktop hints (urgency, category, image) are actually honoured by most daemons. Geofence triggers and time-sensitive flags are not applicable. Register with `services.AddNotifications<TDelegate>();` from the `Shiny` namespace — the same call site as the other platforms. ## Setup Register the notification services in your `MauiProgram.cs`: ```csharp using Shiny; // Without a delegate (fire-and-forget notifications) services.AddNotifications(); // With a delegate to handle notification taps services.AddNotifications<MyNotificationDelegate>(); ``` On iOS, you can optionally pass an `IosConfiguration` to control authorization and presentation options: ```csharp #if IOS || MACCATALYST services.AddNotifications<MyNotificationDelegate>(new IosConfiguration( UNAuthorizationOptions: UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound, PresentationOptions: UNNotificationPresentationOptions.Banner | UNNotificationPresentationOptions.Badge | UNNotificationPresentationOptions.Sound )); #endif ``` ## Code Generation Instructions When generating code that uses Shiny Notifications, follow these conventions: 1. **Always request access before sending notifications:** ```csharp var access = await notificationManager.RequestAccess(); if (access != AccessState.Available) { // Handle denied permission return; } ``` 2. **Use `AccessRequestFlags` when the notification uses triggers:** - `AccessRequestFlags.TimeSensitivity` for scheduled or repeating notifications. - `AccessRequestFlags.LocationAware` for geofence-triggered notifications. - Or use the `RequestRequiredAccess` extension method that infers flags from the notification object. 3. **A `Notification` must have a `Message` set** -- validation will throw otherwise. 4. **Only one trigger type per notification** -- you cannot mix `ScheduleDate`, `RepeatInterval`, and `Geofence` on the same notification. 5. **Implement `INotificationDelegate` for handling user taps:** ```csharp public class MyNotificationDelegate : INotificationDelegate { public async Task OnEntry(NotificationResponse response) { // response.Notification -- the original notification // response.ActionIdentifier -- which action button was pressed // response.Text -- text reply if action was TextReply type } } ``` 6. **Create channels before sending notifications that reference them:** ```csharp notificationManager.AddChannel(new Channel { Identifier = "alerts", Importance = ChannelImportance.High, Sound = ChannelSound.High }); ``` 7. **Use the convenience `Send` extension for simple notifications:** ```csharp await notificationManager.Send("Title", "Message body"); ``` 8. **For platform-specific properties, use the native subclasses:** - Android: `AndroidNotification` and `AndroidChannel` - iOS: `AppleNotification` and `AppleChannel` 9. **Always inject `INotificationManager`** via constructor injection -- never create instances directly. 10. **Use `CancelScope` wisely when cancelling:** - `CancelScope.DisplayedOnly` -- clears only shown notifications. - `CancelScope.Pending` -- clears only scheduled/triggered notifications. - `CancelScope.All` -- clears everything (default). ## Namespace Ambiguities - **`Notification`**: Both `Shiny.Notifications` and `Shiny.Push` define a `Notification` type. If both packages are referenced in the same project, do NOT add both namespaces as global usings. Use `Shiny.Notifications.Notification` FQN or a file-level `using Shiny.Notifications;` directive to disambiguate. ## Best Practices - Always check the `AccessState` result before attempting to send notifications. - Use channels to group notifications by category (e.g., "alerts", "reminders", "messages"). - The default channel (`Channel.Default`) always exists with `Identifier = "Notifications"` and `ChannelImportance.Low`. - Do not remove the default channel -- the library will throw an `InvalidOperationException`. - Set `BadgeCount` only on immediate notifications (not triggered ones) -- validation will fail otherwise. - Use `IntervalTrigger` with either `Interval` (raw TimeSpan) or `TimeOfDay` (daily/weekly recurring), never both. - For geofence notifications, ensure `Center` and `Radius` are both set on `GeofenceTrigger`. - On Android, create a drawable resource named `notification` for the default small icon, or set `SmallIconResourceName` on `AndroidNotification`. - Prefer the `RequestRequiredAccess` extension method to automatically determine needed permission flags from a `Notification` object. - Use `Payload` dictionary on `Notification` to pass custom data that you can read back in your `INotificationDelegate.OnEntry`. ## AI Tool Integration (Shiny.Notifications.Extensions.AI) The optional `Shiny.Notifications.Extensions.AI` package exposes `INotificationManager` as **reminder-framed** `Microsoft.Extensions.AI` tool functions (`AIFunction`s) for LLM agents. You opt-in exactly which operations the model can see — a read/write allow-list you control on behalf of the agent (**not** an OS permission prompt; the platform notification permission must already be granted). Read-only by default; write is opt-in. AOT-compatible (hand-built schemas, `JsonNode` results — no reflection). ```csharp using Shiny.Notifications; using Shiny.Notifications.Extensions.AI; builder.Services.AddNotifications(); // registers INotificationManager builder.Services.AddNotificationAITools(tools => tools .AddReminders(ReminderAICapabilities.ReadWrite, channel: "reminders") // channel is optional ); // resolve the bundle and pass the tools to any IChatClient var tools = sp.GetRequiredService<NotificationAITools>().Tools; var response = await chatClient.GetResponseAsync( messages, new ChatOptions { Tools = [.. tools] } ); ``` Key types: - `AddNotificationAITools(Action<INotificationAIToolBuilder>)` — DI extension; throws if nothing is added. - `INotificationAIToolBuilder` — `AddReminders(ReminderAICapabilities, string? channel = null)`. The channel (if supplied) must already be registered via `AddChannel`. - `ReminderAICapabilities` `[Flags]` — `None`, `Read` (default), `Write`, `ReadWrite`. - `NotificationAITools` — resolve from DI; `.Tools` is `IReadOnlyList<AITool>`. Generated tools (only for opted-in capabilities): `list_reminders` (pending/scheduled), `create_reminder` (omit both `scheduleFor`/`repeatDailyAt` to send now, `scheduleFor` for a one-time reminder, `repeatDailyAt` "HH:mm" for a daily one), `cancel_reminder` (by id). `scheduleFor` and `repeatDailyAt` are mutually exclusive; dates are ISO-8601. > The AI tools assume permissions are already granted — they do **not** trigger the platform permission UI (needs a foreground activity). Call `INotificationManager.RequestAccess(...)` from the app before invoking the agent. ## Reference Files - [API Reference](reference/api-reference.md)
Auf GitHub ansehen