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월 27일 03:31
감지된 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.Geofencing` (Android only - geofence-triggered notifications), `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에서 보기