Asterisk un Bitrix24 integrācija

Asterisk un Bitrix24 integrācija
Tīklā ir dažādi IP-ATC Asterisk un CRM Bitrix24 integrācijas varianti, tomēr mēs tomēr esam nolēmuši izveidot savu.

Funkcionalitāte ir standarta:

  • Cilvēks klikšķinot uz klienta telefona numura saites Bitrix24, Asterisk savieno iekšējo lietotāja numuru, kura vārdā tas tika klikšķināts, ar klienta telefona numuru. Bitrix24 pieraksta zvana ierakstu, un pēc zvana beigām tiek pievienots sarunas ieraksts.
  • Asterisk saņem zvanu no ārpuses — Bitrix24 interfeisā rādām klienta karti tam darbiniekam, uz kura numuru šis zvans ieradās.
    Ja tāda klienta nav, atvērsim jauna lead izveides karti.
    Kad zvans ir pabeigts, atspoguļojam to kartē un pievienojam sarunas ierakstu.

Zemāk pastāstīšu, kā to visu noregulēt sev un sniegšu saiti uz GitHub — jā, jā, ņemiet un lietojiet!

Vispārīgs apraksts

Mūsu integrāciju mēs nosaucu CallMe. CallMe ir neliela tīmekļa lietojumprogramma, kas uzrakstīta PHP.

Izmantotās tehnoloģijas un pakalpojumi

  • PHP 5.6
  • PHP AMI bibliotēka
  • Composer
  • Nginx + php-fpm
  • supervisor
  • AMI (Asterisk Manager Interface)
  • Bitrix Webhook (vienkāršota REST API īstenošana)

Iepriekšējā konfigurācija

Uz servera ar Asterisk ir jāinstalē tīmekļa serveris (mums tas ir nginx + php-fpm), supervisor un git.

Komanda instalēšanai (CentOS):

yum install nginx php-fpm supervisor git

Pārejam uz direktoriju, kas pieejama tīmekļa serverim, no Git ņemam lietojumprogrammu un piešķiram vajadzīgās tiesības mapē:


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

Tālāk noregulēsim nginx, mūsu konfigurācija ir novietota

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

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

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


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

    listen 443 ssl http2;
    server_name pbx.vistep.lv;
    resolver 8.8.8.8;
    ssl_stapling on;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/pbx.vistep.lv/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/pbx.vistep.lv/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; # lieguma noteikumi slēptajiem failiem
        }

        location ~* /(?:uploads|files)/.*.php$ {
                deny all; # lieguma noteikumi augšupielādētām skriptām
        }

        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; # statikas kešēšana
        }

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

Configuraācijas analīze, drošības jautājumi, sertifikāta iegūšana un pat izvēle starp web serveriem paliks ārpus raksta — par to ir daudz rakstīts. Lietojumprogrammai nav ierobežojumu, tā darbojas gan HTTP, gan HTTPS.

Mums ir HTTPS, sertifikāts Let's Encrypt.

Ja viss izdarīts pareizi, tad, pārejot uz saiti, jums jāredz kaut kas līdzīgs

Asterisk un Bitrix24 integrācija

Bitrix24 konfigurācija

Izveidosim divus webhookus.

Ienākošais webhook.

Ar administratora kontu (ar id 1) dodies pa ceļu: Lietojumprogrammas -> Webhooki -> Pievienot webhook -> Ienākošais webhook

Asterisk un Bitrix24 integrācija

Aizpildām ienākošā webhook parametrus kā attēlos:

Asterisk un Bitrix24 integrācija

Asterisk un Bitrix24 integrācija

Un nospiežam saglabot.

Pēc saglabāšanas Bitrix24 sniegs ienākošā webhook URL, piemēram:

Asterisk un Bitrix24 integrācija

Saglabājiet savu variantu URL bez beigu /profile/ — tas tiks izmantots lietojumprogrammā, lai strādātu ar ienākošajiem zvaniem.

Man tas ir https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/

Izejošais webhook.

Lietojumprogrammas -> Webhooki -> Pievienot webhook -> Izejošais webhook

Sīkāka informācija atkal attēlos:

Asterisk un Bitrix24 integrācija

Asterisk un Bitrix24 integrācija

Saglabājam un saņemam autorizācijas kodu

Asterisk un Bitrix24 integrācija

Man tas ir xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6. To arī jākopē, tas būs nepieciešams, lai veiktu izejošos zvanus.

Svarīgi!

Bitrix24 server must have an SSL certificate configured (Let's Encrypt can be used), otherwise the Bitrix API will not function. If you have a cloud version, you don’t need to worry — it already has SSL.

Svarīgi!

In the 'Handler Address' field, you must specify an address that is accessible from the Internet!

Finally, we will set up our CallMeOut as an application for making calls (so that when clicking on the number, a command is sent to the PBX to initiate a call).

In the menu, select: More -> Telephony -> More -> Settings, set 'Default Outgoing Call Number' Application: CallMeOut and click 'Save'

Asterisk un Bitrix24 integrācija

Setting up Asterisk

For successful interaction between Asterisk and Bitrix24, we need to add the AMI user callme to 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

Next, there are a few tricks that need to be implemented through the dialplan (in our case, it is extensions.ael).

I’m providing the entire file, and afterwards, I will give explanations:

globals {
    WAV=\/var\/www\/pbx.vistep.lv\/callme\/records\/wav; \/\/Laika katalogs WAV
    MP3=\/var\/www\/pbx.vistep.lv\/callme\/records\/mp3; \/\/Kur izvietot mp3 failus
    URLRECORDS=https:\/\/pbx.vistep.lv\/callme\/records\/mp3;
    RECORDING=1; \/\/ Ieraksts, 1 - ieslēgts.
};

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()); \/\/ iestatām CallerID, ja to uzzinājām no Bitrix24
        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 jau bija iestatīts ===));  
}

}


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.lv\/CallMeOut.php --data action=sendcall2b24 --data call_id=${CallMeCALL_ID} --data-urlencode FullFname=${FullFname} --data CallIntNum=${CallIntNum} --data CallDuration=${CallMeDURATION} --data-urlencode CallDisposition=${CallMeDISPOSITION});
}

};

Sāksim no sākuma: direktīva globals.

Mainīgais URLRECORDS satur URL uz sarunu ierakstu failiem, pa kuru Bitrix24 tās piekļūs kontaktu kartītē.

Tālāk mūs interesē makro recording.

Šeit, papildus sarunu ierakstīšanai, mēs iestatīsim mainīgo FullFname.

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

Tā satur pilnu URL uz konkrēto failu (makro tiek izsaukts visur).

Izskatīsim izejošo zvanu:

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

Pieņemot, ka zvanām uz 89991234567, vispirms nonākam šeit:

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

t.i., tiek izsaukts sarunas ieraksta makro un noteiktas nepieciešamās mainīgās vērtības.

Tālāk

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

ierakstām, kurš iniciēja zvanu, un fiksējam zvana sākuma laiku.

Un pēc tā pabeigšanas, īpašā kontekstā 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});
}

izslēdzam ierakstu CDR tabulā šim iekšējam numuram (nav nepieciešams), nosakām zvana pabeigšanas laiku, aprēķinām ilgumu, ja zvana rezultāts nav zināms — iestata (mainīgā CallMeDISPOSITION) un, pēdējais solis, nosūtām visu uz Bitrix ar sistēmas curl.

Un vēl nedaudz burvības — ienākošais zvans:

888999 => {
	&recording(${CALLERID(number)},${EXTEN});
        Answer();
        ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp()); // nosakām CallerID, ja to zinām no Bitrix24
        Set(CallStart=${STRFTIME(epoch,,%s)}); // sākam zvana laika uzskaiti
        Queue(Q1,tT);
        Set(CallMeDISPOSITION=${CDR(disposition)}); 
        Hangup();
        }

Šeit mūs interesē tikai viena rinda.

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

Tā norāda ATE, lai iestatītu CallerID(name) vienādu ar mainīgo CallMeCallerIDName.

Pašā mainīgajā CallMeCallerIDName, savukārt, iestata lietojumprogramma CallMe (ja Bitrix24 ir FIO zvanītāja numuram — iestādīsim kā CallerID(name), nē — neko nedarīsim).

Lietojumprogrammas iestatījumi

Lietojumprogrammas iestatījumu fails — /var/www/pbx.vistep.ru/config.php

Lietojumprogrammas parametru apraksts:

  • CallMeDEBUG — ja 1, tad žurnālfailā tiks ierakstīti visi notikumi, ko apstrādā lietojumprogramma, 0 — neko neierakstām
  • tech — SIP/PJSIP/IAX/utt.
  • authToken — Bitrix24 autentifikācijas tokens, izejoša webhook autorizācijas kods
  • bitrixApiUrl — ienākošā webhook URL, bez profile/
  • extentions — ārējo numuru saraksts
  • context — konteksts zvanīšanai
  • listener_timeout — notikumu apstrādes ātrums no Asterisk
  • asterisk — masīvs ar savienojuma iestatījumiem uz Asterisk:
  • host — Asterisk servera IP vai hostname
  • scheme — savienojuma shēma (tcp://, tls://)
  • port — ports
  • username — lietotājvārds
  • secret — parole
  • connect_timeout — savienojuma laika ierobežojums
  • read_timeout — lasīšanas laika ierobežojums

iestatījumu faila piemērs:

 1, // žurnāla debug ziņojumi: 1 - rakstīt, 0 - nerakstīt
        'tech' => 'SIP',
        'authToken' => 'xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6', // Bitrix autentifikācijas tokens
        'bitrixApiUrl' => 'https://b24-xsynia.bitrix24.lv/rest/1/7eh61lh8pahw0fwt/', // url uz Bitrix API (ienākošā webhook)
        'extentions' => array('888999'), // ārējo numuru saraksts, atdalīts ar komatiem
        'context' => 'dial_out', // izejošā konteksts zvanīšanai
        'asterisk' => array( // iestatījumi savienojumam ar Asterisk
                    'host' => '10.100.111.249',
                    'scheme' => 'tcp://',
                    'port' => 5038,
                    'username' => 'callme',
                    'secret' => 'JD3clEB8_f23r-3ry84gJ',
                    'connect_timeout' => 10000,
                    'read_timeout' => 10000
                ),
        'listener_timeout' => 300, // notikumu apstrādes ātrums no Asterisk

);

Supervisor konfigurācija

Supervisor tiek izmantots, lai palaistu notikumu apstrādātāju Asterisk CallMeIn.php, kas uzrauga ienākošos zvanus un mijiedarbojas ar Bitrix24 (parāda karti, slēpj karti utt.).

Konfigurācijas fails, kuru nepieciešams izveidot:

/etc/supervisord.d/callme.conf

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

Lietojumprogrammas palaišana un restartēšana:

supervisorctl start callme
supervisorctl restart callme

lietojumprogrammas darba statusa pārbaude:

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

Secinājums

Tas izrādījās diezgan sarežģīti, bet esmu pārliecināts, ka pieredzējis administrators spēs to ieviest un iepriecināt savus lietotājus.

Kā solīts, saite uz GitHub.

Jautājumi, vēlmes — lūdzu, rakstiet komentāros. Ja interesē, kā noritēja šīs integrācijas izstrāde, rakstiet, un nākamajā rakstā es centīšos to aplūkot detalizētāk.

Avots: habr.com

Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem 🔥 Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem | ProHoster