Asterisk-ի և Bitrix24-ի ինտեգրում

Asterisk-ի և Bitrix24-ի ինտեգրում
Ցանցում IP-PBX Asterisk-ի և CRM Bitrix24-ի ինտեգրման տարբեր տարբերակներ կան, բայց մենք դեռ որոշեցինք գրել մերը:

Ֆունկցիոնալության առումով ամեն ինչ ստանդարտ է.

  • Bitrix24-ում կտտացնելով հաճախորդի հեռախոսահամարով հղման վրա՝ Asterisk-ը կապում է այն օգտատիրոջ ներքին համարը, որի անունից սեղմումը կատարվել է հաճախորդի հեռախոսահամարի հետ: Bitrix24-ում ձայնագրվում է զանգի ձայնագրությունը, իսկ զանգի վերջում վեր հանվում է խոսակցության ձայնագրությունը:
  • Աստղանիշը զանգ է ստանում դրսից. Bitrix24 ինտերֆեյսում մենք հաճախորդի քարտը ցույց ենք տալիս այն աշխատակցին, ում համարին հասել է այս զանգը:
    Եթե ​​այդպիսի հաճախորդ չլինի, մենք կբացենք նոր առաջատարի ստեղծման քարտը:
    Զանգն ավարտվելուն պես մենք դա արտացոլում ենք քարտի վրա և վեր հանում խոսակցության ձայնագրությունը:

Կտրվածքի տակ ես ձեզ կասեմ, թե ինչպես կարգավորել ամեն ինչ ձեզ համար և ձեզ հղում տալ github-ին. այո, այո, վերցրեք այն և օգտագործեք այն:

Ընդհանուր նկարագրություն

Մենք մեր ինտեգրումն անվանեցինք CallMe: CallMe-ը փոքր վեբ հավելված է, որը գրված է PHP-ով:

Օգտագործված տեխնոլոգիաներ և ծառայություններ

  • PHP 5.6
  • PHP AMI գրադարան
  • Կոմպոզիտոր
  • Nginx + php-fpm
  • վերահսկիչ
  • AMI (Asterisk Manager ինտերֆեյս)
  • Bitrix webhooks (պարզեցված REST API-ի իրականացում)

Նախնական կարգավորում

Asterisk-ով սերվերի վրա պետք է տեղադրել վեբ սերվեր (մեզ համար դա nginx+php-fpm է), վերահսկիչ և git։

Տեղադրման հրաման (CentOS):

yum install nginx php-fpm supervisor git

Մենք գնում ենք վեբ սերվերին հասանելի գրացուցակ, քաշում ենք հավելվածը Git-ից և սահմանում ենք անհրաժեշտ իրավունքները թղթապանակում.


cd /var/www
git clone https://github.com/ViStepRU/callme.git
chown nginx. -R callme/

Հաջորդը, եկեք կարգավորենք nginx-ը, մեր կազմաձևը գտնվում է դրանում

/etc/nginx/conf.d/pbx.vistep.ru.conf

server {
	server_name www.pbx.vistep.ru pbx.vistep.ru;
	listen *:80;
	rewrite ^  https://pbx.vistep.ru$request_uri? permanent;
}

server {
#        listen *:80;
#	server_name pbx.vistep.ru;


	access_log /var/log/nginx/pbx.vistep.ru.access.log main;
        error_log /var/log/nginx/pbx.vistep.ru.error.log;

    listen 443 ssl http2;
    server_name pbx.vistep.ru;
    resolver 8.8.8.8;
    ssl_stapling on;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/pbx.vistep.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/pbx.vistep.ru/privkey.pem;
    ssl_dhparam /etc/nginx/certs/dhparam.pem;
    ssl_session_timeout 24h;
    ssl_session_cache shared:SSL:2m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers kEECDH+AES128:kEECDH:kEDH:-3DES:kRSA+AES128:kEDH+3DES:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!MD5:!EXPORT:!LOW:!SEED:!CAMELLIA:!IDEA:!PSK:!SRP:!SSLv2;
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=31536000;";
    add_header Content-Security-Policy-Report-Only "default-src https:; script-src https: 'unsafe-eval' 'unsafe-inline'; style-src https: 'unsafe-inline'; img-src https: data:; font-src https: data:; report-uri /csp-report";
	
	root /var/www/callme;
	index  index.php;
        location ~ /. {
                deny all; # запрет для скрытых файлов
        }

        location ~* /(?:uploads|files)/.*.php$ {
                deny all; # запрет для загруженных скриптов
        }

        location ~* ^.+.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
                access_log off;
                log_not_found off;
                expires max; # кеширование статики
        }

	location ~ .php {
		root /var/www/callme;
		index  index.php;
		fastcgi_pass unix:/run/php/php5.6-fpm.sock;
	#	fastcgi_pass 127.0.0.1:9000;
		fastcgi_index index.php;
		fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
		include /etc/nginx/fastcgi_params;
		}
}

Ես կթողնեմ կազմաձևի վերլուծությունը, անվտանգության խնդիրները, վկայական ստանալը և նույնիսկ վեբ սերվերի ընտրությունը հոդվածի շրջանակից դուրս. այս մասին շատ է գրվել: Հավելվածը սահմանափակումներ չունի, այն աշխատում է ինչպես http-ով, այնպես էլ https-ով:

Մենք օգտագործում ենք https, եկեք գաղտնագրենք վկայականը:

Եթե ​​ամեն ինչ ճիշտ եք արել, ապա սեղմելով հղման վրա դուք պետք է տեսնեք նման բան

Asterisk-ի և Bitrix24-ի ինտեգրում

Bitrix24-ի կարգավորում

Եկեք ստեղծենք երկու վեբ-կեռիկներ:

Մուտքային վեբ կեռիկ:

Ադմինիստրատորի հաշվի տակ (id 1-ով) հետևեք ուղուն՝ Applications -> Webhooks -> Add webhook -> Incoming webhook

Asterisk-ի և Bitrix24-ի ինտեգրում

Լրացրեք մուտքային վեբ-կապիկի պարամետրերը, ինչպես սքրինշոթներում.

Asterisk-ի և Bitrix24-ի ինտեգրում

Asterisk-ի և Bitrix24-ի ինտեգրում

Եվ սեղմեք պահպանել:

Պահելուց հետո Bitrix24-ը կտրամադրի մուտքային վեբ-կապիկի URL-ը, օրինակ՝

Asterisk-ի և Bitrix24-ի ինտեգրում

Պահպանեք URL-ի ձեր տարբերակը առանց վերջնական /պրոֆիլի/-ի, այն կօգտագործվի հավելվածում՝ մուտքային զանգերի հետ աշխատելու համար:

Ես ունեմ սա https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/

Ելքային վեբ կեռիկ:

Ծրագրեր -> Webhooks -> Add webhook -> Outgoing webhook

Մանրամասները կրկին սքրինշոթերում են.

Asterisk-ի և Bitrix24-ի ինտեգրում

Asterisk-ի և Bitrix24-ի ինտեգրում

Պահպանեք և ստացեք թույլտվության կոդը

Asterisk-ի և Bitrix24-ի ինտեգրում

Ես ունեմ սա xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6. Դուք նաև պետք է պատճենեք այն ձեզ համար, այն ձեզ անհրաժեշտ է ելքային զանգեր կատարելու համար:

Կարեւոր!

SSL վկայագիրը պետք է կազմաձևված լինի Bitrix24 սերվերի վրա (կարող եք օգտագործել letsencrypt), հակառակ դեպքում Bitrix api-ն չի աշխատի։ Եթե ​​ունեք ամպային տարբերակ, մի անհանգստացեք, այն արդեն ունի ssl:

Կարեւոր!

«Պրոցեսորի հասցե» դաշտը պետք է պարունակի ինտերնետից հասանելի հասցե:

Եվ որպես վերջին հպում, եկեք տեղադրենք մեր CallMeOut-ը որպես զանգեր կատարելու հավելված (որպեսզի PBX-ի համարի վրա սեղմելիս զանգի սկզբնավորման հրամանը կթռչի):

Մենյուում ընտրեք. Լրացուցիչ -> Հեռախոսակապ -> Ավելին -> Կարգավորումներ, դրեք «Լռելյայն ելքային զանգի համարը» Հավելվածը. CallMeOut և սեղմեք «Պահպանել»:

Asterisk-ի և Bitrix24-ի ինտեգրում

Աստղանիշի կարգավորում

Asterisk-ի և Bitrix24-ի միջև հաջող փոխգործակցության համար մենք պետք է ավելացնենք AMI օգտվողի callme-ը manager.conf-ում:

[callme]
secret = JD3clEB8_f23r-3ry84gJ
deny = 0.0.0.0/0.0.0.0
permit = 127.0.0.1/255.255.255.0
permit= 10.100.111.249/255.255.255.255
permit = 192.168.254.0/255.255.255.0
read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan
write = system,call,agent,log,verbose,user,config,command,reporting,originate

Հաջորդը, կան մի քանի հնարքներ, որոնք պետք է իրականացվեն dialplan-ի միջոցով (մեզ համար սա extensions.ael-ն է):

Ես կներկայացնեմ ամբողջ ֆայլը, իսկ հետո բացատրություն կտամ.

globals {
    WAV=/var/www/pbx.vistep.ru/callme/records/wav; //Временный каталог с WAV
    MP3=/var/www/pbx.vistep.ru/callme/records/mp3; //Куда выгружать mp3 файлы
    URLRECORDS=https://pbx.vistep.ru/callme/records/mp3;
    RECORDING=1; // Запись, 1 - включена.
};

macro recording(calling,called) {
        if ("${RECORDING}" = "1"){
              Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${calling}-${called});
	      Set(datedir=${STRFTIME(${EPOCH},,%Y/%m/%d)});
	      System(mkdir -p ${MP3}/${datedir});
	      System(mkdir -p ${WAV}/${datedir});
              Set(monopt=nice -n 19 /usr/bin/lame -b 32  --silent "${WAV}/${datedir}/${fname}.wav"  "${MP3}/${datedir}/${fname}.mp3" && rm -f "${WAV}/${fname}.wav" && chmod o+r "${MP3}/${datedir}/${fname}.mp3");
	      Set(FullFname=${URLRECORDS}/${datedir}/${fname}.mp3);
              Set(CDR(filename)=${fname}.mp3);
	      Set(CDR(recordingfile)=${fname}.wav);
              Set(CDR(realdst)=${called});
              MixMonitor(${WAV}/${datedir}/${fname}.wav,b,${monopt});

       };
};


context incoming {
888999 => {
	&recording(${CALLERID(number)},${EXTEN});
        Answer();
        ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp()); // выставляем CallerID если узнали его у Битрикс24
        Set(CallStart=${STRFTIME(epoch,,%s)});  
        Queue(Q1,tT);
        Set(CallMeDISPOSITION=${CDR(disposition)}); 
        Hangup();
        }

h => {
    Set(CDR_PROP(disable)=true); 
    Set(CallStop=${STRFTIME(epoch,,%s)}); 
    Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)}); 
    ExecIF(${ISNULL(${CallMeDISPOSITION})}?Set(CallMeDISPOSITION=${CDR(disposition)}):NoOP(=== CallMeDISPOSITION already was set ===));  
}

}


context default {

_X. => {
        Hangup();
        }
};


context dial_out {

_[1237]XX => {
	&recording(${CALLERID(number)},${EXTEN});
        Set(__CallIntNum=${CALLERID(num)})
	Set(CallStart=${STRFTIME(epoch,,%s)});
        Dial(SIP/${EXTEN},,tTr);
        Hangup();
        }

_11XXX => {
	&recording(${CALLERID(number)},${EXTEN});
	Set(CallStart=${STRFTIME(epoch,,%s)});
	Set(__CallIntNum=${CALLERID(num)});
        Dial(SIP/${EXTEN:2}@toOurAster,,t);
        Hangup();
        }

_. => {
	&recording(${CALLERID(number)},${EXTEN});
        Set(__CallIntNum=${CALLERID(num)})
	Set(CallStart=${STRFTIME(epoch,,%s)});
	Dial(SIP/${EXTEN}@toOurAster,,t);
	Hangup();
        }

h => {
        Set(CDR_PROP(disable)=true);
        Set(CallStop=${STRFTIME(epoch,,%s)});
        Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)});
	if(${ISNULL(${CallMeDISPOSITION})}) {
          Set(CallMeDISPOSITION=${CDR(disposition)});
        }
	System(curl -s http://pbx.vistep.ru/CallMeOut.php --data action=sendcall2b24 --data call_id=${CallMeCALL_ID} --data-urlencode FullFname=${FullFname} --data CallIntNum=${CallIntNum} --data CallDuration=${CallMeDURATION} --data-urlencode CallDisposition=${CallMeDISPOSITION});
}

};

Սկսենք սկզբից՝ հրահանգը գլոբալներ.

Փոփոխական URL Ձայնագրություններ պահպանում է զրույցի ձայնագրման ֆայլերի URL-ը, ըստ որի Bitrix24-ը դրանք կքաշի կոնտակտային քարտի մեջ:

Հաջորդը մեզ հետաքրքրում է մակրոմակրո ձայնագրում.

Այստեղ, բացի խոսակցությունները ձայնագրելուց, մենք կսահմանենք փոփոխականը FullFname.

Set(FullFname=${URLRECORDS}/${datedir}/${fname}.mp3);

Այն պահպանում է ամբողջական URL-ը կոնկրետ ֆայլում (մակրոն կոչվում է ամենուր):

Եկեք վերլուծենք ելքային զանգը.

_. => {
	&recording(${CALLERID(number)},${EXTEN});
        Set(__CallIntNum=${CALLERID(num)})
	Set(CallStart=${STRFTIME(epoch,,%s)});
	Dial(SIP/${EXTEN}@toOurAster,,t);
	Hangup();
        }

h => {
        Set(CDR_PROP(disable)=true);
        Set(CallStop=${STRFTIME(epoch,,%s)});
        Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)});
	if(${ISNULL(${CallMeDISPOSITION})}) {
          Set(CallMeDISPOSITION=${CDR(disposition)});
        }
	System(curl -s http://pbx.vistep.ru/CallMeOut.php --data action=sendcall2b24 --data call_id=${CallMeCALL_ID} --data-urlencode FullFname=${FullFname} --data CallIntNum=${CallIntNum} --data CallDuration=${CallMeDURATION} --data-urlencode CallDisposition=${CallMeDISPOSITION});
}

Ենթադրենք, մենք զանգահարում ենք 89991234567, առաջին հերթին մենք ստանում ենք այստեղ.

&recording(${CALLERID(number)},${EXTEN});

դրանք. Զրույցի ձայնագրման մակրոն կանչվում է, և անհրաժեշտ փոփոխականները սահմանվում են:

Հետագա

        Set(__CallIntNum=${CALLERID(num)})
	Set(CallStart=${STRFTIME(epoch,,%s)});

Մենք արձանագրում ենք, թե ով է նախաձեռնել զանգը և գրանցում զանգի մեկնարկի ժամը:

Իսկ դրա ավարտից հետո՝ հատուկ համատեքստում h

h => {
        Set(CDR_PROP(disable)=true);
        Set(CallStop=${STRFTIME(epoch,,%s)});
        Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)});
	if(${ISNULL(${CallMeDISPOSITION})}) {
          Set(CallMeDISPOSITION=${CDR(disposition)});
        }
	System(curl -s http://pbx.vistep.ru/CallMeOut.php --data action=sendcall2b24 --data call_id=${CallMeCALL_ID} --data-urlencode FullFname=${FullFname} --data CallIntNum=${CallIntNum} --data CallDuration=${CallMeDURATION} --data-urlencode CallDisposition=${CallMeDISPOSITION});
}

անջատել մուտքը CDR աղյուսակի այս ընդլայնման համար (այն այնտեղ անհրաժեշտ չէ), սահմանել զանգի ավարտի ժամանակը, հաշվարկել տևողությունը, եթե զանգի արդյունքը հայտնի չէ, սահմանել (փոփոխական CallMeDISPOSITION) և, վերջին քայլը, ուղարկեք ամեն ինչ Bitrix-ին համակարգի curl-ի միջոցով:

Եվ մի փոքր ավելի շատ կախարդություն՝ մուտքային զանգ.

888999 => {
	&recording(${CALLERID(number)},${EXTEN});
        Answer();
        ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp()); // выставляем CallerID если узнали его у Битрикс24
        Set(CallStart=${STRFTIME(epoch,,%s)}); // начинаем отсчет времени звонка
        Queue(Q1,tT);
        Set(CallMeDISPOSITION=${CDR(disposition)}); 
        Hangup();
        }

Այստեղ մեզ միայն մեկ տող է հետաքրքրում.

ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp());

Նա ասում է PBX-ին տեղադրել Զանգողի ID (անուն) հավասար է փոփոխականին CallMeCallerIDName.

CallMeCallerIDName փոփոխականն ինքնին, իր հերթին, սահմանվում է CallMe հավելվածի կողմից (եթե Bitrix24-ն ունի զանգողի համարի լրիվ անվանումը, սահմանեք այն որպես Զանգողի ID (անուն), ոչ, մենք ոչինչ չենք անի):

Հավելվածի կարգավորում

Հավելվածի կարգավորումների ֆայլ - /var/www/pbx.vistep.ru/config.php

Դիմումի պարամետրերի նկարագրությունը.

  • CallMeDEBUG — եթե 1, ապա հավելվածի կողմից մշակված բոլոր իրադարձությունները կգրվեն log ֆայլում, 0 — մենք ոչինչ չենք գրում
  • tech - SIP / PJSIP / IAX / և այլն
  • authToken — Bitrix24 թույլտվության նշան, ելքային webhook-ի թույլտվության կոդը
  • bitrixApiUrl — մուտքային վեբ-կապիկի URL, առանց պրոֆիլի/
  • ընդարձակումներ - արտաքին համարների ցանկ
  • կոնտեքստ — զանգ առաջացնելու համատեքստ
  • listener_timeout — Իրադարձությունների մշակման արագությունը աստղանիշից
  • աստղանիշ — աստղանիշին միանալու կարգավորումներով զանգված.
  • հյուրընկալող — Աստղանիշ սերվերի ip կամ հոսթի անունը
  • սխեմա - կապի դիագրամ (tcp://, tls://)
  • նավահանգիստ - նավահանգիստ
  • օգտագործողի անունը - Օգտագործողի անունը
  • գաղտնիք - գաղտնաբառը
  • connect_timeout - կապի ժամանակի ավարտ
  • read_timeout - կարդալ ժամանակի ընդմիջում

պարամետրերի ֆայլի օրինակ.

 <?php
return array(

        'CallMeDEBUG' => 1, // дебаг сообщения в логе: 1 - пишем, 0 - не пишем
        'tech' => 'SIP',
        'authToken' => 'xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6', //токен авторизации битрикса
        'bitrixApiUrl' => 'https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/', //url к api битрикса (входящий вебхук)
        'extentions' => array('888999'), // список внешних номеров, через запятую
        'context' => 'dial_out', //исходящий контекст для оригинации звонка
        'asterisk' => array( // настройки для подключения к астериску
                    'host' => '10.100.111.249',
                    'scheme' => 'tcp://',
                    'port' => 5038,
                    'username' => 'callme',
                    'secret' => 'JD3clEB8_f23r-3ry84gJ',
                    'connect_timeout' => 10000,
                    'read_timeout' => 10000
                ),
        'listener_timeout' => 300, //скорость обработки событий от asterisk

);

Վերահսկիչի կարգավորում

Supervisor-ն օգտագործվում է Asterisk CallMeIn.php-ից իրադարձությունների մշակման գործընթացը գործարկելու համար, որը վերահսկում է մուտքային զանգերը և փոխազդում Bitrix24-ի հետ (ցույց տալ քարտը, թաքցնել քարտը և այլն):

Կարգավորումների ֆայլը, որը պետք է ստեղծվի.

/etc/supervisord.d/callme.conf

[program:callme]
command=/usr/bin/php CallMeIn.php
directory=/var/www/pbx.vistep.ru
autostart=true
autorestart=true
startretries=5
stderr_logfile=/var/www/pbx.vistep.ru/logs/daemon.log
stdout_logfile=/var/www/pbx.vistep.ru/logs/daemon.log

Գործարկեք և վերագործարկեք հավելվածը.

supervisorctl start callme
supervisorctl restart callme

Դիտելով հավելվածի գործառնական կարգավիճակը.

supervisorctl status callme
callme                           RUNNING   pid 11729, uptime 17 days, 16:58:07

Ամփոփում

Բավականին բարդ է ստացվել, բայց վստահ եմ, որ փորձառու ադմինիստրատորը կկարողանա այն իրականացնել և գոհացնել իր օգտատերերին։

Ինչպես խոստացել էի, հղում github-ին.

Հարցեր, առաջարկություններ - խնդրում ենք թողնել դրանք մեկնաբանություններում: Բացի այդ, եթե ձեզ հետաքրքրում է, թե ինչպես է ընթացել այս ինտեգրման զարգացումը, գրեք, իսկ հաջորդ հոդվածում ես կփորձեմ ամեն ինչ ավելի մանրամասն բացահայտել։

Source: www.habr.com

Добавить комментарий