Freeswitch: mod_callcenter
mod_callcenter - модуль очередей входящих вызовов.
настройки
Settings
odbc-dsn
Callcenter поддерживает ODBC вместо используемой по умолчанию внутренней БД SQLite.
В таблицах хранятся динамические данные вызывающих абонентов (members), агентов (agents) и уровней (tiers).
Пример из таблицы members (вызывающий абонент в очереди)
queue | system | uuid | session_uuid | cid_number | cid_name | system_epoch | joined_epoch | rejoined_epoch | bridge_epoch | abandoned_epoch | base_score | skill_score | serving_agent | serving_system | state |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
testcc@default | single_box | 6f3cbada-ffd6-428d-aa61-ee783ddad25b | 414a9b82-c8fd-49f0-a97f-3d83d6f3671d | +79219981138 | D.Khlevnoy | 1556203331 | 1556203331 | 0 | 0 | 0 | 0 | 0 | ring-all | Trying |
Пример из таблицы agents (Агент вызывается)
name | system | uuid | type | contact | status | state | max_no_answer | wrap_up_time | reject_delay_time | busy_delay_time | no_answer_delay_time | last_bridge_start | last_bridge_end | last_offered_call | last_status_change | no_answer_count | calls_answered | talk_time | ready_time | external_calls_count |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
6666@default | single_box | callback | user/6666@132.123.123.123 | Available | Receiving | 3 | 10 | 3 | 60 | 0 | 1556203356 | 1556203356 | 1556203643 | 1556092161 | 0 | 41 | 178 | 0 |
Пример параметра для Postgres:
<param name="odbc-dsn" value="pgsql://hostaddr=127.0.0.1 dbname=DB user=USER password='PASS'"/>
Таблицы создаются автоматически при загрузке модуля mod_callcenter
dbname
Устанавливает путь и имя к внутренней БД SQLite. ( для лучшей производительности рекомендуется помещать на ram disk или использовать ODBC). Если не задано, то будет создано в директории по умолчанию.
Agent options
name
Имя агента, в первую очередь обеспечивает логическую связь с соответствующим tiers.
type
На данный момент поддерживаются 2 типа callback
и uuid-standby
.
callback
пытается вызвать агента на основании данных из поляcontact
uuid-standby
пытается соединиться с агентом напрямую используя его uuid.
contact
Строка для вызова агента, как в команде bridge: user/1000@default. Или, например, для verto: ${verto_contact(1000@default)}.
Перед строкой вызова в квадратных скобках можно задать переменные per-leg, например время вызова агента при серийной стратегии (round-robin): [leg_timeout=10]sofia/gateway/fs210/2668
status
Назначает статус агента. Смотри подробнее ниже>>
max-no-answer
Кол-во неотвеченных агентом вызовов, после которого ему будет автоматически присвоен статус On Break
.
wrap-up-time
Пауза после завершения вызова для того чтобы оператор мог закончить работу (внести данные по звонку в базу, например), прежде чем, он будет возвращен в обслуживание очереди.
reject-delay-time
Если агент отклоняет вызов, выждать назначенное время, прежде чем пытаться вызвать его снова.
busy-delay-time
Если агент недоступен (DND) выждать указанное время, прежде чем пытаться вызвать его снова.
no-answer-delay-time
Если агент не ответил на вызов, выждать указанное время, прежде чем пытаться вызвать его снова.
reserve-agents
Если задано true
, состояние (state) агента изменяется на Reserved
, после предыдущего состояния Receiving
вызовы снова будут поступать на него, только после того как состояние будет изменено.
Это используется, если вы манипулируете состоянием агента извне, через API mod_callcenter. По умолчанию false
.
truncate-agents-on-load
Если задано true
, при загрузке модуля все агенты удаляются из очереди. По умолчанию false
.
truncate-tiers-on-load
Если задано true
, при загрузке модуля все правила (tiers) удаляются. По умолчанию false
.
Queue options
strategy
Стратегия обзвона агентов в очереди смотрите подробнее ниже>>
moh-sound
Воспроизведение медиа вызывающему абоненту в ожидании ответа.
Вы можете использовать любой из типов воспроизведения поддерживаемый FreeSWITCH:
- прямое воспроизведение файла, например с бесконечной петлей.
- local srtream (local_stream://moh) или $${hold_music} заданное в //vars.xml//
- FreeSWITCH phrase system (phrase:my-special-phrase) (например, чтобы воспроизвести несколько сообщений друг за другом)
- tone stream т.е. КПВ, (tone_stream://${ru-ring};loops=-1)
record-template
Задает шаблон имени файла для записи вызова и путь к директории в локальной файловой системе например:
/var/spool/freeswitch/${strftime(%Y/%m/%d/%H-%M-%S)}_${destination_number}_${caller_id_number}_${uuid}.mp3
time-base-score
Может принимать значения queue
или system
(По умолчанию queue
).
Если установлено system
, ко времени проведенному вызывающим абонентом в очереди прибавляется время которое вызов мог провести в системе до попадания в очередь. Таким образом такой вызов может получить приоритет над другими вызовами уже находящимися в очереди. Если установлено queue
, то все вызовы имеют равные условия и для позиции в очереди учитывается только время проведенное в ней.
tier-rules-apply
Может быть true
или false
.
Указывает применять или нет перечисленные далее tier-rule…
для продвижения по уровням очереди.
Если установлено false
используются все уровни без ожидания.
tier-rule-wait-second
Время ожидания в секундах до перехода абонента на следующий уровень. Умножается на номер уровня, если tier-rule-wait-multiply-level
= true
. Если же tier-rule-wait-multiply-level
= false
, тогда по истечении заданного времени все уровни становятся открытыми для вызовов в порядке перечисления и дополнительные критерии ожидания не действуют.
tier-rule-wait-multiply-level
Может быть true
или false
.
Если false
то по истечении времени заданного в tier-rule-wait-second
вызывающему абоненту становятся доступны все уровни в заданном порядке (level/position).
Если значение true
, то абонент ожидает время заданное в tier-rule-wait-second
умноженное на номер уровня до перехода на следующий уровень.
tier-rule-no-agent-no-wait
Может быть true
или false
.
Если false
абонент может перескакивать уровни без доступных агентов. Иначе придется ждать по всем правилам. Агенты должны иметь статус Logged Out
, чтобы считаться недоступными.
discard-abandoned-after
Время в секундах (таймаут), по истечению которого вызывающий абонент будет удален из очереди (abandoned).
Но если abandoned-resume-allowed
= true
, то он будет возвращен в очередь на предыдущую позицию.
abandoned-resume-allowed
Может быть true
или false
.
true
позволяет вернуться в очередь на прежнюю позицию если он был удален из нее по истечению таймаута (discard-abandoned-after
)
In order to maintain their position in the queue, they must not abandoned it for longer than the number of seconds defined in 'discard-abandoned-after'.
max-wait-time
По умолчанию 0
, т.е. выключено
Любое значение в секундах, ограничивающее время пребывания в очереди (абсолютный таймаут). По идее должно быть больше чем discard-abandoned-after
иначе не будет учитываться.
max-wait-time-with-no-agent
По умолчанию 0
, т.е. выключено
Максимальное время пребывания в очереди без агентов. Призвано защитить абонентов от массового исключения из очереди, если все агенты по какой-то причине отвалились.
max-wait-time-with-no-agent-time-reached
По умолчанию 5
Любое значение в секундах. По достижению лимита max-wait-time-with-no-agent
отвергать новые вызовы в течении заданного времени. Затем в течении этого же времени будет дан шанс подключиться к очереди.
(но если агенты не появятся, будет ли задан новый лимит?)
ring-progressively-delay
По умолчанию 10
Значение в секундах, задает время до вызова следующего агента при стратегии ring-progressively
.
Tiers options
Tiers или уровни связывают агента с обслуживаемой очередью.
agent
Имя агента из параметра name
настроек агентов соответственно
queue
Очередь с которой связан агент. Если агент обслуживает несколько очередей, для каждой создается tiers
level
Уровень используемый для tier-rule…
position
Номер позиции используется при стратегиях обзвона очереди
Пример таблицы динамических данных из таблицы tiers:
Вызывается очередь со стратегией round-robin и агент 2668:
queue | agent | state | level | position ----------------+--------------+-----------+-------+---------- testcc@default | 6666@default | No Answer | 1 | 1 testcc@default | 2668@default | Offering | 1 | 2
Вызов перешел на агента 6666:
fscore=> select * from tiers; queue | agent | state | level | position ----------------+--------------+-----------+-------+---------- testcc@default | 2668@default | No Answer | 1 | 2 testcc@default | 6666@default | Offering | 1 | 1
./autoloads_configs/callcenter.conf.xml
<configuration name="callcenter.conf" description="CallCenter"> <settings> <!--<param name="odbc-dsn" value="dsn:user:pass"/>--> <!--<param name="dbname" value="/dev/shm/callcenter.db"/>--> </settings> <queues> <queue name="sales@default"> <param name="strategy" value="agent-with-least-talk-time"/> <param name="moh-sound" value="$${hold_music}"/> <!--<param name="record-template" value="$${base_dir}/recordings/sales/${strftime(%Y-%m-%d-%H-%M-%S)}.${destination_number}.${caller_id_number}.${uuid}.wav"/>--> <param name="time-base-score" value="queue"/> <param name="tier-rules-apply" value="false"/> <param name="tier-rule-wait-second" value="300"/> <param name="tier-rule-wait-multiply-level" value="true"/> <param name="tier-rule-no-agent-no-wait" value="false"/> <param name="discard-abandoned-after" value="14400"/> <param name="max-wait-time" value="0"/> <param name="max-wait-time-with-no-agent" value="120"/> </queue> <queue name="support@default"> <param name="strategy" value="longest-idle-agent"/> <param name="moh-sound" value="$${hold_music}"/> <!--<param name="record-template" value="$${base_dir}/recordings/support/${strftime(%Y-%m-%d-%H-%M-%S)}.${destination_number}.${caller_id_number}.${uuid}.wav"/>--> <param name="time-base-score" value="system"/> <param name="tier-rules-apply" value="false"/> <param name="tier-rule-wait-second" value="300"/> <param name="tier-rule-wait-multiply-level" value="true"/> <param name="tier-rule-no-agent-no-wait" value="false"/> <param name="discard-abandoned-after" value="60"/> <param name="abandoned-resume-allowed" value="false"/> <param name="max-wait-time" value="0"/> <param name="max-wait-time-with-no-agent" value="120"/> </queue> </queues> <!-- WARNING: Configuration of XML Agents will be updated into the DB upon restart. --> <!-- WARNING: Configuration of XML Tiers will reset the level and position if those were supplied. --> <!-- WARNING: Agents and Tiers XML config shouldn't be used in a multi FS shared DB setup. --> <agents> <agent name="1000@default" type="callback" contact="[leg_timeout=10]user/1000@default" status="Available" max-no-answer="3" wrap-up-time="10" reject-delay-time="10" busy-delay-time="60" /> <!-- If you would like to set the Caller ID name, for whatever reason notice below. --> <agent name="1001@default" type="callback" contact="[origination_caller_id_name='Queue Caller',leg_timeout=10]user/1001@default" status="Available" max-no-answer="3" wrap-up-time="10" reject-delay-time="10" busy-delay-time="60" /> </agents> <tiers> <!-- If no level or position is provided, they will default to 1. You should do this to keep db value on restart. --> <!-- agent 1000 will be in both the sales and support queues --> <tier agent="1000@default" queue="sales@default" level="1" position="1"/> <tier agent="1000@default" queue="support@default" level="1" position="1"/> <!-- agent 1001 will only be in the support queue --> <tier agent="1001@default" queue="support@default" level="1" position="1"/> </tiers> </configuration>
Queues Strategy
Стратегии обзвона
String | Description |
---|---|
ring-all | Все агенты вызываются одновременно. |
longest-idle-agent | Вызывается агент с наибольшим временем простоя с учетом уровня (tier level). |
round-robin | Агенты вызываются по кругу после агента принявшего последний вызов (round-robin memory). |
top-down | Агенты вызываются в порядке перечисления сверху вниз. |
agent-with-least-talk-time | Вызывается агент с наименьшим временем разговора. |
agent-with-fewest-calls | Вызывается агент принявший наименьшее кол-во звонков. |
sequentially-by-agent-order | Агенты вызываются по очереди в соответствии с уровнем (tier level) и порядком. |
random | Агенты вызываются в случайном порядке. |
ring-progressively | Похоже на top-down , но предыдущий агент продолжает вызываться, т.е. в конце концов будет ring-all . |
Agents Status & States
Агенты имеют Status (статус) и States (состояние).
- Status - ключевое состояние агента.
- Status - не изменяется системой автоматически, но может быть изменен вручную, если нужно.
- Status - может быть изменен во время разговора, это не повлияет на текущий вызов, а только на следующий.
- States - специфическое состояние агента, устанавливается автоматически системой, в зависимости от фазы участия агента в обслуживании вызова.
- Таким образом статистическое состояние агента (например в разговоре или вызывается) отделено от логического (принимает вызовы или нет).
Agent Status и States могут принимать следующие значения:
Agent Status:
String | Description |
---|---|
Logged Out | Не принимать вызовы из очереди. |
Available | Принимать вызовы. |
Available(On Demand) | После завершения вызова состояние будет установлено «Idle» (автоматически не устанавливается на «Waiting»).. * |
On Break | В очереди, но временно не принимает вызовы. |
* Изменение статуса применяется только к следующему звонку. Так, например, если вы измените пользователя с Available
на Available(On Demand)
, когда он находится в состоянии вызова или ожидания вызова, он получит еще один вызов и только затем перейдет в состояние Idle
.
Agent State:
String | Description |
---|---|
Idle | Ничего не делает, звонки не принимаются. |
Waiting | Готов принять вызов. |
Receiving | Очередь вызывает агента. |
In a queue call | В разговоре из очереди. |
Variables
cc_export_vars
Экспортировать переменные в b-leg(s) после вызова приложения callcenter.
Это необходимо потому-что mod_callcenter производит вызов агента отдельным потоком, т.е. екстеншн в котором задано
<action application="callcenter" data="9000@callcenter"/>
является a-leg, а вызов агента по отношению к вызову приложения callcenter является b-leg.
Пример использования:
<action application="set" data="hold_music=local_stream://example_moh"/> <action application="set" data="origination_caller_id_name=Call Center"/> <action application="set" data="origination_caller_id_number=9000"/> <action application="set" data="cc_export_vars=hold_music,origination_caller_id_name,origination_caller_id_number"/> <action application="callcenter" data="9000@callcenter"/>
Иначе (без использования cc_export_vars) придется делать так:
<action application="bridge_export" data="nolocal:verto_h_pr=${pr}"/> <action application="callcenter" data="foo"/>
Но иногда бывает, что заранее (в a-leg) нужной переменной еще нет, а она будет инициализированна только после вызова приложения callcenter. Например cc_queue_joined_epoch, тогда можно задать переменные в параметрах вызова агента в поле Contact:
[execute_on_answer=record_session::$${recordings_dir}/${strftime(%Y/%m/%d)}/call_project_${accountcode}/q_${cname}_${cnum}_${cc_queue_joined_epoch}]user/AGENT_ID@DOMAIN
В данном примере, мы получаем дополнительный бонус, активируя запись вызова, только после ответа агента очереди колл-центра.
Appendix: Lua DBH Handler & Database scheme mod_callcenter
[execute_on_answer=bind_meta_app 8 ab s log::ERR FOOTEST]