Overview
In-house outbound and inbound dialer on Asterisk.
CRM pushes leads into sales_dialer_master_data. Agents join a Socket.IO panel. One process claims rows, originates through AMI, and settles hangups. Mode is Progressive or Predictive from sales_dialer_config. Inbound PSTN is always on.
Skill-only claim
No master agent pin
AMI originate
Unlimited hold
How the pieces fit
HTTP APICRM upserts leads and schedules callbacks. Does not originate.
Socket hubAgent ready/pause (picker reason required), dashboard snapshot, dialer phases, inbound ringing, redial.
EnginesProgressive: one call per idle agent. Predictive: customer first, then skill bridge.
AMI + inboundDevice state, originate, bridge, MOH. PSTN park and skill offer.
Roster is sales_dialer_employee for module_id = sales-dialer. Skills JSON must include the lead form_type. AMI only tracks those extensions. Config reloads every 30 seconds; switching dialer_type waits until the floor is idle.
Engine
Progressive Agent-first AMI originate. One live outbound per desk. Guide →Engine
Predictive Customer-first Local originate, ratio pacing, unlimited hold, decline cooldown. Guide →PSTN
Inbound Park on hold music, look up by phone, offer a skilled idle agent. Blocks outbound on that desk. Guide →Lead type
Callback Time gate on callback priorities. Any matching skill may take it when due. CRM pending callbacks and dispositions. Guide →Shared
Settle & retry Hangup map,retry_pattern for NC, Abandoned retry_seconds, wrap, pauses, maintenance, redial, missed activities, priorities.
Guide →
Reference
HTTP API Auth, lead push, callback request, pending callbacks / dispositions, missed activities, pause reasons, health. Guide →Life of a lead
- CRM
POST /api/leadsupserts byoli_idand mints a newdata_id(returned on the 201). Status is Pending, or Callback if a callback priority has a time. - An idle ready agent with matching skill claims the row:
Calling, reserved.call_countdoes not increment here. - Progressive originates the agent channel. Predictive originates the customer Local channel, then bridges a skilled agent on answer.
- Hangup settles master + a row on
sales_dialer_call_attempts(agent,call_type, and the masterdata_idat settle). - Not Connected retries on
sales_dialer_config.retry_pattern(currently[4,4,3,2,1,1,1,1,1,1,1]) untilmax_tries(currently 20). Abandoned is not on that cycle — it keeps a futurenext_retry_at, otherwise waitsretry_seconds(currently 3600). Received / Rejected / Disposed stop unless socketredial, a new CRM push, or a CRM pending callback. - After a bridged outgoing / redial call the agent has
MISSED_ACTIVITY_GRACE_MINUTES(default 10) to store a callback or disposition from the CRM. Otherwise their outbound is paused (inbound still rings) until they do. See Missed activities.
Master has no agent_id column. Sending it on the API is a 400. Connected agent is on sales_dialer_call_attempts only.
Dial status
| Status | Meaning | Claimed again? |
|---|---|---|
| Pending | In the pool | Yes, skill + priority allowlist |
| Callback | Waiting on callback_scheduled_at | When due, skill + priority allowlist |
| Calling | Reserved, originate in flight | No |
| Received | Talked | No (unless redial) |
| Not Connected | No answer / busy / congestion | After retry_pattern / retry_seconds |
| Abandoned | Customer left while waiting (predictive / inbound) | After retry_seconds (or existing next_retry_at) |
| Rejected | Cancel / invalid / reject cause | No (unless redial) |
| Disposed | NC cap, or CRM final disposition | No unless redial, a new CRM push, or a CRM pending callback |
Tables this process owns
| Table | Role |
|---|---|
sales_dialer_employee | Roster, skills, priority_ids, panel pause/active |
sales_dialer_config | Mode, wrap, ratio, retry, hours, isMaintainance |
sales_dialer_priority | Queue order, callback flags |
sales_dialer_master_data | Leads. No agent pin |
sales_dialer_call_attempts | Every settle, with agent, hold seconds, master data_id snapshot, previous_dial_status (master at claim), and call_type (outgoing / incoming / redial) |
sales_dialer_agent_declines | SIP deny on a live hold (same call_type values) |
sales_dialer_agent_pauses | Panel pause intervals |
sales_dialer_api_call_log | Hangup webhook posts |
sales_dialer_after_hours_calls | After-hours DID misses (announce path only) |
sales_dialer_pending_callbacks | CRM callbacks / final dispositions held until the live call settles |
sales_dialer_missed_activities | Bridged outgoing / redial calls awaiting a CRM callback or disposition (outbound block) |
What this dialer does not do
- Pin a lead to one employee on master.
- Cap hold time (
hold_timeout_secondsis unused leftover). - Apply a drop-rate brake (
max_abandon_rateis unused). - Originate through
call.php. - Count Abandoned toward
max_tries. - Hang a live call when maintenance turns on (only new originates / redials / inbound offers stop).