Integriĝo de Asterisk kaj Bitrix24

Integriĝo de Asterisk kaj Bitrix24
Estas malsamaj ebloj por integri IP-PBX Asterisk kaj CRM Bitrix24 en la reto, sed ni tamen decidis skribi nian propran.

Koncerne funkciecon, ĉio estas norma:

  • Alklakante ligilon kun la telefonnumero de kliento en Bitrix24, Asterisk ligas la internan nombron de la uzanto, pro kies nomo la klako estis farita kun la telefonnumero de la kliento. En Bitrix24, registro de la voko estas registrita kaj, ĉe la fino de la voko, registrado de la konversacio estas tirita supren.
  • Asterisk ricevas vokon de ekstere - en la interfaco Bitrix24 ni montras la klientkarton al la dungito, al kies numero ĉi tiu alvoko alvenis.
    Se ne ekzistas tia kliento, ni malfermos la karton por krei novan plumbon.
    Tuj kiam la voko estas finita, ni reflektas tion sur la karto kaj eltiras registradon de la konversacio.

Sub la tranĉo mi rakontos al vi kiel agordi ĉion por vi mem kaj donos al vi ligilon al github - jes, jes, prenu ĝin kaj uzu ĝin!

Ĝenerala priskribo

Ni nomis nian integriĝon CallMe. CallMe estas malgranda retejo-aplikaĵo skribita en PHP.

Teknologioj kaj servoj uzataj

  • PHP 5.6
  • PHP AMI-biblioteko
  • komponisto
  • Nginx + php-fpm
  • kontrolisto
  • AMI (Asterisk Manager Interface)
  • Bitrix-rethokoj (simpligita REST API-efektivigo)

Antaŭ-agordo

Sur servilo kun Asterisk, vi devas instali retservilon (por ni ĝi estas nginx+php-fpm), kontrolisto kaj git.

Instala komando (CentOS):

yum install nginx php-fpm supervisor git

Ni iras al la dosierujo alirebla al la retservilo, eltiras la aplikaĵon el Git kaj starigas la necesajn rajtojn al la dosierujo:


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

Poste, ni agordu nginx, nia agordo troviĝas en

/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;
		}
}

Mi forlasos analizi la agordojn, sekurecajn problemojn, akiri atestilon kaj eĉ elekti retservilon ekster la amplekso de la artikolo - multe estas skribita pri tio. La aplikaĵo ne havas limigojn, ĝi funkcias ambaŭ per http kaj https.

Ni uzas https, ni ĉifri atestilon.

Se vi faris ĉion ĝuste, tiam alklakante la ligilon vi devus vidi ion tian

Integriĝo de Asterisk kaj Bitrix24

Agordo de Bitrix24

Ni kreu du rethokojn.

Envenanta rethoko.

Sub la konto de administranto (kun id 1), sekvu la vojon: Aplikoj -> Rethooks -> Aldoni rethook -> Envenanta rethoko

Integriĝo de Asterisk kaj Bitrix24

Plenigu la parametrojn de la envenanta rethoko kiel en la ekrankopioj:

Integriĝo de Asterisk kaj Bitrix24

Integriĝo de Asterisk kaj Bitrix24

Kaj alklaku konservi.

Post konservado, Bitrix24 provizos la URL de la envenanta rethoko, ekzemple:

Integriĝo de Asterisk kaj Bitrix24

Konservu vian version de la URL sen la fina /profile/ - ĝi estos uzata en la aplikaĵo por labori kun envenantaj vokoj.

Mi havas ĉi tion https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/

Eksiĝinta rethoko.

Aplikoj -> Webhooks -> Aldoni rethook -> Eksiĝinta rethook

Detaloj estas denove sur la ekrankopioj:

Integriĝo de Asterisk kaj Bitrix24

Integriĝo de Asterisk kaj Bitrix24

Konservu kaj ricevu la rajtigan kodon

Integriĝo de Asterisk kaj Bitrix24

Mi havas ĉi tion xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6. Vi ankaŭ devas kopii ĝin por vi mem; vi bezonas ĝin por fari eksiĝintajn vokojn.

Grava!

SSL-atestilo devas esti agordita sur la servilo Bitrix24 (vi povas uzi letsencrypt), alie la Bitrix-api ne funkcios. Se vi havas nuban version, ne maltrankviliĝu - ĝi jam havas ssl.

Grava!

La kampo "Procesoro-Adreso" devas enhavi adreson alireblan de la Interreto!

Kaj kiel fina tuŝo, ni instalu nian CallMeOut kiel aplikaĵon por fari vokojn (por ke kiam vi alklakas la numeron sur la PBX, la komando por estigi la vokon forflugos).

En la menuo, elektu: Pli -> Telefonio -> Pli -> Agordoj, agordu en "Defaŭlta eksiĝinta alvoko" Apliko: CallMeOut kaj alklaku "Konservi"

Integriĝo de Asterisk kaj Bitrix24

Agordi asteriskon

Por sukcesa interago inter Asterisk kaj Bitrix24, ni devas aldoni la AMI-uzanto callme al 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

Poste, estas pluraj lertaĵoj, kiuj devos esti efektivigitaj per dialplano (por ni ĉi tio estas extensions.ael).

Mi provizos la tutan dosieron, kaj poste mi donos klarigon:

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});
}

};

Ni komencu de la komenco: la direktivo globoj.

Variablo URLRECORDS konservas la URL al la konversaciaj registraddosieroj, laŭ kiu Bitrix24 tiros ilin en la kontaktkarton.

Poste ni interesiĝas pri la makroo registradon.

Ĉi tie, krom registri konversaciojn, ni starigos la variablon PlenaFnomo.

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

Ĝi stokas la plenan URL al specifa dosiero (la makroo estas nomita ĉie).

Ni analizu la eksiĝintan vokon:

_. => {
	&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});
}

Ni diru, ke ni vokas 89991234567, unue ni venas ĉi tien:

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

tiuj. La konversacia registra makroo estas vokita kaj la necesaj variabloj estas fiksitaj.

plia

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

Ni registras kiu iniciatis la vokon kaj registras la komencotempon de la voko.

Kaj post ĝia kompletigo, en speciala kunteksto 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});
}

malŝaltu eniron al la CDR-tabelo por ĉi tiu etendo (ĝi tie ne necesas), agordu la fintempon de la voko, kalkulu la daŭron, se la rezulto de la voko ne estas konata - agordu (variablon). CallMeDISPOSITION) kaj, la lasta paŝo, sendu ĉion al Bitrix per la sistema buklo.

Kaj iom pli da magio - alvenanta voko:

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();
        }

Ĉi tie ni nur interesiĝas pri unu linio.

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

Ŝi rakontas al la PBX instali Alvokanto(nomo) egala al variablo CallMeCallerIDName.

La variablo CallMeCallerIDName mem, siavice, estas agordita de la aplikaĵo CallMe (se Bitrix24 havas plenan nomon por la numero de la alvokanto, agordu ĝin kiel Alvokanto(nomo), ne - ni faros nenion).

Agordo de aplikaĵo

Dosiero de agordoj de aplikaĵo - /var/www/pbx.vistep.ru/config.php

Priskribo de aplikaj parametroj:

  • VokuMeDEBUG — se 1, tiam ĉiuj eventoj procesitaj de la aplikaĵo estos skribitaj al la protokoldosiero, 0 — ni skribas nenion
  • teknologio - SIP/PJSIP/IAX/ktp
  • aŭthToken — Bitrix24-rajtigo-ĵetono, eksiĝinta rethook-rajtigokodo
  • bitrixApiUrl — URL de la envenanta rethoko, sen profilo/
  • etendaĵoj — listo de eksteraj nombroj
  • kunteksto — kunteksto por estigi vokon
  • listener_timeout — rapideco de evento-traktado de asterisko
  • asterisko — tabelo kun agordoj por konekti al la asterisko:
  • gastiganto — ip aŭ gastiga nomo de la asteriskservilo
  • skemo — konektodiagramo (tcp://, tls://)
  • haveno - haveno
  • uzantonomo - Uzantnomo
  • sekreta - Pasvorto
  • connect_timeout — konektotempo
  • read_timeout - legu timeout

ekzempla agorda dosiero:

 <?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

);

Kontrolisto aranĝo

Kontrolisto estas uzata por lanĉi la eventan prizorgan procezon de Asterisk CallMeIn.php, kiu kontrolas envenantajn vokojn kaj interagas kun Bitrix24 (montri karton, kaŝi karton, ktp.).

Agorda dosiero kreota:

/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

Lanĉu kaj rekomencu la aplikaĵon:

supervisorctl start callme
supervisorctl restart callme

Vidante la funkcian staton de la aplikaĵo:

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

konkludo

Ĝi montriĝis sufiĉe komplika, sed mi certas, ke sperta administranto povos efektivigi ĝin kaj plaĉi al siaj uzantoj.

Kiel promesite, ligo al github.

Demandoj, sugestoj - bonvolu lasi ilin en la komentoj. Ankaŭ, se vi interesiĝas pri kiel iris la disvolviĝo de ĉi tiu integriĝo, skribu, kaj en la sekva artikolo mi provos malkaŝi ĉion pli detale.

fonto: www.habr.com

Aldoni komenton