1C+Asterisk. Пример интеграции

Опубликовал oleg.rizvanov в раздел Оборудование - Телефония, SIP

Пример интеграции 1С:Предприятие 7.7 и Asterisk PBX. Прослушивание событий, совершение исходящих звонков, отправка команд в Asterisk.

1СКакая самая распространенная система IP-телефонии? Правильно - Asterisk. Какая самая распространенная учетная система? Правильно - . А если их подружить, тогда - профит. Smile

Возможно, статья написана излишне подробно - не обессудьте. Хотелось, чтобы было понятно всем, да и множество важных деталей упустить не хотелось.

Условия.

Начнем "дружить" 1С и Asterisk. Возьмем самый тяжелый случай со стороны 1С - версию 7.7 (версия 8.х в уме), а со стороны Asterisk версию 1.6.2.x.

Чего мы хотим:

  1. Функцию исходящего звонка из 1С.
  2. Знать в 1С-е номер звонящего при входящем звонке.

Как будем строить.

У Asterisk-а есть свой API, через который мы и будем подключаться к нему. Называется он AMI - Asterisk Management Interface. Со стороны 1С будем использовать механизм внешних компонент.

Выбор внешней компоненты.

Google в помощь, ищем готовые внешние компоненты. Находим: Asterisk.dll, находим Obeliks, находим VVSAst.dll, находим ROM-Asterisk.dll.

Смотрим, анализируем... Возможно, в будущем захочется развить нашу систему, поэтому смотрим еще и на масштабируемость, наличие универсальных методов отправки команд в Asterisk, на поддержку версии 8.х

Asterisk.dll только для 1С версии 8.х, к тому же у этой ВК нет универсального метода отправки команд в AMI, она может только позвонить и все. Не подходит. :(

Obeliks - ограничения функциональности в шареварной версии. Каждый час перезагрузка, разговор 3 минуты. Снятие ограничений только в платной версии. Не подходит. :(

VVSAst.dll - для версии 7.7 ограничений нет, версия для 8.х платная. Есть универсальные методы отправки команд в AMI. Подходит, но лишь частично.

ROM-Asterisk.dll- полностью свободная и для 7.7 и для 8.х. Есть универсальные методы отправки команд в AMI. Есть мощные средства фильтрации. Полностью подходит.

Подключение внешней компоненты.

Компонента ROM-Asterisk саморегистрирующаяся, загружается через ЗагрузитьВнешнююКомпоненту()

Функция _АстерискЗагрузитьВК() Экспорт;
    Попытка
        ЗагрузитьВнешнююКомпоненту(КаталогИБ()+
"ROM-Asterisk.dll");
       
_Телефония = СоздатьОбъект("AddIn.ROM-Asterisk");
        Возврат
1;
    Исключение
        Сообщить(
"Не удалось загрузить внешнюю компоненту для связи с Asterisk");
    КонецПопытки;
    Возврат
0;
КонецФункции

Дальше, нам нужна еще одна предопределенная процедура - ОбработкаВнешнегоСобытия()

Процедура ОбработкаВнешнегоСобытия(Источник,Событие,Данные)
    Если
Источник="ROM-Asterisk" Тогда
        Сообщить(
Данные);
    КонецЕсли;
КонецПроцедуры

Теперь, нам нужно будет выполнить настройку со стороны Asterisk-а, а уже затем будем продолжать разбираться с 1С.

Настройка доступа со стороны Asterisk

Теперь, выполняем настройку со стороны Asterisk. Для простоты, IP адрес нашего Asterisk-a статический 192.168.1.100, подключения будут выполняться из той же подсети 192.168.1.0/24

Настройка доступа к AMI

Заходим на консоль или же подключаемся через SSH к Asterisk-у. Нас интересует файл /etc/asterisk/manager.conf

[general]
enabled=yes                ; возможность работать с AMI (по-умолчанию no)
port=5038                  ; на порту TCP 5038
bindaddr=192.168.1.0       ; принимать соединения в лок. сети (0.0.0.0 - все)
timestampevents = no       ; Отправлять в пакетах событий временную метку
displayconnects = yes      ; Отображать факт подключения пользователя к AMI
allowmultiplelogin = yes   ; Разрешить несколько подключений с одним именем

Настройка пользователя

Перейдем к секции, которая отвечает за пользователя:

[admin]                            ; имя пользователя
secret=password1234                ; пароль пользователя AMI
deny=0.0.0.0/0.0.0.0               ; запретить все ip-адреса
permit=192.168.1.0/255.255.255.0   ; разрешить соединение с подсети
read=system, call, command, agent  ; список классов событий
write=system, call,command, agent  ; список классов команд"

Проверка

Проверяем. Заходим на порт 5038, используя PuTTY. Если все хорошо, то увидим приветствие Asterisk. Вводим команду:

Action: login
Username: admin
Secret: password1234

В конце дважды нажимаем Enter. Asterisk на это должен ответить:

Response: Success
Message: Authentication accepted

Значит, все замечательно - получилось :)

Окончательная настройка 1С

Выполним окончательную настройку 1С. Переходим к 1С-у, к глобальному модулю. Напишем пару сервисных функций и будем уже слушать наш Asterisk. Для начала, сделаем переменную _Телефония глобальной и экспортной. Мы уже инициализировали эту переменную в функции _АстерискЗагрузитьВК()

Перем _Телефония Экспорт;

Напишем функцию для организации подключения к AMI

Функция _АстерискСоединиться(IP,Port=5038)Экспорт
    Если
_Телефония.Connect(IP,Port)=0 Тогда
        Сообщить(
"Не удалось соединиться с сервером Asterisk");
        Возврат
0;
    КонецЕсли;
    Возврат
_Телефония.Connected;
КонецФункции

Нужна универсальная функция, которая позволяет выполнять произвольную команду в AMI.

Функция _АстерискВыполнитьКоманду(ТекстКоманды) Экспорт;
    Если
_Телефония.Connected=0 Тогда
        Сообщить(
"Соединение не установлено");
        Возврат
0;
    КонецЕсли;

   
ТекстКоманды=ТекстКоманды;
    Если
_Телефония.ВыполнитьКоманду(ТекстКоманды)=0 Тогда
        Сообщить(
"Asterisk. Ошибка выполнения команды:");
        Сообщить(
ТекстКоманды);
        Возврат
0;
    КонецЕсли;
КонецФункции

Теперь, нужна функция авторизации. Выше, мы авторизовались из командной строки, теперь сделаем тоже самое из 1С.

Функция _АстерискАвторизоваться(Юзер,Хеш)Экспорт
   
CRLF=РазделительСтрок;
   
СтрокаКоманды= "Action: Login"+CRLF+
   
"Username: "+Юзер+CRLF+
   
"Secret: "+Хеш+CRLF+CRLF;
    Возврат
_АстерискВыполнитьКоманду(СтрокаКоманды);
КонецФункции

Напишем функцию прослушивания событий AMI

Процедура _АстерискСлушать(Режим=1) Экспорт;
    Если
_Телефония.Connected=0 Тогда
        Сообщить(
"Соединение не установлено");
        Возврат;
    КонецЕсли;
    Если
_Телефония.РежимПрослушивания(Режим)=0 Тогда
        Сообщить(
"Не удалось установить режим прослушивания");
    КонецЕсли;
КонецПроцедуры

Осталось только вызвать все эти процедуры и функции. Сделаем это ПриНачалеРаботыСистемы(), добавим в эту процедуру строки:

Процедура ПриНачалеРаботыСистемы()
    Если
_АстерискЗагрузитьВК()=1 Тогда
        Если
_Телефония.Connected=0 Тогда
            Если
_АстерискСоединиться("192.168.1.100",5038)=0 Тогда
                Сообщить(
"Не удалось соединиться с сервером Астериск");
                Возврат;
            КонецЕсли;
           
_АстерискСлушать();

           
АмиПользователь="admin";
           
АмиХешПароля="password1234";
            Если
_АстерискАвторизоваться(АмиПользователь,АмиХешПароля)=0 Тогда
                Сообщить(
"Не удалось авторизоваться на сервере Астериск");
                Возврат;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Загружаем 1С в режиме "Предприятие". Если все сделано правильно, то в строке сообщений появится куча всяких интересных событий AMI. Как минимум, мы должны увидеть событие своей успешной авторизации. Если это случилось - поздравляю, вы слышите Asterisk Laughing

А что дальше?

Слышать Asterisk - это прекрасно, но этого мало. С помощью написанного выше, мы можем, не только слушать события, но и выполнять любые команды, доступные в Asterisk AMI. Все необходимые для этого функции 1С у нас уже есть. Например, для совершения исходящего звонка, можно воспользоваться командой Originate.

ТекстКоманды="Action: Originate"+CRLF+
"Channel: SIP/"+СокрЛП(Источник)+CRLF+
"Context: from-internal"+CRLF+
"Exten: "+СокрЛП(Приемник)+CRLF+
"Priority: 1"+CRLF+
"Callerid: "+СокрЛП(Источник)+CRLF+
"Timeout: 30000"+CRLF+
"Async: true"+CRLF;

Пример, вы можете посмотреть в обработке Originate, которая есть в составе конфигурации.

Полный список команд Asterisk AMI можно посмотреть на сайте Asterisk.org, либо в русскоязычной версии справки.

Готовый пример для версии 8.х и подробное описание внешней компоненты: ROM-Asterisk: свободная полнофункциональная внешняя компонента для интеграции 1С и Asterisk

Успехов вам в дальнейшей разработке!

Файлы

Наименование Файл Версия Размер Кол. Скачив.
Конфигурация для 7.7 v2
.zip 132,49Kb
08.05.12
78
.zip 132,49Kb 78 Скачать
Конфигурация для 7.7
.rar 77,52Kb
08.05.12
53
.rar 77,52Kb 53 Скачать

См. также

Лучшие комментарии

34. Land1966 12.06.2013 15:39
(33) Спасибо. Все получилось, использовали компоненту версии 2.0.2.2, обновил на 2.0.2.3. Теперь разрыв соединения перехватывается обработкой внешнего события и сообщение об ошибке не выводится.
+ 1 [ oleg.rizvanov; ]
# Ответить
13. oleg.rizvanov 22.01.2012 15:56
(12) jorikfon,
Балованные у вас разработчики :)
+ 1 [ fzt; ]
# Ответить

Комментарии

1. evn-zorin 26.10.2011 11:01
Здорово! Плюсуем!
# Ответить
2. shamant 27.10.2011 02:00
Познавательно, спасибо
# Ответить
3. ms200999 27.10.2011 09:50
Отличная публикация. Плюс.
# Ответить
4. Medvedik 27.10.2011 12:43
Мне не нужно (скачивать не буду), но познавательно и написано хорошо, подробно (поэтому +)
# Ответить
5. mcarchi 27.10.2011 18:56
Однозначно +
# Ответить
6. ba2000 28.10.2011 10:46
Здорово. Сами ломали голову, но постоянно что-то глючило.
Попробуем Вашу.
Ответили: (7)
# Ответить
7. oleg.rizvanov 28.10.2011 11:42
(6) ba2000,
Решение на базе описанного в продакшне трудится уже давненько. Пока проблем не было.
# Ответить
8. opiumdx 31.10.2011 07:23
Спасибо, познавательно!
Ответили: (9)
# Ответить
9. oleg.rizvanov 31.10.2011 14:48
(8) opiumdx,
Главное, чтобы пригодилось для конкретного применения :)
# Ответить
10. jorikfon 22.01.2012 01:46
Мы разработали компонент для 8.2, который работает в тонком, толстом и web клиенте. Компонент написан по технологии Native API. Вот Демо ролик
Загрузка плеера
Ответили: (11)
# Ответить
11. oleg.rizvanov 22.01.2012 14:33
(10) jorikfon,
NativeAPI - это прекрасно.
Правда, на платформу 7.7 не станет - это раз.
Денег прилично стоит - это два.
Защита на HASP-е добавит юзерам головняка - это три.
# Ответить
12. jorikfon 22.01.2012 15:36
На 7.7 пока не претендуем, нет уже желания и возможности с ней работать, у меня все разработчики боятся ее как огня.
По деньгам, да. Но там цена для конечников, для разработчиков скидка 55%.
HASP сейчас уже не тот что был встроен в 1С. Есть программные лицензии, нет необходимости разносить ключи по разным машинами, менеджер лицензий не нужен для раздачи, я был приятно удивлен когда узнал новые возможности защиты. Ну а в общем вы наверное понимаете чем коммерческий продукт отличается от бесплатного. Мы будем разбираться и помогать в решении проблем, будем писать нормальную документацию, будем расширять и поддерживать функуционал и развивать компоненту вместе с новыми выпусками Asterisk и 1C.
Ответили: (13)
# Ответить
13. oleg.rizvanov 22.01.2012 15:56
(12) jorikfon,
Балованные у вас разработчики :)
+ 1 [ fzt; ]
# Ответить
14. 1C82 10.02.2012 04:31
Спасибо за подробное описание! Лучше чем документацию курить.Не знал с какой стороны подойти до этого. Только все-таки не понятно : как в 1с отловить номер входящего звонка?
Ответили: (15) (16)
# Ответить
15. jorikfon 10.02.2012 10:49
(14) 1C82, У нас это делается при помощи процедуры ВнешнееСобытие(Источник, Событие, Данные)
Более подробно в документации http://wiki.miko.ru/doc:1cajam:listening
Ответили: (17)
# Ответить
16. oleg.rizvanov 10.02.2012 14:00
(14) 1C82,
Отлавливать в ОбработкаВнешнегоСобытия

Если делаете интеграцию для 8-ки, то не проще ли взять какую-то готовую разработку? Например, у Simplit-а или у Miko
Если делаете для 7.7, то Miko вам не подойдет - NativeAPI под 7.7 не работает.

Сделал многим клиентам интеграцию на базе разработки Simplit - успешно. С Мико не работал, пока не было задачи под веб-клиент. Вроде бы хорошие ребята.
Ответили: (17)
# Ответить
17. 1C82 11.02.2012 03:27
(15)(16)Спасибо за ответы. Я и сам уже сделал вывод что проще взять готовую разработку, но ведь все-равно под клиента всегда приходится допиливать.
# Ответить
18. alyuev (файл скачал) 26.03.2012 13:33
Вопрос такого плана. Если делать исходящий звонок и у меня на рабочем месте стоит SIP телефон - как сделать так, чтобы нажав кнопку в 1С я мог говорить по этому телефону?

Почему спрашиваю, потому что работал с обычной миниАТС Panasonic с использованием сервера Rander - и там такой вызов работал. Т.е. нажимаю кнопку в 1С - на мой аппарат идет звонок, я поднимаю трубку и слышу гудок соединения, т.е. номер набран и мне осталось дождаться поднятия трубки на той строне.
Ответили: (19) (20)
# Ответить
19. jorikfon 26.03.2012 15:24
(18) alyuev,
Все зависит от телефона, например про Linksys SPA я писал в своем блоге..

В своей панели телефонии для Asterisk мы как раз реализовали автоподъем используя установку указанного в блоге параметра.
# Ответить
20. oleg.rizvanov 26.03.2012 15:48
(18) alyuev,
Это на телефоне настраивается. В нормальных телефонах, обычно есть функция автоподнятия
Ответили: (21)
# Ответить
21. jorikfon 26.03.2012 18:40
(20) oleg.rizvanov,
На телефоне то оно настраивается, но иногда этим процессом хочется управлять программно. Мы умеем для Linksys и Cisco телефонов.
# Ответить
22. R150380 30.10.2012 21:35
Подскажите как отключить в 1с 7.7 сообщение ROM-Asterisk : Сервер закрыл соединение
Ответили: (23) (30)
# Ответить
23. oleg.rizvanov 30.10.2012 21:56
(22) R150380,
Это сообщение попадет в процедуру ОбработкаВнешнегоСобытия - там его и ловите
# Ответить
24. R150380 31.10.2012 12:08
пишу вот так :

Если Источник="ROM-Asterisk" Тогда

СтрБуфер=Данные;

Если СокрЛП(Данные)="Disconnect" Тогда
Возврат;
КонецЕсли;

Но сообщение в окне сообщений все равно выходит. Как его убрать ?
Ответили: (25)
# Ответить
25. oleg.rizvanov 31.10.2012 20:38
(24) R150380,
Вас же интересует строка данных "Сервер закрыл соединение", зачем тогда в условии вы проверяете на "Disconnect"?

Если СокрЛП(Данные)="Сервер закрыл соединение" Тогда
Возврат;
КонецЕсли;

ОбработкаВнешнегоСобытия еще имеет параметр "Событие" послушайте его тоже.
# Ответить
26. seperblunt 18.12.2012 15:24
Однако, универсальный вызов методов астерикса выглядит интересней.
# Ответить
27. R150380 31.12.2012 17:22
Всех поздравляю С Новым годом !!! Особая благодарность: oleg.rizvanov. В новом году желаю Удачи, Успехов в работе и всех всех благ.
Ответили: (28)
# Ответить
28. oleg.rizvanov 31.12.2012 20:28
(27) R150380,
Спасибо большое, приятно :)
Желаю всем успехов в новом году!!!
# Ответить
29. LexSeIch 08.05.2013 04:59
Мир этому дому!
Прекрасная статья. Автору спасибо. Успехов.
# Ответить
30. Land1966 27.05.2013 16:39
(22) Удалось убрать сообщение? Если да, поделитесь, опытом, плиз. В процедуре ОбработкаВнешнегоСобытия() ничего сделать не могу. Похоже, она вызывается уже после выдачи сообщения.
Ответили: (31)
# Ответить
31. oleg.rizvanov 28.05.2013 11:42
(30) Land1966,
В процедуре ВнешнееСобытие закомментируйте строки Сообщить()
Ответили: (32)
# Ответить
32. Land1966 30.05.2013 18:08
(31) За публикацию и компоненту огромное спасибо. Встроили в свою учетную систему на 7.7, пользуемся более полугода. Все отлично. Но после перевода "1С" на удаленный сервер сообщение "Сервер Астериск закрыл соединение" стало появляться довольно часто. Встроил в обработчик ожидания автоматическое переподключение. Но само сообщение, конечно, раздражает пользователей. В ОбработкеВнешнегоСобытия() процедура Сообщить() выдает "Disconnect". А сообщение о закрытии соединения, похоже, генерируется самой ВК, как ошибка еще до возникновения внешнего события. Пока ничего придумать не смогли.
Ответили: (33)
# Ответить
33. oleg.rizvanov 30.05.2013 23:28
(32) Land1966,
Разрыв соединения - это объективная реальность. Например, провайдер перестроил маршрут, или превышен таймаут, или потерялись пакеты. Издержки удаленной работы. Лечится переподключением.

Согласен, пользователю не особо нужно знать о разрывах соединения. Насколько я помню, то в первых версиях компоненты, при разрыве соединения сообщение выдавалось в строку сообщений. В актуальной версии, все уходит в обработчик внешнего события. А уже программисту виднее как именно нужно обработать эти события.

Просто, обновите версию ВК - на сайте в разделе загрузки. Возьмите ВК из примера для 8-ки, т.к. пример для 7.7 обновляется реже
Ответили: (34)
# Ответить
34. Land1966 12.06.2013 15:39
(33) Спасибо. Все получилось, использовали компоненту версии 2.0.2.2, обновил на 2.0.2.3. Теперь разрыв соединения перехватывается обработкой внешнего события и сообщение об ошибке не выводится.
+ 1 [ oleg.rizvanov; ]
# Ответить
35. poshik 26.03.2014 09:56
Помогите пожалуйста страница с ROM-Asterisk.dll не доступна если есть у кого пришлите пожалуйст

Прикрепленные файлы:

w512h4291337871194512.png
# Ответить
36. AndrewUtkaev 23.06.2014 06:44
Добрый день. Скажите, через компоненту можно загрузить историю звонков из Астериска или нужно напрямую подключаться к MySQL базе?
Ответили: (37)
# Ответить
37. oleg.rizvanov 23.06.2014 12:38
(36) AndrewUtkaev,
Можно, но намного проще спросить напрямую через MySQL
# Ответить
38. AndreyNit 11.07.2014 09:06
Автору спасибо за отличную публикацию!!! В голове сразу всё на место встало. Однозначно плюс!
Ответили: (39)
# Ответить
39. oleg.rizvanov 11.07.2014 13:29
(38) AndreyNit,
Это достаточно старая статья.
Пример для 8.х лучше брать из этой статьи
# Ответить
Внимание! За постинг в данном форуме $m не начисляются.
Внимание! Для написания сообщения необходимо авторизоваться
Текст сообщения*
Прикрепить файл