Click2Call Module
Click2Call places outbound calls from the CRM: a manager opens a customer card, presses
the call button, and the module dials both sides through a telephony provider. It keeps
the call history, the resulting statuses, and the call recordings.
The module never becomes a voice path itself. It asks a provider to connect the manager
and the customer, then tracks what happened to that call — by polling the provider or by
receiving provider webhooks.
What it covers
- Providers — 19 telephony integrations, each as an adapter with its own credentials
schema and capability set.
- Routing — the provider is chosen by the destination of the number, with fallback to
backup profiles when the primary one refuses the call.
- Number validation — the number is parsed against the national numbering plan, so an
impossible number is rejected before it costs a call.
- Calling windows — calls are allowed only inside the local time window of the
customer's country, which is a regulatory requirement in many jurisdictions.
- DNC blacklist — numbers that must never be dialled, checked before the provider is
contacted.
- Recordings — the recording link is fetched from the provider on demand and cached.
- Statuses — one canonical status set for every provider.
Methods
Every method is available through both transports. Names in the table are the TCP command
names; the REST column is the HTTP entry point of the same method.
Calls
Providers and profiles
Agents and dial rules
Blacklist (DNC)
Calling windows
Webhooks
Service
| Method |
REST |
Description |
| Click2CallPing |
GET click2call/ping |
Cheap liveness probe with a problem list |
| Click2CallHealth |
GET click2call/health |
Full module state: database, adapters, crons, call backlog |
Entities
| Entity |
Scope |
Purpose |
providers |
global |
Telephony integration catalogue; name is the adapter name, options describes credential fields for the UI |
providerProfiles |
brand |
Credentials and behaviour of one integration: mode, callsUpdateBy, allowed destinations, routingPriority |
agents |
brand |
Manager-to-line link, used by INDIVIDUAL profiles |
dialRules |
brand |
Dial prefix/postfix per destination, attached to a profile |
calls |
brand |
Calls and their state, provider call id, recording link |
webhooks |
brand |
Public callback URLs and their secrets |
webhookEvents |
via webhooks |
Raw provider payloads and deduplication |
phoneBlacklist |
brand |
DNC numbers |
callWindows |
brand |
Allowed calling hours per country |
Everything is scoped by brand. Desks are not part of the model: a phone number and a
provider profile belong to a brand, not to a department.
Call statuses
| Status |
Meaning |
INITIATED |
Provider accepted the request, nothing else is known yet |
RINGING |
One of the sides is ringing |
ANSWERED |
Conversation started |
BUSY |
Line was busy |
NO_ANSWER |
Nobody picked up |
REJECTED |
Call was declined |
FAILED |
Provider could not place the call |
UNRESOLVED |
Provider never reported a final status and the call was closed by timeout |
ANSWERED is not a final status by itself — a call stays open until the provider reports
the hang-up or the stale-call sweep closes it. closedBy says who finished the call:
CRM, PROVIDER, or TIMEOUT.
Statuses are normalised by the module, not by the provider: every adapter maps its own
vocabulary into this set, so the CRM sees the same values regardless of the integration.
Call lifecycle
sequenceDiagram
participant CRM
participant Module as Click2Call
participant Provider
CRM->>Module: Click2CallStartCall
Module->>Module: number, DNC, calling window, routing
Module->>Provider: dial manager and customer
Provider-->>Module: provider call id
Module-->>CRM: callId, externalId, INITIATED
loop until final status
Provider-->>Module: webhook, or module polls the provider
Module->>Module: status change, journal, events
end
Module-->>CRM: click2call.call.ended
Status delivery is chosen per profile in callsUpdateBy:
| Mode |
How statuses arrive |
WEBHOOK |
Provider calls click2call/handleWebhooks/:uuid |
REQUEST |
Module polls the provider every few seconds while the call is open |
NONE |
No status tracking; the call is closed by timeout |
Events
The module publishes events on the bus, so CRM, analytics, and workflow rules react
without polling.
| Event |
When |
click2call.call.initiated |
Call record created |
click2call.call.started |
Status became ANSWERED |
click2call.call.ended |
Call reached a final status |
click2call.callEnd |
Notification for the manager UI |
Order of checks in Click2CallStartCall
The order is deliberate: every check that can reject the call for free runs before the
provider is contacted.
- Number — parsed and validated against the numbering plan of its country.
- Blacklist — a DNC number must not cost a call or a cent.
- Calling window — local time of the customer, not of the manager.
- Routing — profiles allowed for that destination, ordered by
routingPriority.
- Dial rule — applied only to an explicitly selected profile.
- Duplicate protection — the same manager cannot double-click into two real calls.
- Providers — candidates are tried in order until one accepts the call.