Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Enable browser notifications on websites for monitoring and event-driven routine flows.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 105% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 278% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 70% | 0% |
| case-10 | ✗→✓ | ▲ Improved | -14% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 84% | 0% |
Enabling website notifications requires TWO steps — browser permission AND site-level opt-in. Both are mandatory; browser permission alone does nothing if the site hasn't been told to send notifications.
Before granting permission, check if this origin already has a notification grant:
js// Query the daemon to see if we already granted notification permission for this origin const origin = new URL(page.url()).origin; const existing = await trpcClient.inbox.getNotificationGrant.query({ origin }); if (existing) { // Already granted — skip to Step 2 (site-level opt-in) or Step 3 (source resolution) }
If a grant already exists, skip Step 1 entirely. The browser already has "Allow for AI" permission for this origin. Proceed to Step 2 if site-level opt-in has not been done, then Step 3 before waiting.
jsawait page.grantNotificationPermission();
Call this on the target site FIRST. This does two things:
After grantNotificationPermission() returns, wait for the page to settle before proceeding to Step 2.
This is the critical step. Most websites require you to opt in to desktop/browser/push notifications from their own settings page. The general strategy:
js// Take a snapshot to orient — look for settings/gear icons, profile menus await snapshot(page, { interactive: true }); // Common approaches: // 1. Direct URL if known (check browsing history or guess common patterns) // e.g. /settings/notifications, /preferences, /account/notifications // 2. Click settings icon (gear) → look for "Notifications" section // 3. Profile menu → Settings/Preferences → Notifications tab
js// Snapshot the settings page — look for notification-related controls await snapshot(page); // Search for keywords in the snapshot: // - "Desktop notifications", "Browser notifications", "Push notifications" // - "Email notifications" (NOT this — we want push/desktop only) // - Toggle switches, checkboxes, "Enable" / "Turn on" / "Allow" buttons // - "New mail notifications" (Gmail-like), "Notify me about..." (Slack-like)
js// Click the toggle/checkbox/button await page.locator('<ref>').click(); // Snapshot diff to confirm state changed const after = await snapshot(page); // Verify the toggle shows "on" state or a success message appeared
page.grantNotificationPermission(), reload, retry.Before creating an event routine, resolve the user's site/service reference to the exact page origin. Never pass the user's raw phrase directly as eventFilter.from.
Resolution priority:
trpcClient.inbox.listNotificationGrants.query().Use the technical origin URL internally, but speak to the user in site/domain terms. Good: "I'll wait for Gmail site notifications." or "I'll wait for notifications from mail.google.com." Avoid exposing implementation wording like "origin subscription" unless the user asks.
If the user wants any browser notification classified, omit eventFilter.from and inspect the received event after wake. For a specific named site/service, resolve the site first and use the origin URL.
After browser permission, site-level opt-in, and source resolution succeed, create an event routine with routine_update:
For a one-shot wait that continues this conversation when the notification arrives ("wake me when the Gmail reply comes"):
mode: "create"
kind: "heartbeat" ← wakes this session
triggerKind: "event"
scheduleKind: "once" ← auto-pauses after the first matching event
eventFilter: { source: "web-push-notification", from: "<origin URL>" }
timeoutMinutes: 60 ← optional; defaults to 60 for once waits
name/prompt: what to do when the event (or timeout) arrivesThen end the turn normally — the session stays idle and is woken with the event content when a matching notification arrives, or with a timeout notice if the deadline passes.
For a standing monitor that starts a new task per notification, use kind: "cron" with scheduleKind: "recurring" instead.
eventFilter.from must be the page origin URL (e.g. https://mail.google.com, https://app.slack.com), NOT an email address or username. This is because the browser delivers push notifications tagged with the sending origin.
Other measured skills in the registry, with their headline benchmark lift.