signal-call

n8n trigger node that fires on Signal call outcomes (missed/answered/declined/busy) via signal-cli-rest-api's WebSocket receive stream

Documentation

n8n-nodes-signal-call

An n8n community node that starts a workflow when a Signal
call ends
, with a derived outcome (missed / answered / declined /
busy). It reads call-signaling envelopes from the same
signal-cli-rest-api
WebSocket receive stream that the message trigger uses, but looks at
callMessage.hangupMessage instead of message content.

This is a companion to n8n-nodes-signal-cli-rest-api (message send / receive).
It does not send Signal messages itself.

Installation

In n8n: Settings → Community Nodes → Install, then enter:

n8n-nodes-signal-call

Or install manually into your n8n custom nodes directory:

npm install n8n-nodes-signal-call

Prerequisites

signal-cli-rest-api must run in json-rpc or json-rpc-native mode. The
WebSocket receive endpoint (/v1/receive/<number>) does not exist in normal
or native mode, and the node will not receive any events.

The registered Signal number must be able to receive calls (i.e. the account is
linked / registered on that signal-cli-rest-api instance).

Node: Signal Call Trigger

Parameter Description Default
signal-cli-rest-api Base URL Base URL of the signal-cli-rest-api instance. http:// is rewritten to ws:// internally. http://signal-cli-rest-api:8080
Registered Phone Number The phone number registered on that instance, E.164 format. —
Ignore Outgoing Calls Skip hangup events for calls placed by this number itself (envelope.sourceNumber equals the registered number). true
Reconnect Delay (Seconds) Wait time before reconnecting after the WebSocket drops. 5

Manual (test) execution

Click Execute step, then place a call to the bot number — let it ring out
(missed) or answer it on any linked device (answered). The node emits once the
call ends and stops listening.

Active (production) execution

While the workflow is active the node keeps a persistent WebSocket open and
emits one execution per completed call (hangup), reconnecting automatically if
the connection drops.

Output

{
  "outcome": "missed",
  "hangupType": "NORMAL",
  "callId": 123456789,
  "caller": {
    "number": "+380XXXXXXXXX",
    "uuid": "........-....-....-....-............",
    "name": "Jane Doe"
  },
  "timestamp": 1730000000000,
  "raw": { "envelope": { "...": "..." } }
}

Outcome mapping

The signal-cli hangup type (MessageEnvelope.Call.Hangup.Type in
AsamK/signal-cli) is mapped to a
plain-English outcome:

hangupType outcome Meaning
NORMAL missed Call rang out, was not answered
ACCEPTED answered Answered on any linked device
DECLINED declined Explicitly declined
BUSY busy Line busy
NEED_PERMISSION need_permission Caller not permitted to call this number
(anything else) unknown Unrecognised hangup type — inspect raw

NORMAL → missed and ACCEPTED → answered were confirmed empirically
against a live signal-cli-rest-api instance.

Development

npm install      # .npmrc sets ignore-scripts=true so the n8n-workflow type
                 # dependency does not try to compile isolated-vm
npm run build    # tsc -> dist/, then copies the icon
npm pack --dry-run

Compatibility

  • n8n >= 1.x (n8n Nodes API v1)
  • Node.js >= 20.15
  • Tested against signal-cli-rest-api 0.x in json-rpc mode

License

MIT

Discussion