Имя: Пароль:
1C
1С v8
Интеграция AMI Asterisk + 1С входящие/исходящие
,
0 Vladislava-smile
 
11.11.16
09:50
Добрый день, кто сталкивался - подскажите как определять входящий вызов или исходящий.

Библиотеку подкрутила, 1с - ка отлавливает события AMI.

Из событий VarSet параметры value, Channel, ID гружу в ТЗ

При снятии трубки по Bridge есть Channel1 и Channel2 и ID1 и ID2. Ищу в ТЗ файл записи.

Как я думала, если найден по Channel1 и ID1, то номером клиента является CallerID1, а звонок входящий, но нет (((

По Hangup с отбором ТЗ чиститься.
1 ADirks
 
11.11.16
10:03
Лучше беги от этой шляпы куда подальше
Разбирать протоколы от астериска - это то ещё развлечение.

кстати, там ещё там перевод звонка бывает...

Ну а если не убежать, то берёшь полные протоколы, и куришь их, пока из ушей не полезет.
у нас вот, к примеру, такое накурилось



стрСобытие = сзПакет.Получить("Event");
Если стрСобытие = "Cdr" Тогда
    UniqueID = сзПакет.Получить("UniqueID");
    Если UniqueID = идСоединение Тогда
        _Звонок_Завершение(сзПакет);
    КонецЕсли;
    
ИначеЕсли стрСобытие = "Newchannel" Тогда
    Если стрСостояние = "" Тогда
        Channel = сзПакет.Получить("Channel");
        идСоединение = сзПакет.Получить("Uniqueid");
        
        УстановитьФильтрСобытий(стрФильтр_Channel());
    КонецЕсли;
    
ИначеЕсли стрСобытие = "Dial" Тогда
    _Звонок_Dial(сзПакет);
    
ИначеЕсли стрСобытие = "Bridge" Тогда
    State = сзПакет.Получить("Bridgestate");

    CallerID1 = сзПакет.Получить("CallerID1");
    CallerID2 = сзПакет.Получить("CallerID2");
    ИД = сзПакет.Получить("Uniqueid1");

    Channel1 = сзПакет.Получить("Channel1");
    Channel2 = сзПакет.Получить("Channel2");
    _ВЛог("Bridge: State = "+State+", стрСостояние = "+стрСостояние+", CallerID1 = "+CallerID1+", CallerID2 = "+CallerID2+", Channel1 = "+Channel1+", "+Channel);
    
    Если (State = "Link") И (CallerID2 = МойТелефон) Тогда //входящий
        Если (идСоединение <> ИД) ИЛИ (стрСостояние = "") Тогда
            Channel = Channel2;
            идСоединение = ИД;
            стрСостояние = сост_Входящий;
            Номер1 = УнифицированныйНомерТелефона(CallerID1);
            Номер2 = МойТелефон;
            
            УстановитьФильтрСобытий(стрФильтр_Channel());
            ...
        КонецЕсли;
        
    ИначеЕсли (State = "Link") И ((CallerID1 = МойТелефон) ИЛИ (Channel1 = Channel)) Тогда //исходящий
        //!!! если приходит повторное событие, то нужно его проигнорировать !!!
        Если (идСоединение <> ИД) ИЛИ (стрСостояние = "") Тогда
            Channel = Channel1;
            идСоединение = ИД;
            стрСостояние = сост_Исходящий;
            Номер1 = МойТелефон;
            Номер2 = УнифицированныйНомерТелефона(CallerID2);
            
            УстановитьФильтрСобытий(стрФильтр_Channel());
            ...
        КонецЕсли;
    КонецЕсли;

ИначеЕсли стрСобытие = "Hangup" Тогда
    _Звонок_Завершение(сзПакет);
КонецЕсли;
2 Vladislava-smile
 
11.11.16
10:11
(1) - примерно то же самое и у меня, как я понимаю у Вас в базе у пользователей прописан свой внутренний номер (МойТелефон). Я думала, что по средствам астериска есть какой-то способ определять тип звонка. Но все равно спасибо.
3 ADirks
 
11.11.16
10:21
(2) ну да, у нас такой вот частный случай, потому я и говорю "например"
Думаю, что есть более правильные способы, но лезть слишком глубоко ни желания ни времени не было.
4 Fedor-1971
 
11.11.16
10:48
(0) Получи трассу звонка в текстовом виде. Примерно такую:
- 06.09.2016 12:57:46
Event: DialBegin
Privilege: call,all
Channel: SIP/3001-00000828
ChannelState: 6
ChannelStateDesc: Up
CallerIDNum: 3001
CallerIDName: Soroka
ConnectedLineNum: 3001
ConnectedLineName: <unknown>
Language: en
AccountCode:
Context: All-1C
Exten: 9879150400502
Priority: 1
Uniqueid: 1473155861.13765
Linkedid: 1473155861.13765
DestChannel: SIP/oTrunk638-00000829
DestChannelState: 0
DestChannelStateDesc: Down
DestCallerIDNum: 9879150400502
DestCallerIDName: <unknown>
DestConnectedLineNum: 3001
DestConnectedLineName: Soroka
DestLanguage: en
DestAccountCode:
DestContext: from-Mango
DestExten: 9879150400502
DestPriority: 1
DestUniqueid: 1473155863.13768
DestLinkedid: 1473155861.13765
DialString: 79150400502@oTrunk638
- 06.09.2016 12:57:47
Event: Hangup
Privilege: call,all
Channel: SIP/oTrunk638-00000829
ChannelState: 0
ChannelStateDesc: Down
CallerIDNum: 9879150400502
CallerIDName: <unknown>
ConnectedLineNum: 3001
ConnectedLineName: Soroka
Language: en
AccountCode:
Context: from-Mango
Exten: 9879150400502
Priority: 1
Uniqueid: 1473155863.13768
Linkedid: 1473155861.13765
Cause: 16
Cause-txt: Normal Clearing
- 06.09.2016 12:57:47
Event: Hangup
Privilege: call,all
Channel: SIP/3001-00000828
ChannelState: 6
ChannelStateDesc: Up
CallerIDNum: 3001
CallerIDName: Soroka
ConnectedLineNum: 3001
ConnectedLineName: <unknown>
Language: en
AccountCode:
Context: All-1C
Exten: 9879150400502
Priority: 1
Uniqueid: 1473155861.13765
Linkedid: 1473155861.13765
Cause: 16
Cause-txt: Normal Clearing


Дальше несколько способов:
1.Анализируешь:
       CallerIDNum: - Номер с которого набирали
       Exten: - набранный номер
и определяешь если короткий 1, то звонок исходящий, если 2, то звонок входящий

2. Правильно называешь контексты звонка
Например, Context: для входящих всегда начинаем с IN, для исходящих OUT.

В обеих случаях будет проблема если нужно определить внутренний звонок был входящим или исходящим, и выход только один - как-то зафиксировать номер сотрудника, относительно которого проверяем (например, сохранить его в справочнике)
5 Serginio1
 
11.11.16
10:49
6 Serginio1
 
11.11.16
10:50
7 Йохохо
 
11.11.16
10:56
(4) но если вы поймали dialbegin, там же сразу понятно кто дайял бегин
8 Vladislava-smile
 
11.11.16
10:57
(4) - спасибо, буду пробовать.
9 Fedor-1971
 
11.11.16
11:00
(7) при неизвестном номере сотрудника - нет
10 Fedor-1971
 
11.11.16
11:03
9+ Трасса исходящего звонка
- 06.09.2016 12:49:32
Event: DialBegin
Privilege: call,all
Channel: SIP/oTrunk553-0000080e
ChannelState: 6
ChannelStateDesc: Up
CallerIDNum: 79165895764
CallerIDName: 79165895764
ConnectedLineNum: <unknown>
ConnectedLineName: <unknown>
Language: en
AccountCode:
Context: from-Mango
Exten: 4996382550
Priority: 2
Uniqueid: 1473155368.13583
Linkedid: 1473155368.13583
DestChannel: SIP/3001-00000812
DestChannelState: 0
DestChannelStateDesc: Down
DestCallerIDNum: 3001
DestCallerIDName: Soroka
DestConnectedLineNum: <unknown>
DestConnectedLineName: <unknown>
DestLanguage: en
DestAccountCode:
DestContext: All-1C
DestExten:
DestPriority: 1
DestUniqueid: 1473155368.13593
DestLinkedid: 1473155368.13583
DialString: SIP/3001
- 06.09.2016 12:49:35
Event: Hangup
Privilege: call,all
Channel: SIP/3001-00000812
ChannelState: 5
ChannelStateDesc: Ringing
CallerIDNum: 3001
CallerIDName: Soroka
ConnectedLineNum: 79165895764
ConnectedLineName: 79165895764
Language: en
AccountCode:
Context: All-1C
Exten: 4996382550
Priority: 1
Uniqueid: 1473155368.13593
Linkedid: 1473155368.13583
Cause: 26
Cause-txt: Answered elsewhere


К стати, в (4) надо опираться не на Exten, а на DestCallerIDNum - номер куда звонили, в данном случае нашему сотруднику

Всё зависит от версии Asterisk и библиотеки захвата событий AMI. Так что, (8) успехов в анализе
11 Fragster
 
гуру
11.11.16
11:04
я забил и купил https://telefon.miko.ru/
12 Йохохо
 
11.11.16
11:08
(10) исходящего? "DialString: SIP/3001" это чистый астериск или поверх еще что то? "Context: from-Mango"
13 Fedor-1971
 
11.11.16
11:09
(11) Это правильно. Есть много готовых решений. Плюс в том, что какую-то поддержку от поставщика получить всё-таки удастся (пока деньги не заплачены и не подписан акт внедрения).
14 Fedor-1971
 
11.11.16
11:12
(12) DialString: SIP/oTrunk553, практически чистый лог, контексты и номера игрушечные, на боевой нормально названы контексты
15 Йохохо
 
11.11.16
11:14
(14) нет такой строки DialString: SIP/oTrunk553
16 Fedor-1971
 
11.11.16
11:17
(15) таки и строки из (12) в трассе нет
17 Йохохо
 
11.11.16
11:17
DestUniqueid: 1473155368.13593
DestLinkedid: 1473155368.13583
DialString: SIP/3001
18 Йохохо
 
11.11.16
11:19
Context: from-Mango
DestContext: All-1C
это входящий
19 Fedor-1971
 
11.11.16
11:25
(17)(18) Да, лопухнулся. Это входящий.
(0) обрати внимание, что при настройке Dial(sip, sip, sip ...) Hungup то же будет несколько и ты почистишь ТЗ до завершения звонка
20 Йохохо
 
11.11.16
11:39
21 Fedor-1971
 
11.11.16
12:23
(20) надёжно отследить звонок можно только так:
DialBegin (иногда их несколько) - BridgeEnter (может быть несколько) - Hangup (может быть несколько).
Пишем данные в РС с измерениями Linkedid (от первого BridgeEnter) и датой звонка - обеспечит уникальность звонка за день. После того как положили трубку (BridgeLeave - их то же может быть несколько) будут идти ещё некоторое время события закрытия канала, поэтому просто пишем события в РС и если нужно, отображаем пользователю.

Как показывает опыт эксплуатации - на начальном этапе: "мы хотим ВСЁ и сразу прямо On-Line", а по факту: "достаточно загрузить лог звонков за вчерашний день".
22 Йохохо
 
11.11.16
12:36
(21) а оно отловит так звонок на ринг групп с стратегией ринг ол и пропущенный менеджером?
23 Fedor-1971
 
11.11.16
13:39
(22) Если ни кто трубку не взял, будет запись с признаком "Недозвон" (есть DialBegin - Hangup  но внутри нет событий для регистрации, трубку сотрудники не поднимали),
если кто-то трубку поднял - ему зарегистрируется звонок, остальным в группе ничего не регистрируется.

Можно посмотреть трассу звонка на группу и определить события вызова адресатов группы (Queue скорее всего) и если нужно  можно писать в РС и эту информацию, только придётся добавить в измерения "Внутренний номер"
24 CodeFinder
 
11.11.16
13:42
Я делал на Django + soap по 1с. Звонки по call файлам.
25 APXi
 
11.11.16
13:57
А какую компоненту лучше использовать для связи с астериском?
26 CodeFinder
 
11.11.16
13:57
(25) если звонить call файлы.
27 APXi
 
11.11.16
14:00
А если еще смотреть кто куда звонит, занят/не занят и т.д.?
28 CodeFinder
 
11.11.16
14:02
(27) астериск ведет базу логов. подключаешся как ко внешней базе и поехали. яндекси cdr
29 Vladislava-smile
 
16.11.16
08:06
Товарищи, вопрос с входящими решен с помощью события:

    Если Событие = "Newchannel" тогда
        
        НовЗапись = ТЗСобытийVarSet.Добавить();
        НовЗапись.Uniqueid = СтруктураПолей.Получить("Uniqueid");
        
        Если СтруктураПолей.Получить("Context") = "incall" тогда
            НовЗапись.Телефон = "8" + СтруктураПолей.Получить("CallerIDNum");
            НовЗапись.ВидЗвонка = Перечисления.ВидЗвонка.Входящий;
        Иначе
            НовЗапись.Телефон = СтруктураПолей.Получить("Exten");
            НовЗапись.ВидЗвонка = Перечисления.ВидЗвонка.Исходящий;
        КонецЕсли;
        
    ИначеЕсли Событие = "VarSet" тогда
...

Теперь встал вопрос с исходящими вызовами из 1с.

ТекстКоманды = "Action: Originate" + CRLF +
    "Channel: SIP/" + СокрЛП(ВнутреннийНомерПользователя) + CRLF +
    "Context: from-internal" + CRLF +
    "Exten: " + СокрЛП(ВходящийНомерТелефона) + CRLF +
    "Priority: 1" + CRLF+
    "Callerid: " + ВнутреннийНомерПользователя + "->" + СокрЛП(ВходящийНомерТелефона) + CRLF +
    "Timeout: 30000" + CRLF +
    "Async: true" + CRLF;
Asterisk._АстерискВыполнитьКоманду(ТекстКоманды);

Софтфон срабатывает, но после поднятия трубки не проиходит дальнейшего звонка. Что не так?
30 Vladislava-smile
 
16.11.16
08:09
Если просто звонить с софтфона - звонок идет
31 Shved_72
 
16.11.16
08:26
офф: никто не дружил 1с в керио-оператор?
32 Vladislava-smile
 
16.11.16
08:28
(31) - так он вроде платный, нет?
33 Vladislava-smile
 
16.11.16
08:29
(31) - да и зачем?
34 Shved_72
 
16.11.16
08:33
платный. хотя там тоже Астерикс
"AMI (интерфейс управления сервером Asterisk) — интеграция с другими системами управления взаимоотношениями с клиентами (CRM)."
http://www.kerio.ru/products/kerio-operator/features
35 Vladislava-smile
 
16.11.16
08:39
(34) и что? Зачем мне это? я уже прикрутила все через библиотеку к 1с. Может у кого пример есть? Или в каких логах посмотреть?
36 trdm
 
16.11.16
08:41
С астериксом не возился, но делал ч/з коммуникейшинАссистент.
Та еще гемороища. И не любая станция подходит.
37 Йохохо
 
16.11.16
08:48
(29) вроде все верно. -> не нравится, вроде в конец надо еще 1 пустую строку добавить, один црлф. А что на софтфоне после поднятия трубки?
38 Йохохо
 
16.11.16
08:56
"Callerid: " + ВнутреннийНомерПользователя + "->" + СокрЛП(ВходящийНомерТелефона)
"Async: true" + CRLF;
уберите это, потом можно так попробовать
"Callerid: " + СокрЛП(ВходящийНомерТелефона) + CRLF
39 Fedor-1971
 
16.11.16
08:56
(29) Проверяй на консоли Астериска: возможно твой контекст просто не имеет выхода наружу (имеет смысл специально сделать отдельный контекст для звонков из 1С, т.е. с софтофона -одни правила набора, а из 1С другие, с полными префиксами разрешенных направлений звонка, т.к. пользователь их не набирает).
Как тест без консоли: набери внутренний номер.

У меня Asnc=false и CallerID=внутренний номер
40 Йохохо
 
16.11.16
08:59
(39) почему внутренний?)
для отладки можно позвонить через ssh, это ж линукс
41 Fedor-1971
 
16.11.16
09:01
(40) CallerID - кто звонит, т.е. внутренний номер.
42 Vladislava-smile
 
16.11.16
09:02
(37) - тишина, вообще никаких действий нет
43 Fedor-1971
 
16.11.16
09:03
41+ Exten: - куда звоним
44 Йохохо
 
16.11.16
09:03
(42) убрали строки?
45 Vladislava-smile
 
16.11.16
09:04
(38) - ничего не изменилось (
46 Йохохо
 
16.11.16
09:06
(45) проверьте контекст "Context: from-internal" он такой у внутренних? у внешнего абонента есть звонок?
шел есть на астериск?
47 Йохохо
 
16.11.16
09:08
если астер вообще чужой, еще бы права ами пользователя проверить, есть ли право звонить
48 Fedor-1971
 
16.11.16
09:09
(42) нужно посмотреть в консоль сервера астериск (строка запуска: "asterisk -rvvvv", т.е. подробная информация об установке соединения) посмотреть что происходит на стороне астериска

(45) CallerID - просто внутренний номер телефона, а не тот на который звоним
"CallerID:" + СокрЛП(ВнутреннийНомерПользователя) + CRLF +
"Exten: " + СокрЛП(ВходящийНомерТелефона) + CRLF + тут точно номер на который звоним?
49 Vladislava-smile
 
16.11.16
09:09
(47) звонок идет из софтфона
50 Fedor-1971
 
16.11.16
09:10
(49) контекст от софтофона = from-internal
51 Vladislava-smile
 
16.11.16
09:10
(48) "Exten: " + СокрЛП(ВходящийНомерТелефона) + CRLF + тут точно номер на который звоним?

Абсолютно точно - по отладчику проверяла.
52 Fedor-1971
 
16.11.16
09:11
(51) а CallerID? контексты точно одинаковые на софтофоне и при звонке из 1С
53 Fedor-1971
 
16.11.16
09:12
52+ всю строку инициализации звонка сюда можно выложить?
54 Йохохо
 
16.11.16
09:12
(51) точно
55 Vladislava-smile
 
16.11.16
09:14
Action: Originate
Channel: SIP/104
Context: from-internal
Exten: 89144004946
Priority: 1
Callerid: 104
56 Йохохо
 
16.11.16
09:15
(55) таймаут не скопипастился?
57 Vladislava-smile
 
16.11.16
09:16
(55) а он и ним и без него не пашет
58 Vladislava-smile
 
16.11.16
09:18
В софтфоне идет отображение как входящего звонка

104(104)(104)
59 Йохохо
 
16.11.16
09:18
позвоните на внутренний
60 Fedor-1971
 
16.11.16
09:19
(57) таймаут нужен - иначе астериск тупо кладёт трубку в канале, типа пользователь не ответил, Async:false - ждём когда пользователь снимет трубку на софтофоне
(58) правильно, Звоним себе, когда сняли трубку - инициируем вызов внешненго номера
61 Vladislava-smile
 
16.11.16
09:20
(59) - никаких изменений
62 Vladislava-smile
 
16.11.16
09:21
(60) - вернула
63 Йохохо
 
16.11.16
09:21
я бы контекст проверил, т.к. вроде все верно
64 Fedor-1971
 
16.11.16
09:25
(61) можно попробовать софтофон: MicroSIP, и как-бы пора добраться до консоли астериск и контекстов
65 Йохохо
 
16.11.16
09:30
(64) или cygwin + nmap =) го хц
66 Vladislava-smile
 
16.11.16
10:29
(64) - попробую MicroSIP, спасибо
67 Vladislava-smile
 
16.11.16
10:29
(63) а где его проверять?
68 Fedor-1971
 
16.11.16
10:39
(67) на сервере Астериска,
в файлах extension*.* находишь [fom_internal] и смотришь куда из него можно звонить и можно ли вообще,
в файлах sip*.* (pjsip*.*) ищешь [внутренний номер телефона] и смотришь контекст.

Если сама не настраивала, лучше дёрни админа и вместе с ним глянете на настройки и консоль сервера.
69 Йохохо
 
16.11.16
11:20
или попросите вывод "sip show peer 104" из консоли астериска asterisk -r , строка Context
70 Vladislava-smile
 
17.11.16
06:04
(68, 69) - спасибо, так и сделаю
71 Vladislava-smile
 
17.11.16
08:10
Если убрать контекст или поставить office, тогда
звонок идет, НО поле Exten при Event: Newchannel не заполнено (если звонить из 1С), но если звонить из микросипа, тогда поле заполнено. Почему?
72 Vladislava-smile
 
17.11.16
08:10
Спросила у админа, он сказал, что астериске все поля заполняются и контекст стоит office
73 Vladislava-smile
 
17.11.16
09:08
Вот что я получаю:

Event: Newchannel
Privilege: call,all
Channel: SIP/104-000000f9
ChannelState: 0
ChannelStateDesc: Down
CallerIDNum:
CallerIDName:
AccountCode:
Exten:
Context: office
Uniqueid: 1479362841.249
Event: VarSet
Privilege: dialplan,all
Channel: SIP/104-000000f9
Variable: MIXMONITOR_FILENAME
Value: /var/record/2016/11/17/1479362841.249-2016-11-17-16_07-104-89144004946.wav
Uniqueid: 1479362841.249
Event: Newchannel
Privilege: call,all
Channel: SIP/sipout-000000fa
ChannelState: 0
ChannelStateDesc: Down
CallerIDNum:
CallerIDName:
AccountCode:
Exten:
Context: incall
Uniqueid: 1479362842.250
Event: Dial
Privilege: call,all
SubEvent: Begin
Channel: SIP/104-000000f9
Destination: SIP/sipout-000000fa
CallerIDNum: 104
CallerIDName: <unknown>
ConnectedLineNum: 104
ConnectedLineName: <unknown>
UniqueID: 1479362841.249
DestUniqueID: 1479362842.250
Dialstring: sipout/89144004946
Event: Bridge
Privilege: call,all
Bridgestate: Link
Bridgetype: core
Channel1: SIP/104-000000f9
Channel2: SIP/sipout-000000fa
Uniqueid1: 1479362841.249
Uniqueid2: 1479362842.250
CallerID1: 104
CallerID2: 89144004946
Event: Hangup
Privilege: call,all
Channel: SIP/sipout-000000fa
Uniqueid: 1479362842.250
CallerIDNum: 89144004946
CallerIDName: <unknown>
ConnectedLineNum: 104
ConnectedLineName: <unknown>
Cause: 16
Cause-txt: Normal Clearing
Event: Hangup
Privilege: call,all
Channel: SIP/104-000000f9
Uniqueid: 1479362841.249
CallerIDNum: 104
CallerIDName: <unknown>
ConnectedLineNum: 104
ConnectedLineName: <unknown>
Cause: 16
Cause-txt: Normal Clearing
74 Fedor-1971
 
17.11.16
09:20
(71) не парься, NewChannel начинается на Originate, т.е. с вызова своего софтофона, Async=true параллельно отправляет вызов на внешний номер.

Опирайся на:
UniqueID: 1479362841.249 - он одинаковый до конца звонка по нему записывай события в регистр сведений и сможешь отследить когда началась обработка звонка (NewChannel), подняли трубку (Bridge ), положили трубку(Hungup)- если надо, то кто первый положил трубку)

Дальше анализируй Bridge по "CallerID1: 104" и "CallerID2: 89144004946" для определения направления звонка (или можно опереться на контекст, но его может поменять админ без всяких мыслей, что он где-то используется)

Завершение звонка: последнее событие Hungup c "CallerIDNum: 104"
75 Vladislava-smile
 
17.11.16
09:30
(74) да я так и сделал все уже, просто не понятно почему???

Ладно, тема закрыта, Fedor-1971, отдельное спасибо )
76 Fedor-1971
 
17.11.16
09:37
(75) потому что, вызов инициирует сервер Астериск, поэтому первое событие не содержит ни каких данных о телефонах, за то определяет UniqueID.
Компьютеры — это как велосипед. Только для нашего сознания. Стив Джобс