Files
openhuman/docs/NOTIFICATION_TESTING_STATUS.md
T
2026-04-26 10:28:36 -07:00

8.2 KiB

Native OS Notification — Testing Status

Companion to TAURI_CEF_FINDINGS_AND_CHANGES.md.
This file is a quick-reference checklist: what is done, what is still needed, and how to test.


What Is Done

tauri-cef (vendored submodule)

Change File
NotifyRenderProcessHandler wired into TauriApp::render_process_handler vendor/tauri-cef/crates/tauri-runtime-cef/src/cef_impl.rs
run_cef_helper_process() uses NotifyApp (not None) vendor/tauri-cef/crates/tauri-runtime-cef/src/lib.rs
notification::unregister(browser_id) called on browser close vendor/tauri-cef/crates/tauri-runtime-cef/src/cef_impl.rs
Dispatch logs added ([cef-notify] dispatch / dropped) vendor/tauri-cef/crates/tauri-runtime-cef/src/notification.rs
on_context_created install logs in runtime shim vendor/tauri-cef/crates/tauri-runtime-cef/src/notification.rs
on_context_created install logs in helper shim vendor/tauri-cef/cef-helper/src/notification.rs
Debug markers: window.__OPENHUMAN_CEF_NOTIFICATION_SHIM, __OPENHUMAN_CEF_NOTIFICATION_ORIGIN vendor/tauri-cef/cef-helper/src/notification.rs
Manual test entry point: window.__openhumanFireNotification(title, opts) vendor/tauri-cef/cef-helper/src/notification.rs
ensure-tauri-cli.sh reinstalls vendored CLI when tauri-cef sources are newer scripts/ensure-tauri-cli.sh

tauri-plugin-notification (vendored to stop init-script conflict)

Change File
Plugin vendored at vendor/tauri-plugin-notification/ app/src-tauri/Cargo.toml
Plugin dependency switched from git rev to local path app/src-tauri/Cargo.toml
.js_init_script(...) call removed from plugin init() vendor/tauri-plugin-notification/src/lib.rs

Why this mattered: Without this change, the plugin injected a JS shim that forwarded new Notification(...) to http://ipc.localhost/plugin:notification|notify. That IPC always fails with 500 in third-party webviews (Slack), overwriting the CEF shim and blocking all notification delivery.

openhuman-cursor app shell

Change File
Default notification toggle set to true src/notification_settings/mod.rs
OPENHUMAN_DISABLE_SLACK_SCANNER=1 env bypass for DevTools inspection src/webview_accounts/mod.rs
Platform-specific OS notification with click detection added src/webview_accounts/mod.rs
macOS: mac-notification-sys + wait_for_click + std::thread::spawn src/webview_accounts/mod.rs
Linux: notify-rust + wait_for_action + std::thread::spawn src/webview_accounts/mod.rs
Windows: fire-and-forget fallback via NotificationExt src/webview_accounts/mod.rs
notification:click Tauri event emitted with { account_id, provider } src/webview_accounts/mod.rs
[notify-click] success logs promoted from debug to info src/webview_accounts/mod.rs
mac-notification-sys = "0.6" added to macOS dependencies app/src-tauri/Cargo.toml
notify-rust added to Linux dependencies app/src-tauri/Cargo.toml
NotificationExt import scoped to #[cfg(all(feature = "cef", windows))] src/webview_accounts/mod.rs
tokio::task::spawn_blocking replaced with std::thread::spawn (fixes tokio panic from CEF callback thread) src/webview_accounts/mod.rs
Scanner fallback: per-channel unread baseline, delta-based notification synthesis src/slack_scanner/mod.rs

What Is Still Needed

1. Slack scanner registry re-enabled

File: app/src-tauri/src/lib.rs

This fix has already been applied in this PR. ScannerRegistry is now registered in the Tauri app state, so the scanner-driven fallback notification path is active.

The following was added to lib.rs inside tauri::Builder::default()...manage(...):

// already applied
.manage(Arc::new(slack_scanner::ScannerRegistry::new()))

With this change:

  • The scanner tracks per-channel unread counts
  • When a channel's unread count increases, the scanner synthesizes a native OS notification
  • This is the fallback path because Slack's embedded session does not call new Notification(...) for real incoming messages

2. Verify end-to-end with a real incoming Slack message

Once the scanner registry is registered:

  1. Run the app: cd app && pnpm dev:app
  2. Open the Slack webview — wait for Slack to load fully
  3. Have someone send you a Slack message from another device
  4. Watch the log:
    tail -f /tmp/openhuman-dev-app.log | grep --line-buffered "notify-cef\|notify-click\|scanner\|unread"
    
  5. Expected log sequence:
    [scanner] unread delta channel=... prev=N new=M
    [notify-cef][<account_id>] source=... tag=... title_chars=N body_chars=M
    
  6. OS toast should appear
  7. Click the toast → expected:
    [notify-click][<account_id>] clicked provider=slack
    
  8. Slack webview should come into focus (frontend routes notification:clicksetActiveAccountactivate_main_window)

3. Verify the CEF shim installs in Slack's page context

Before relying on real messages, confirm the helper shim is active via DevTools:

  1. Open brave://inspect
  2. Find the Slack page target → click Inspect
  3. In Console, run:
    window.__OPENHUMAN_CEF_NOTIFICATION_SHIM   // should be true
    window.__OPENHUMAN_CEF_NOTIFICATION_ORIGIN  // should be the Slack URL
    
  4. If both are present, the CEF helper shim installed correctly

4. Verify the manual helper trigger path end-to-end

With DevTools open on the Slack target:

window.__openhumanFireNotification("Slack CEF test", { body: "Manual trigger" })

Expected log:

[cef-notify] dispatch browser_id=N source=Window title="Slack CEF test" origin=...
[notify-cef][<account_id>] source=Window tag= silent=false title_chars=14 body_chars=13

And an OS notification toast should appear. If no toast appears, the blocker is in forward_native_notification in webview_accounts/mod.rs.

5. Clean up debug instrumentation (post-verification)

Once notifications are working reliably, remove:

  • window.__OPENHUMAN_CEF_NOTIFICATION_SHIM global marker
  • window.__OPENHUMAN_CEF_NOTIFICATION_ORIGIN global marker
  • window.__openhumanFireNotification manual trigger
  • window.__OPENHUMAN_CEF_NOTIFICATION_CONSTRUCTOR saved reference
  • [cef-helper-notify] eprintln! calls in cef-helper/src/notification.rs (or replace with proper log::debug!)

How To Run The App Correctly

The app must be started with dev:app, not tauri dev directly:

cd app && pnpm dev:app

dev:app sets CEF_PATH=$HOME/Library/Caches/tauri-cef and ensures the vendored cargo-tauri is installed. Without it, the app panics at startup in cef::library_loader with No such file or directory.

Live log location:

tail -f /tmp/openhuman-dev-app.log | grep --line-buffered "notify-cef\|notify-click\|scanner\|unread\|cef-notify"

Key Log Prefixes

Prefix Where Meaning
[cef-helper-notify] on_context_created renderer subprocess shim callback fired for a new JS context
[cef-helper-notify] installed shims renderer subprocess shim installed in that context
[cef-helper-notify] execute renderer subprocess new Notification(...) called by page JS
[cef-notify] dispatch browser process notification IPC received from renderer, handler called
[cef-notify] dropped browser process notification IPC received but no handler registered
[notify-cef][id] webview_accounts notification payload reached app, OS toast being sent
[notify-click][id] clicked webview_accounts user clicked OS toast, emitting notification:click
[webview-accounts] slack ScannerRegistry not in app state webview_accounts scanner registry is missing — add .manage(ScannerRegistry::new()) in lib.rs

Frontend Side (Already Wired, No Changes Needed)

app/src/services/webviewAccountService.ts already listens for notification:click:

listen('notification:click', ({ payload }) => {
  dispatch(setActiveAccount(payload.account_id));
  invoke('activate_main_window');
});

No frontend changes are needed. The click routing will work once the Rust side emits the event.