Tauri 插件通知
一个 Tauri v2 插件,用于在桌面和移动平台发送通知. 通过FCM、APNs和UnitedPush发送土司通知(简便自动过期OS窗口元素),支持内容丰富、调度、行动、渠道和推送.
特征
- 发送简单而丰富的通知
- 具体日期或重复间隔的附表通知
- 与自定义动作的互动通知
- 有组织的通知通知渠道(Android)
- 管理待处理和正在使用的通知
- 支持附件、图标和自定义声音
- 收件箱和大文本通知样式
- 附有摘要支持的小组通知
- 权限管理
- 实时通知活动
平台支持
- 马科斯: 土著通知中心一体化
- 窗口: 视窗通知系统
- 链接: 有桌面通知支持的通知- 信任; 通过 UnitedPush 推动通知
- 免费BSD: 在一个 D- Bus 会话总线上带有桌面通知支持的通知- rust
- iOS系统: 用户通知框架
- 机器人: 有频道的Android通知系统
安装
安装 JavaScript 软件包 :
npm install @choochmeque/tauri-plugin-notifications-api
# or
yarn add @choochmeque/tauri-plugin-notifications-api
# or
pnpm add @choochmeque/tauri-plugin-notifications-api
在您的 Tauri 工程中添加插件 Cargo.toml数字 :
[dependencies]
tauri-plugin-notifications = "0.5"
按下通知特性
这个 push-notifications 特性是 默认禁用。为了提供推动通知支持:
[dependencies]
tauri-plugin-notifications = { version = "0.5", features = ["push-notifications"] }
这样可以:
- Firebase Cloud 通讯支持在 Android 上
- IOS 和 macOS 上的 APN( Apple Push 通知服务)支持
- Linux上的统一Push支持( D- Bus 发行商协议)
说明: 目前支持在iOS,Android,macOS,和Linux上发布Push通知. 视窗支持尚未可用 .
在 Linux 上, 您还需要一个 UnitedPush 分销商 已安装应用程序( ntfy, NextPush, Conversions等) 分销商名单) (中文(简体) ). 插件本身是无国籍的 : 您只为当前进程设定生命 。 见 Linux 统一 Push 设置 详情见下文.
没有此功能 :
- Android 建筑中不包括火基地依赖性
- 按下通知注册代码已禁用
- 这个
registerForPushNotifications()如果调用函数, 函数将返回出错
桌面通知后端( 通知- Rust)
这个 notify-rust 特性是 默认启用 并使用 通知失败 货箱.
何时使用通知失败( 默认) :
- Linux、 FreeBSD、 macOS 和 Windows 的简单通知
- 跨平台一致性
- 基本通知特征(标题、正文、图标)
在Linux和FreeBSD上,通知-rust总是被启用,因为它是唯一的桌面后端. 需要运行一个 D- Bus 会话总线和一个桌面通知守护进程 .
禁用通知失败时 :
- 您需要带有高级功能( 动作、 英雄图像、 排程) 的本地 Windows 土司通知
- 您需要 MacOS/ Windows 上的平台专用通知功能
要禁用 notify-rust 并使用本地平台执行:
[dependencies]
tauri-plugin-notifications = { version = "0.5", default-features = false }
要禁用 notify-rust 并启用按键通知:
[dependencies]
tauri-plugin-notifications = { version = "0.5", default-features = false, features = ["push-notifications"] }
配置您的插件权限 capabilities/default.json数字 :
{
"permissions": [
"notifications:default"
]
}
在您的 Tauri 应用程序中注册插件 :
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_notifications::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
示例应用
一个示例应用在 examples/notifications-demo 显示所有插件特性 :
- 许可管理和推动通知(移动)
- 基本通知、排期通知和类型通知
- 带有动作按钮的交互式通知
- 通知频道(Android)
- 待处理和积极的通知管理
- 记录活动听众
运行它:
cd examples/notifications-demo
pnpm install
pnpm tauri dev
使用量
Java 脚本/ Type 脚本
基本通知
import {
isPermissionGranted,
requestPermission,
sendNotification
} from '@choochmeque/tauri-plugin-notifications-api';
// Check and request permission
let permissionGranted = await isPermissionGranted();
if (!permissionGranted) {
const permission = await requestPermission();
permissionGranted = permission === 'granted';
}
// Send simple notification
if (permissionGranted) {
sendNotification('Hello from Tauri!');
// Or with more details
sendNotification({
title: 'TAURI',
body: 'Tauri is awesome!'
});
}
丰富的通知
import { sendNotification } from '@choochmeque/tauri-plugin-notifications-api';
// Notification with icon and sound
await sendNotification({
id: 1,
title: 'New Message',
body: 'You have a new message from John',
icon: 'message_icon',
sound: 'notification_sound',
autoCancel: true
});
// Large text notification
await sendNotification({
id: 2,
title: 'Article',
body: 'New article available',
largeBody: 'This is a much longer text that will be displayed when the user expands the notification...',
summary: 'Read more'
});
// Inbox style notification
await sendNotification({
id: 3,
title: 'Email',
body: '3 new emails',
inboxLines: [
'Alice: Meeting at 3pm',
'Bob: Project update',
'Charlie: Lunch tomorrow?'
]
});
排定的通知
import { sendNotification, Schedule } from '@choochmeque/tauri-plugin-notifications-api';
// Schedule notification for specific date
await sendNotification({
title: 'Reminder',
body: 'Time for your meeting!',
schedule: Schedule.at(new Date(2024, 0, 15, 14, 30))
});
// Repeating notification
await sendNotification({
title: 'Daily Reminder',
body: 'Don\'t forget to exercise!',
schedule: Schedule.at(new Date(2024, 0, 15, 9, 0), true)
});
// Schedule with interval
await sendNotification({
title: 'Break Time',
body: 'Time to take a break!',
schedule: Schedule.interval({
hour: 1
})
});
// Schedule every X units
import { ScheduleEvery } from '@choochmeque/tauri-plugin-notifications-api';
await sendNotification({
title: 'Hourly Update',
body: 'Checking in every hour',
schedule: Schedule.every(ScheduleEvery.Hour, 1)
});
与行动互动通知
import {
sendNotification,
registerActionTypes,
onAction
} from '@choochmeque/tauri-plugin-notifications-api';
// Register action types
await registerActionTypes([{
id: 'message-actions',
actions: [
{
id: 'reply',
title: 'Reply',
input: true,
inputPlaceholder: 'Type your reply...',
inputButtonTitle: 'Send'
},
{
id: 'mark-read',
title: 'Mark as Read'
},
{
id: 'delete',
title: 'Delete',
destructive: true
}
]
}]);
// Send notification with actions
await sendNotification({
title: 'New Message',
body: 'You have a new message',
actionTypeId: 'message-actions'
});
// Listen for action events
const unlisten = await onAction((notification) => {
console.log('Action performed on notification:', notification);
});
// Stop listening
unlisten();
通知频道(Android)
import {
createChannel,
channels,
removeChannel,
Importance,
Visibility
} from '@choochmeque/tauri-plugin-notifications-api';
// Create a notification channel
await createChannel({
id: 'messages',
name: 'Messages',
description: 'Notifications for new messages',
importance: Importance.High,
visibility: Visibility.Private,
sound: 'message_sound',
vibration: true,
lights: true,
lightColor: '#FF0000'
});
// Send notification to specific channel
await sendNotification({
channelId: 'messages',
title: 'New Message',
body: 'You have a new message'
});
// List all channels
const channelList = await channels();
// Remove a channel
await removeChannel('messages');
管理通知
import {
pending,
active,
cancel,
cancelAll,
removeActive,
removeAllActive
} from '@choochmeque/tauri-plugin-notifications-api';
// Get pending notifications
const pendingNotifications = await pending();
// Cancel specific pending notifications
await cancel([1, 2, 3]);
// Cancel all pending notifications
await cancelAll();
// Get active notifications
const activeNotifications = await active();
// Remove specific active notifications
await removeActive([
{ id: 1 },
{ id: 2, tag: 'message' }
]);
// Remove all active notifications
await removeAllActive();
通知事件
import { onNotificationReceived } from '@choochmeque/tauri-plugin-notifications-api';
// Listen for notifications received
const unlisten = await onNotificationReceived((notification) => {
console.log('Notification received:', notification);
});
// Stop listening
unlisten();
按下通知( 移动)
import { registerForPushNotifications } from '@choochmeque/tauri-plugin-notifications-api';
// Register for push notifications and get device token
try {
const token = await registerForPushNotifications();
console.log('Push token:', token);
// Send this token to your server to send push notifications
} catch (error) {
console.error('Failed to register for push notifications:', error);
}
锈
use tauri_plugin_notifications::{NotificationsExt, Schedule, ScheduleEvery};
// Send simple notification
app.notifications()
.builder()
.title("Hello")
.body("This is a notification from Rust!")
.show()?;
// Send rich notification
app.notifications()
.builder()
.id(1)
.title("New Message")
.body("You have a new message")
.icon("message_icon")
.sound("notification_sound")
.auto_cancel()
.show()?;
// Scheduled notification
app.notifications()
.builder()
.title("Reminder")
.body("Time for your meeting!")
.schedule(Schedule::at(date_time, false, false))
.show()?;
// Notification with attachments
use tauri_plugin_notifications::Attachment;
app.notifications()
.builder()
.title("Photo Shared")
.body("Check out this image!")
.attachment(Attachment {
id: "image1".to_string(),
url: "file:///path/to/image.jpg".to_string(),
})
.show()?;
API 参考
isPermissionGranted()
检查是否获准发送通知 .
回返情况: Promise<boolean>
requestPermission()
请求允许发送通知.
回返情况: Promise<'granted' | 'denied' | 'default'>
registerForPushNotifications()
注册该应用程序用于推进通知 。 在Android上,它检索到 FCM 设备代号;在iOS上,它请求远程通知的许可和注册;在Linux上,它与选定的UnitedPush发行商注册.
回返情况: Promise<string> 平台专用标识符:
- iOS: APNs 设备符号
- Android: FCM 设备令牌
- Linux: 统一Push端点 URL( 您的后端 POST 有效载荷的 URL)
listDistributors() (Linux / 仅统一推出)
按其D-Bus总线名称列出每个运行中的统一Push发行商(例如:. org.unifiedpush.Distributor.ntfy) (中文(简体) ). 当没有安装时返回一个空阵列——这就是要求用户从 https://unifedpush.org/uses/distributors/ 互联网档案馆的存檔,存档日期2013-12-02。 。 。 .
扔出非Linux平台,因为基础的Tauri命令没有在那里注册.
回返情况: Promise<string[]>
setDistributor(name: string) (Linux / 仅统一推出)
抓取下一张发行商 registerForPushNotifications() 电话. 一定是之前打来的 registerForPushNotifications() ——在注册成功后拨打,对现有的端点没有影响;再换发商,取消注册和注册.
选择是 未坚持 横跨发布——如果主机应用程序想记住用户的选择,则存储,并在启动时重新应用. 如果从未呼叫, 第一个条目来自 listDistributors() 已使用.
拒绝如果 name 目前没有在公交车上。 投出非Linux平台.
setToken(token: string) (Linux / 仅统一推出)
设置随后使用的统一Push客户端符号 registerForPushNotifications() 打电话. 一定是之前打来的 registerForPushNotifications() ——在注册成功后拨打,对现有终点没有影响.
发行方返回的端点 URL 来源于 (app_identifier, client_token),因此,在发射过程中传递同样的同物,产生相同的端点URL. 标志是 未坚持 ——主机app如果想要端点稳定,必须存储并重新在启动时应用.
如果从未调用,在每个寄存器调用(FCM/APNs-style sord room)上都会生成一个新的UUID——应用程序每次都将新的端点URL推到后端.
拒绝如果 token 为空。 投出非Linux平台.
sendNotification(options: Options | string)
向用户发送通知。 可以用简单的标题字符串调用,也可以用详细的选项对象调用.
参数:
options通知选项或标题字符串id: 通知标识符(32位整数)channelId: 频道标识符 (Android)title页:1body: 通知机构schedule: 延迟或反复通知的时间表largeBody: 多行文本内容summary: 大通知的详细文本actionTypeId: 动作类型标识符group: 组标识符groupSummary: 标为组摘要 (Android)sound: 声音资源名inboxLines: 收件箱样式的行序( 最大 5)icon: 通知图标largeIcon: 大图标 (Android)iconColor: 图标颜色 (Android)attachments: 附件阵列extra: 额外有效载荷数据ongoing: 不可解除通知(Android)autoCancel: 点击时自动取消silent: 无声通知(iOS)visibility: 通知可见度number: 物品数量(Android)
registerActionTypes(types: ActionType[])
登记用户点击通知时执行的行动.
参数:
types: 动作类型对象的阵列:id: 动作类型标识符actions: 动作对象阵列id: 行动标识符title: 动作标题requiresAuthentication: 需要设备解锁foreground: 在前景中打开应用程序destructive: 破坏动作样式input: 启用文本输入inputButtonTitle: 输入按钮标签inputPlaceholder: 输入占位符文本
pending()
获取待处理通知清单.
回返情况: Promise<PendingNotification[]>
cancel(notifications: number[])
以给定的识别器列表取消未决通知.
cancelAll()
取消所有待定通知.
active()
获取活动通知列表 .
回返情况: Promise<ActiveNotification[]>
removeActive(notifications: Array<{ id: number; tag?: string }>)
删除带有指定标识符列表的有效通知.
removeAllActive()
删除所有活动通知.
createChannel(channel: Channel)
创建通知频道(Android).
参数:
channel: 频道配置id: 频道标识符name频道名称description: 频道描述sound: 声音资源名lights: 启用通知灯lightColor: 浅色vibration: 启用振动importance: 重要级别(无、敏、低、默认、高)visibility:能见度(秘密,私人,公共)
removeChannel(id: string)
删除带有指定标识符的频道.
channels()
检索通知渠道清单.
回返情况: Promise<Channel[]>
onNotificationReceived(callback: (notification: Options) => void)
接到通知的听众收到事件.
回返情况: Promise<PluginListener> 与 unlisten() 方法
onAction(callback: (notification: Options) => void)
通知行动听取会进行了活动.
回返情况: Promise<PluginListener> 与 unlisten() 方法
平台差异
桌面( MacOS、 Windows、 Linux)
- 使用本地通知系统
- 行动支持因平台而异
- 某些平台的时间安排能力有限
- 不适用的通道( Android )
- Linux 通过 UnitedPush 额外支持服务器驱动的推动(参见 Linux 统一 Push 设置(中文(简体) )
iOS系统
- 需要请求许可
- 带有附件的丰富通知
- 附有投入选项的行动支助
- 可用无声通知
- 分组通知(线索识别符)
机器人
- Android 8.0+ 所需的通知渠道
- 全部排程支持
- 丰富的通知样式( 收件箱, 大文本)
- 正在进行中的背景任务通知
- 详细的重要性和能见度控制
- 自定义声音、振动和灯光
平台设置
iOS 设置
- 插件自动配置通知能力
- 如果需要, 在您的 Xcode 项目中添加通知声音 :
- 在您的 iOS 工程中添加声音文件
- 在应用程序捆绑中
- 按文件名分列的参考文献( 不扩展名)
Android 设置
- 插件自动包含所需的权限
- 对于自定义声音 :
- 将声音文件放入
res/raw/文件夹 - 按文件名分列的参考文献( 不扩展名)
- 将声音文件放入
- 对于自定义图标:
- 将图标放入
res/drawable/文件夹 - 按文件名分列的参考文献( 不扩展名)
- 将图标放入
- 推进通知(FCM) - 这些步骤必须在您的Tauri应用项目中完成:
- 在 火地控台
- 下载
google-services.json来自 Firebase 控制台的文件 - 地点
google-services.json在你的Tauri应用程序gen/android/app/目录 - 在您的应用程序中添加 Google 服务类路径
gen/android/build.gradle.kts数字 :buildscript { repositories { google() mavenCentral() } dependencies { classpath("com.google.gms:google-services:4.4.2") } } - 在底部应用插件
gen/android/app/build.gradle.kts数字 :apply(plugin = "com.google.gms.google-services") - 通知插件中已经包含 Firebase 云发送依赖性
push-notifications特性已启用
Linux 统一 Push 设置
UnitedPush 是一个用户安装的联邦推进协议 分销商 app通过 D- Bus 向您的应用程序发送消息 。 插件执行 连接器 侧并曝光标准 registerForPushNotifications() 流动.
- 启用
push-notifications特性 在你身边Cargo.toml(这拉入zbus编号 :tokio编号 :uuid(原始内容存档于2018-10-21). Deps on Linux. - 安装分发器。用户选择一个(或者您用您的应用程序运送一个):
- 纯度 ——最小,可自见,有 Linux 桌面客户端
- 下一个推 — 由下一台云端服务器支持
- 对话 - 基于XMPP的
- 完整列表 : https://unifedpush.org/uses/distributors/ 互联网档案馆的存檔,存档日期2013-12-02
- JS的登记数字 :
import { registerForPushNotifications, listDistributors, setDistributor, setToken } from '@choochmeque/tauri-plugin-notifications-api'; const distributors = await listDistributors(); if (distributors.length === 0) { // prompt the user to install a distributor return; } await setDistributor(distributors[0]); const storedToken = localStorage.getItem('up-client-token') ?? crypto.randomUUID(); localStorage.setItem('up-client-token', storedToken); await setToken(storedToken); const endpoint = await registerForPushNotifications(); // POST `endpoint` to your backend so it can deliver pushes
应用程序运行时接受推力
自动处理收到的统一Push消息:
-
系统土司通过
notify-rust(如果启用了该特性——默认为). -
一样
onNotificationReceived处理本地通知的监听器source: "push"数字 :import { onNotificationReceived } from '@choochmeque/tauri-plugin-notifications-api'; const unlisten = await onNotificationReceived((n) => { if (n.source === 'push') { console.log('UnifiedPush message:', n.title, n.body, n.extra); } });
插件将消息字节作为 JSON 并提取 title, (中文(简体) ), body (或 message),以及 data (或 extra非JSON有效载荷降落在 body 作为平庸的字符串。 二进制有效载荷最终进入 extra 作为 <binary N bytes> 标记.
当应用程序关闭时接收推取( 可选)
UnitedPush通过D-Bus方法发送消息,调用该app的总线名. 如果一个推力到达时应用程序没有运行,则发行商依赖于D-Bus会话激活来启动.
为此,船只a .service 激活文件于 ~/.local/share/dbus-1/services/<app-identifier>.service数字 :
[D-BUS Service]
Name=com.example.MyApp
Exec=/usr/bin/my-app
替换 Name 您的 Tauri 应用程序的标识符( 包含 identifier 从字段 tauri.conf.json和 Exec 带有安装的二进制的绝对路径。 没有此文件, 推器只在应用程序已经运行时才会被发送 .
插件确实如此 没有 为你安装此文件——这是包装/部署的决定. Distros 和包装器通常从 .deb 编号 : .rpm 平板电脑.
关于冷启动交付的重要警告: 该插件的统一Push连接器( 拥有您的应用标识符的 D- Bus 服务) 是 懒散初始化 第一声呼叫 listDistributors(), (中文(简体) ), setDistributor(), (中文(简体) ), setToken(),或 registerForPushNotifications() 从JS层。 如果您的应用程序是由 D-Bus 启动, 纯粹为了处理一个推力, 发行商的方法调用可能会与懒惰的输入器相竞争, 并在连接器注册之前到达—— 然后调用无声失败 。 要让激活驱动的送货可靠, 触发热心在你的Rust setup() (例如电话) notifications.list_distributors() )或打电话 listDistributors() 从JS,早在你的应用启动。 在你发现之前,治疗 .service 启动为最佳效果.
测试
桌面
- 通知出现在系统通知中心
- 测试不同的通知类型和相互作用
- 核实通知的持久性和解雇情况
iOS系统
- 物理设备测试( 模拟器支持有限)
- 发送通知前请求权限
- 测试不同间隔的预定通知
- 核查行动处理和通知分组
机器人
- 创建和测试通知通道
- 测试不同的重要性级别和可见度设置
- 用设备睡眠验证预定的通知
- 测试当前针对背景任务的通知
- 验证通知样式( 收件箱、 大文本等)
解决问题
未提交的通知
- 获得验证权限
- 在Android上,确保通知通道存在
- 检查系统通知设置
- 验证通知 ID 是独一无二的
未发射的预定通知
- 检查设备电源设置( 电池优化)
- 安卓上,请使用
allowWhileIdle关键通知 - 校验计划时间在将来
无效的行动
- 确保行动类型在发出通知前得到登记
- 验证登记和处理之间的动作标识
- 检查特定平台的行动支持