screenPopScreen pop
Pushes content to the answering agent's softphone — either a URL (CRM page, ticket, knowledge base) or inline custom HTML you author here. Choose how it r…
type: screenPop status: stable sinceVersion: 0.1.0 seeAlso: [agentNotify] keywords: ["screenPop", "screen", "pop", "url", "html", "custom pop", "agent experience"]
What it does
Pushes content to the answering agent's softphone — pick a pop type: a
URL (CRM customer page, open ticket, knowledge-base article) or Custom
HTML (an inline card you author right here). This single node covers both
modes; the former standalone "Custom pop" node has been folded in. Templates
resolve server-side against vars, contact, and event, so what you ship
can be specific to this caller (https://crm.acme.com/customers/{{contact.id}},
or <h3>{{contact.displayName}}</h3>) without any client-side glue.
The pop is published over the per-user realtime channel that the softphone
subscribes to, so it only reaches the specific agent who answered the
bridge — not every agent in the org. That's why this node only works inside
an onAgentAnswered chain: outside that scope the worker has no agent
identity to address. Pops are buffered per-call on the softphone and GC'd
about thirty seconds after the call ends, so a pop that fires near
hangup still gets a chance to display before its owning call closes.
When to use it
- Open a CRM customer record the moment an agent answers a known caller
- Drop a ticket or work-order URL into the agent's drawer for inbound service calls
- Surface a knowledge-base article when the caller landed in a specialty queue (warranty, billing, technical)
- Open a payment or e-sign page in a new tab when the flow has gathered enough context to start a transaction
- Pair with
contactLookupso the URL deep-links by contact id only when the caller is recognized
Configuration
Pushes content to the answering agent's softphone — either a URL (CRM page, ticket, knowledge base) or inline custom HTML you author here. Choose how it renders: embedded inline, side drawer, or a new browser tab. Only works inside an "On agent answered" chain.
| Field | Label | Type | Required | Default | Notes |
|---|---|---|---|---|---|
source | Pop type | select | Optional | url | Options: url, html. |
url | URL | text | Required | https://crm.acme.com/customers/{{contact.id}} | Supports {{contact.}}, {{vars.}}, {{event.from}} templates. Must be HTTPS. |
mode | How to display | select | Optional | drawer | Options: drawer, iframe, newTab. |
requireClick | Require agent click to open | boolean | Optional | false | Force a click-to-open notification instead of auto-opening. |
html | HTML body | json | Required | {} | Full HTML document or fragment. Supports {{contact.}}, {{vars.}}, {{event.*}} templates expanded server-side before delivery. |
htmlMode | How to display | select | Optional | embedded | Options: embedded, drawer. |
width | Width (px) | number | Optional | 0 | |
height | Height (px) | number | Optional | 320 |
Outgoing events: __next
Examples
Drawer pop with a contact id
A standard pop that opens the matched contact's CRM page in the softphone's drawer the instant the agent picks up.
{
"id": "pop-crm",
"type": "screenPop",
"config": {
"url": "https://crm.acme.com/customers/{{contact.id}}",
"mode": "drawer",
"requireClick": false
},
"on": { "__next": "agent-whisper" }
}
Iframe with a click-to-open guard
Use mode: iframe plus requireClick: true when the URL is heavy or
shouldn't load until the agent is ready. The agent sees a click target
on the softphone and the page only fetches when they ask for it.
{
"id": "pop-ticket",
"type": "screenPop",
"config": {
"url": "https://help.acme.com/tickets/{{vars.ticketId}}",
"mode": "iframe",
"requireClick": true,
"width": 480,
"height": 640
},
"on": { "__next": "end" }
}
Gotchas
- Only fires inside an
onAgentAnsweredchain. The worker readsstate.triggerAgent.userIdto route the pop to a specific user channel. If you drop this node before any bridge picks up — or anywhere outside an agent-answered chain — the worker logs a warning and skips it. The flow still advances down the next edge. - HTTPS only. URLs that aren't
https://...are dropped at the worker with a warning. The softphone iframe modes also enforce mixed-content rules, so plainhttp://would fail to render even if the worker passed it through. iframemode is sandboxed without same-origin. The softphone usessandbox="allow-scripts allow-forms"— explicitly noallow-same-origin. Any in-page script that reads cookies, talks to its own backend on its own session, or assumes window.parent access will break. For full-fidelity pages, usemode: newTabinstead.- Templates are resolved when the node fires, not when it loads. If
vars.ticketIdchanges after the pop is sent (because a later script rewrites it) the URL the agent sees is the old one. The pop is a one-shot event, not a live binding. - One pop per call view, mostly. The softphone dedups identical pops
inside a ~2 second window per
callId. Firing the same node twice in quick succession (e.g. inside a tight loop) yields a single visible pop. - The agent must be online. The pop is published to Redis and forwarded via the user channel — if the agent's softphone has lost its websocket the event will not be replayed when they reconnect.
