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
آخر نشاط في المصدر
١٥ سبتمبر ٢٠٢٦ في ١٧:٥٤
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٬٥٨٣
التفرعات
٢٤٨

خيارات التثبيت

يُحدَّد 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