From b194d77d575b203fe252da6f0472882a13fea30b Mon Sep 17 00:00:00 2001 From: esdrasrenan Date: Sun, 7 Dec 2025 03:13:41 -0300 Subject: [PATCH] Add Windows native notifications for chat sessions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add tauri-plugin-notification for native Windows notifications - Send notification when new chat session is started - Configure notification permissions in capabilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- apps/desktop/src-tauri/Cargo.lock | 69 ++++++++++++++++++- apps/desktop/src-tauri/Cargo.toml | 1 + .../src-tauri/capabilities/default.json | 6 +- apps/desktop/src-tauri/src/chat.rs | 22 ++++++ apps/desktop/src-tauri/src/lib.rs | 1 + 5 files changed, 97 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src-tauri/Cargo.lock b/apps/desktop/src-tauri/Cargo.lock index 0757b46..74248f9 100644 --- a/apps/desktop/src-tauri/Cargo.lock +++ b/apps/desktop/src-tauri/Cargo.lock @@ -73,6 +73,7 @@ dependencies = [ "sysinfo", "tauri", "tauri-build", + "tauri-plugin-notification", "tauri-plugin-opener", "tauri-plugin-process", "tauri-plugin-store", @@ -2101,6 +2102,18 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +[[package]] +name = "mac-notification-sys" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fd3f75411f4725061682ed91f131946e912859d0044d39c4ec0aac818d7621" +dependencies = [ + "cc", + "objc2 0.6.3", + "objc2-foundation 0.3.2", + "time", +] + [[package]] name = "markup5ever" version = "0.14.1" @@ -2256,6 +2269,20 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +[[package]] +name = "notify-rust" +version = "4.11.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6442248665a5aa2514e794af3b39661a8e73033b1cc5e59899e1276117ee4400" +dependencies = [ + "futures-lite", + "log", + "mac-notification-sys", + "serde", + "tauri-winrt-notification", + "zbus", +] + [[package]] name = "ntapi" version = "0.4.1" @@ -2872,7 +2899,7 @@ checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" dependencies = [ "base64 0.22.1", "indexmap 2.11.4", - "quick-xml", + "quick-xml 0.38.3", "serde", "time", ] @@ -3002,6 +3029,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quick-xml" +version = "0.37.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +dependencies = [ + "memchr", +] + [[package]] name = "quick-xml" version = "0.38.3" @@ -4130,6 +4166,25 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tauri-plugin-notification" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01fc2c5ff41105bd1f7242d8201fdf3efd70749b82fa013a17f2126357d194cc" +dependencies = [ + "log", + "notify-rust", + "rand 0.9.2", + "serde", + "serde_json", + "serde_repr", + "tauri", + "tauri-plugin", + "thiserror 2.0.17", + "time", + "url", +] + [[package]] name = "tauri-plugin-opener" version = "2.5.0" @@ -4310,6 +4365,18 @@ dependencies = [ "toml 0.9.8", ] +[[package]] +name = "tauri-winrt-notification" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9" +dependencies = [ + "quick-xml 0.37.5", + "thiserror 2.0.17", + "windows 0.61.3", + "windows-version", +] + [[package]] name = "tempfile" version = "3.23.0" diff --git a/apps/desktop/src-tauri/Cargo.toml b/apps/desktop/src-tauri/Cargo.toml index b7466f2..27dd251 100644 --- a/apps/desktop/src-tauri/Cargo.toml +++ b/apps/desktop/src-tauri/Cargo.toml @@ -23,6 +23,7 @@ tauri-plugin-opener = "2.5.0" tauri-plugin-store = "2.4.0" tauri-plugin-updater = "2.9.0" tauri-plugin-process = "2.3.0" +tauri-plugin-notification = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" sysinfo = { version = "0.31", default-features = false, features = ["multithread", "network", "system", "disk"] } diff --git a/apps/desktop/src-tauri/capabilities/default.json b/apps/desktop/src-tauri/capabilities/default.json index 9fe95d8..d76705a 100644 --- a/apps/desktop/src-tauri/capabilities/default.json +++ b/apps/desktop/src-tauri/capabilities/default.json @@ -13,6 +13,10 @@ "store:allow-save", "store:allow-delete", "updater:default", - "process:default" + "process:default", + "notification:default", + "notification:allow-notify", + "notification:allow-request-permission", + "notification:allow-is-permission-granted" ] } diff --git a/apps/desktop/src-tauri/src/chat.rs b/apps/desktop/src-tauri/src/chat.rs index e06efdc..63f8282 100644 --- a/apps/desktop/src-tauri/src/chat.rs +++ b/apps/desktop/src-tauri/src/chat.rs @@ -12,6 +12,7 @@ use std::sync::Arc; use std::time::Duration; use tauri::async_runtime::JoinHandle; use tauri::{Emitter, Manager, WebviewWindowBuilder, WebviewUrl}; +use tauri_plugin_notification::NotificationExt; use tokio::sync::Notify; // ============================================================================ @@ -340,6 +341,27 @@ impl ChatRuntime { }, ); + // Enviar notificacao nativa do Windows + let notification_title = format!( + "Chat iniciado - Chamado #{}", + session.ticket_ref + ); + let notification_body = format!( + "{} iniciou um chat de suporte", + session.agent_name + ); + if let Err(e) = app + .notification() + .builder() + .title(¬ification_title) + .body(¬ification_body) + .show() + { + crate::log_warn!( + "Falha ao enviar notificacao: {e}" + ); + } + // Abrir janela de chat automaticamente if let Err(e) = open_chat_window_internal( &app, diff --git a/apps/desktop/src-tauri/src/lib.rs b/apps/desktop/src-tauri/src/lib.rs index 75b8be2..ba122fc 100644 --- a/apps/desktop/src-tauri/src/lib.rs +++ b/apps/desktop/src-tauri/src/lib.rs @@ -298,6 +298,7 @@ pub fn run() { .plugin(StorePluginBuilder::default().build()) .plugin(tauri_plugin_updater::Builder::new().build()) .plugin(tauri_plugin_process::init()) + .plugin(tauri_plugin_notification::init()) .on_window_event(|window, event| { if let WindowEvent::CloseRequested { api, .. } = event { api.prevent_close();