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.

インストールへ移動

ソース情報

リポジトリ
shinyorg/shiny
ソースの最終更新活動
2026年9月15日 17:54
検出された SKILL.md の言語
英語
スター
1,583
フォーク
248

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
2 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
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. Scheduled and repeating notifications are checked every 30 seconds, so expect up to ~30s of lateness. `IntervalTrigger.Interval` repeats every interval from the `Send` call; `IntervalTrigger.TimeOfDay` is local time and fires today if that time is still ahead, otherwise the next day (or next matching `DayOfWeek`). 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)
GitHubで見る