TriggersonCallUnholdstable

On unhold

Fires when an agent takes the caller off hold. Use it to log the hold to a CRM or kick off any side-task that should run when a held caller is brought bac…

What it does

Fires when an agent takes the caller off hold from their softphone. There is no unholdCall flow node anymore — like the hold itself, resuming is something an agent does mid-call. The moment it happens, the caller's own active flow's onCallUnhold chain runs.

Unlike onCallHold, this chain's verbs are not played into the live conference — there's no wire-level "unhold" audio event to hang them off of, so say / playAudio output from this chain is informational only (the caller doesn't hear it). What matters is the chain running at all: its side-effects (a screenPop refresh, an agentNotify, a setVar, an analytics webhook) fire the instant the resume happens.

When to use it

  • Send a Slack ping to #ops when a long-held customer is finally picked back up
  • Compute hold duration by reading a vars.heldAt stamped from onCallHold and posting now - vars.heldAt to your dashboard
  • Refresh a screen pop or CRM note the moment the agent comes back
  • Increment a counter tracking how many holds happen per customer per day

If you need the caller to actually hear something the moment they're picked back up ("Thanks for waiting"), wire that into the main flow itself (a say after wherever the bridge resumes) — this trigger's own audio output is discarded.

Configuration

_label and _note are author-only metadata; this trigger has no runtime configuration of its own.

Fires when an agent takes the caller off hold. Use it to log the hold to a CRM or kick off any side-task that should run when a held caller is brought back.

FieldLabelTypeRequiredDefaultNotes
_labelTrigger labeltextOptional—
_noteInternal notetextareaOptional—

Outgoing events: triggered

Examples

Slack ping when a customer comes off hold

{
  "id": "unhold-trigger",
  "type": "onCallUnhold",
  "config": { "_label": "Notify ops on resume" },
  "on": { "triggered": "slack-ping" }
}
[onCallUnhold] ──► [apiCall POST hooks.slack.com/...
                     body: { text: "Caller {{event.from}} resumed" }] ──► [end]

Compute and log hold duration

Pairs with a setVar in the onCallHold chain that stamps vars.heldAt.

{
  "id": "unhold-trigger",
  "type": "onCallUnhold",
  "config": {},
  "on": { "triggered": "log-duration" }
}
{
  "id": "log-duration",
  "type": "apiCall",
  "config": {
    "mode": "http",
    "url": "https://analytics.example.com/hold-duration",
    "method": "POST",
    "body": "{ \"heldAt\": \"{{vars.heldAt}}\" }"
  },
  "on": { "next": "end" }
}

Gotchas

  • Fires from the softphone, not from a flow node. There is no unholdCall node anymore — an agent takes the caller off hold from their softphone UI, and that's what triggers this chain.
  • The chain's audio output is discarded. say / playAudio verbs from this chain don't reach the live call — there's no unhold wire event to play them into. Use this trigger for side-effects only; put an audible "thanks for waiting" in the main flow if you need one.
  • Side-chain runs in an isolated state branch. It shares the call's vars but can't move the main flow's cursor.
  • Caller-initiated hangup during hold won't fire this. If the caller hangs up while on hold, the hold simply ends with the call — no agent resumed it, so this trigger never runs.
  • Implemented by GET|POST /hooks/conf-unhold in rust/bins/heyquad-walker/src/webhooks.rs, called by heyquad-api the moment an agent resumes a held caller.

See also