Dialer docsProgressive engine
Home Progressive Predictive Callback Disposition API Socket Dashboard

Progressive engine

One free agent. One next lead. No overdial.

This guide is only the calling brain. Lead ingest lives in the API reference. Overdial and customer-first originate are in the Predictive guide.

Panel active Presence ready AMI idle priority 1–3 wait on time

End-to-end flow

The engine does not poll on a global timer. Every AMI patch, panel join/leave, or ready/pause updates that extension and may schedule a claim.

Progressive dialer end-to-end flow

When an agent dials

FlagSourceMust be
panelAgent page connectedactive
presenceReady / pause on the panel (dialer_employee.panel_status)ready
amiAsterisk device stateidle

Also required: no call already in flight, employee loaded from this module’s dialer_employee roster, and at least one skill in dialer_employee.skills (JSON list matched to lead form_type). Ready/pause writes dialer_employee.panel_status. AMI and the dashboard only track roster extensions. After a call, the engine waits buffer_time seconds, then claims again. If no lead matches, it retries every 10 seconds.

Claim order

Two agents cannot take the same row. Claim uses FOR UPDATE SKIP LOCKED, then sets Calling, reserves the lead, increments call_count, and sets first_attempt_at on the first originate.

1
Pinned agent
If agent_id is set, only that employee claims and originates it. Skill match is skipped.
2
Priority number
Lowest priority_no first (Callback Request is 1).
3
Dial status
Pending, then Callback, then Abandoned, then Not Connected.
4
Age
Never attempted first, then oldest attempt, then oldest push, then lowest id.

Unassigned leads (agent_id null or 0) must match form_type to the agent’s skills. Any master row with agent_id is originated only on that agent’s extension. Received, Rejected, Calling, and reserved rows are skipped. Claim also waits on next_retry_at and refuses originate outside work_start–work_end except for a due callback.

Callback Request

priority_id 1, 2, or 3 honor callback_scheduled_at. A callback time requires agent_id. Full behaviour (time gate, pin, retry) is in the Callback Request guide. How you send the fields is in the API reference.

1
Lead is waiting
Future callback_scheduled_at → skip. Other priorities keep dialing.
2
Time is due
Only that agent_id claims it. It is first in their queue.
3
No time sent
Priority 1–3 without a datetime is Pending. If agent_id is set, only that agent dials it; otherwise any matching skill.

Hangup results

HangupStored status
ANSWERReceived (keeps agent_id)
Cancel by customer, invalid destinationRejected
No answer, busy, congestion, chanunavailNot Connected

Received, Rejected, and Disposed are not claimed again. Not Connected and Abandoned use a 2-2-1 scheduler: retry_pattern (default [2,2,1]) caps tries per working day from first_attempt_at; retry_seconds is the same-day gap; a slot after work_end (default 18:30 IST) snaps to the next working day’s work_start. Final Disposal only when call_count reaches max_tries. Received keeps agent_id. Pinned callbacks keep agent_id on every outcome and use the same retry policy.

Engine config

SettingWhereMeaning
dialer_typefic_dialer_configProgressive or Predictive
buffer_timefic_dialer_configSeconds between calls per agent
max_triesfic_dialer_configHard cap on originates (keep in sync with sum of retry_pattern)
retry_secondsfic_dialer_configSame-day gap after Not Connected or Abandoned
retry_patternfic_dialer_configPer working-day caps, default [2,2,1]
work_start / work_endfic_dialer_configOriginate window, default 09:30–18:30 IST
work_daysfic_dialer_configISO weekdays, default Mon–Sat [1,2,3,4,5,6]
disposed_priority_idfic_dialer_configFinal Disposal — never claimed
CALL_API_URL.envOriginate URL (call.php)
DIAL_ORIGINATE_TIMEOUT_MS.envWait for AMI on_call (default 60s)