Перейти к основному содержимому

Asterisk (SFTP)

Интеграция подключается к вашей АТС по SFTP, читает журнал звонков Master.csv (модуль cdr_csv) и забирает записи разговоров из каталога записей. Никаких модулей на АТС устанавливать не нужно — достаточно включить CSV-журнал, передать путь записи в CDR и выдать доступ только на чтение.

Что попадает в Лия Sense:

  • только звонки с записью — строки CDR без файла записи пропускаются;
  • метаданные звонка из CDR: номера, направление, результат, длительность, очередь, оператор (см. Метаданные);
  • аудио — по запросу из вашего каталога записей в момент обработки.
Используете FreePBX?

Для FreePBX есть отдельная интеграция, которая получает CDR через API FreePBX. Эта страница — для «чистого» Asterisk.

Что подготовить на стороне АТС

1. Включите CSV-журнал звонков

В /etc/asterisk/cdr.conf добавьте или проверьте секцию [csv]:

[csv]
loguniqueid=yes
loguserfield=yes
newcdrcolumns=yes
; usegmtime=yes ; только если хотите писать даты в UTC
  • loguniqueid=yesобязательно: без колонки uniqueid интеграция не сможет устойчиво идентифицировать звонок и отклонит подключение.
  • loguserfield=yes — добавляет колонку userfield, в которую передаётся путь к записи (следующий шаг).
  • newcdrcolumns=yes — добавляет peeraccount, linkedid, sequence; linkedid нужен, чтобы связать плечи одного звонка (переводы, очереди).

После правки перезагрузите модуль: asterisk -rx "module reload cdr_csv.so" и убедитесь, что в новых строках Master.csv появилась колонка uniqueid: с рекомендованными настройками строка содержит 21 колонку, без newcdrcolumns — 18. Раскладки с uniqueid, но без userfield (17 или 20 колонок) тоже принимаются — запись тогда ищется по uniqueid; раскладки без uniqueid отклоняются.

2. Передайте путь записи в CDR

В том же месте диалплана, где запускается запись через MixMonitor, добавьте одну строку:

same => n,Set(CDR(userfield)=${MIXMONITOR_FILENAME})

В userfield должен попасть фактический путь к файлу записи. Если поле пустое, интеграция попробует найти файл по uniqueid в каталоге за день звонка, но это медленнее и менее надёжно — передавайте путь явно.

3. Создайте пользователя SFTP только на чтение

Пользователь должен читать:

  • каталог CDR — по умолчанию /var/log/asterisk/cdr-csv/ (сам Master.csv и его ротации);
  • каталог записей — по умолчанию /var/spool/asterisk/monitor/ со всеми подкаталогами.

Shell для этого пользователя можно отключить: интеграции нужен только SFTP. Аутентификация — по паролю или по SSH-ключу. Порт SFTP должен быть доступен с адресов Лия Sense (уточните их у поддержки).

4. Определитесь с часовым поясом

cdr_csv пишет даты без указания зоны. Интеграции нужно знать, как их читать:

  • если в [csv] не задан usegmtime=yes (по умолчанию) — даты локальные; укажите в форме часовой пояс АТС в формате IANA, например Europe/Moscow;
  • если задан usegmtime=yes — отметьте в форме «CSV пишется в UTC»; часовой пояс тогда не влияет на разбор дат из CSV. Но если userfield может оказаться пустым, всё равно укажите часовой пояс, по которому организованы каталоги записей: он нужен, чтобы выбрать каталог суток при поиске записи по uniqueid (при пустом поле берётся UTC).

Неправильное сочетание сдвинет время звонков на несколько часов: часть звонков попадёт не в тот день или будет пропущена.

5. Не сжимайте свежие ротации Master.csv

Читаются Master.csv и его несжатые ротации (Master.csv.1, Master.csv-20260911 и т. п.). Файлы .gz не читаются. Настройте logrotate так, чтобы ротации хранились несжатыми хотя бы двое суток — периодическая задача забирает звонки за последние 24 часа ночью.

Поля формы подключения

Для подключения нужны хост, пользователь SFTP и способ аутентификации; если CSV пишется не в UTC — ещё и часовой пояс АТС. Остальные поля имеют значения по умолчанию.

ПолеОбязательноеОписание
Хост АТСДаDNS-имя или IP-адрес АТС (сервера SFTP)
Порт SFTPНетПо умолчанию 22
Пользователь SFTP (только чтение)ДаУчётная запись из шага 3
Пароль SFTPОдно из двухПароль пользователя — либо приватный ключ
Приватный ключ SFTPОдно из двухПолное содержимое приватного ключа, включая строки BEGIN и END
Отпечаток/ключ хостаНетОтпечаток SHA-256/MD5/SHA-1 или публичный ключ хоста. Пусто — ключ хоста не проверяется, подключение принимается с любым ключом сервера; укажите значение, чтобы включить строгую проверку
Путь к Master.csvНетПо умолчанию /var/log/asterisk/cdr-csv/Master.csv
Состав колонок CSVНетauto (по умолчанию) — определяется автоматически; можно указать uniqueid, uniqueid_userfield или full
CSV пишется в UTCНет1, если в cdr.conf задано usegmtime=yes; иначе 0 или пусто
Часовой пояс АТСЕсли CSV не в UTCIANA-зона, например Europe/Moscow
Максимальная длительность звонка, чНетПо умолчанию 4. Влияет на границы периода при разовых задачах
Каталог записейНетКорень дерева записей на SFTP, по умолчанию /var/spool/asterisk/monitor. Пути из userfield приводятся относительно него; если путь выходит за пределы каталога, запись считается недоступной и звонок пропускается
Шаблон пути к записиНетПо умолчанию {Y}/{m}/{d}/{basename}, см. пояснение под таблицей. Используется, когда userfield пуст
Контексты входящихНетКонтексты диалплана (dcontext) входящих звонков через запятую. По умолчанию from-pstn,from-trunk,from-did-direct
Контексты исходящихНетПо умолчанию from-internal
Шаблон внутреннего номераНетРегулярное выражение, которому целиком соответствует внутренний номер, например ^\d{3,4}$. Нужен, чтобы звонки между сотрудниками получали направление internal
Каналов в записи (1 или 2)НетПо умолчанию 1 (моно). 2 — только если MixMonitor пишет стерео

Шаблон пути к записи задаёт путь внутри Каталога записей: {Y} — год из четырёх цифр, {m} — месяц, {d} — день (две цифры, по дате звонка в часовом поясе АТС), {basename} — имя файла с расширением. Когда userfield заполнен, путь берётся из него, и шаблон не нужен. Когда userfield пуст, по шаблону без {basename} определяется каталог суток (для шаблона по умолчанию — /var/spool/asterisk/monitor/2026/09/11/), и в нём ищется файл, в имени которого есть uniqueid звонка.

При нажатии Подключить система подключается по SFTP, читает первую полную строку Master.csv, определяет состав колонок и проверяет каталог записей. Ошибка подключения означает, что источник не создан — проверьте доступ и настройки CSV.

Требования к записям

  • Запись через MixMonitor. Записи Monitor() в виде двух файлов «по плечам» не поддерживаются (само приложение удалено в Asterisk 21).
  • Форматы файлов: .wav, .wav49, .mp3, .ogg. Файлы .gsm, .ulaw, .sln пропускаются — настройте MixMonitor на поддерживаемый формат.
  • Файл должен лежать под каталогом записей и оставаться на месте до обработки: интеграция не копирует записи, а забирает их по SFTP в момент, когда Лия Sense обрабатывает звонок. Не удаляйте записи как минимум несколько дней после звонка.
  • Размер одной записи — до 64 МиБ (67 108 864 байт).
  • Стерео (Каналов в записи = 2) улучшает разделение спикеров: канал 0 — оператор, канал 1 — клиент.

Направление звонка

Направление определяется по контексту диалплана (dcontext) и шаблону внутреннего номера:

УсловиеНаправление
dcontext в списке контекстов входящихinbound
dcontext в списке контекстов исходящих, а dst не внутренний номерoutbound
И src, и dst — внутренние номераinternal
Только src внутреннийoutbound
Только dst внутреннийinbound
Иначеunknown

Без шаблона внутреннего номера направление internal не определяется. Для звонков вне указанных контекстов направление выводится по шаблону внутреннего номера; если и он не помогает — unknown. Если у вас нестандартные контексты, перечислите их в форме.

Метаданные

Каждый звонок получает метаданные из CDR, по которым можно фильтровать разговоры и строить аналитику:

ПолеОписание
cdr.directionНаправление: inbound, outbound, internal, unknown
cdr.src, cdr.dstНомер источника и назначения
cdr.didDID. У Asterisk (SFTP) остаётся пустым: поддерживаемые раскладки cdr_csv не содержат колонки DID; заполняется только в интеграции FreePBX
cdr.recording_pathПуть к файлу записи относительно каталога записей
cdr.dispositionРезультат по Asterisk: ANSWERED, NO ANSWER, BUSY, FAILED, CONGESTION
cdr.duration, cdr.billsecПолная длительность и длительность разговора, с
cdr.operatorВнутренний номер оператора (по направлению и каналам)
cdr.queueИмя очереди, если звонок прошёл через Queue()
cdr.dcontext, cdr.accountcodeКонтекст и accountcode из CDR
cdr.uniqueid, cdr.linkedid, cdr.sequenceИдентификаторы CDR; linkedid связывает плечи одного звонка
conversation_group_idСовпадает с linkedid: по нему группируются плечи одного звонка

Статус разговора в Лия Sense выводится из disposition: ANSWERED → завершён, NO ANSWER/BUSY → пропущен, FAILED/CONGESTION → ошибка; любое другое значение считается завершённым звонком.

Фильтры задачи сбора

В задаче сбора для Asterisk доступны фильтры:

  • Результат звонка — один или несколько disposition; например, только ANSWERED, чтобы не тратить транскрибацию на пропущенные;
  • Минимальная длительность разговора, с — по billsec.

Ограничения

  • Один CDR — не всегда один разговор: переводы, очереди и Local-каналы создают несколько плеч с общим linkedid. В Лия Sense попадают только плечи, у которых есть поддерживаемая запись.
  • .wav49 Asterisk может сохранять как .WAV с кодеком GSM внутри; такой файл может не воспроизводиться. Предпочтительны .wav (PCM) или .mp3.
  • Даты в CSV без часового пояса: ошибка в настройке «CSV пишется в UTC» / «Часовой пояс АТС» не обнаруживается автоматически — проверьте время первых загруженных звонков.
  • Сжатые ротации Master.csv*.gz не читаются.

Проверка после подключения

  1. Создайте разовую задачу за один прошедший день, в котором точно были звонки с записью, и запустите её.
  2. Дождитесь статуса «завершено» и откройте любой загруженный разговор: проверьте время звонка (часовой пояс), номера в метаданных и воспроизведение записи.
  3. Если записи не воспроизводятся — проверьте, что тот же SFTP-пользователь может открыть файл по пути из userfield, и что путь лежит под каталогом записей.
  4. Создайте периодическую задачу и привяжите пайплайн.