Asterisk és Bitrix24 integráció

Asterisk és Bitrix24 integráció
Az interneten különböző lehetőségek vannak az IP-ATC Asterisk és a Bitrix24 CRM integrálására, de mi végül úgy döntöttünk, hogy megírjuk a sajátunkat.

A funkciók mind standard módon működnek:

  • A Bitrix24-ben a kliens telefonos számának linkjére kattintva az Asterisk összeköti a felhasználó belső számát, akinek nevében a kattintás történt, a kliens telefonszámával. A Bitrix24-ben rögzítjük a hívás jegyzetét, és a hívás befejezése után megjelenik a beszélgetés felvétele.
  • Az Asteriskhez bejövő hívás érkezik – a Bitrix24 felületén megmutatjuk az ügyfél kártyáját annak a munkatársnak, akinek a számára a hívás érkezett.
    Ha az ügyfél nem létezik, megnyitjuk az új lead létrehozására szolgáló kártyát.
    Amint a hívás befejeződik, ezt tükrözzük a kártyán, és lekérjük a beszélgetés felvételét.

A bejegyzés alatt elmondom, hogyan állítsd be magadnak, és adok egy linket a github-hoz – igen, vidd és használd!

Általános leírás

A saját integrációnkat CallMe-nek neveztük. A CallMe egy kis webalkalmazás, amit PHP-ben írtunk.

Használt technológiák és szolgáltatások

  • PHP 5.6
  • PHP AMI könyvtár
  • Composer
  • Nginx + php-fpm
  • supervisor
  • AMI (Asterisk Manager Interface)
  • Bitrix webhookok (egyszerűsített REST API megvalósítás)

Előkészítő beállítás

Az Asterisken futó szerveren webkiszolgálót kell telepíteni (nálunk ez nginx+php-fpm), supervisort és git-et.

A telepítési parancs (CentOS):

yum install nginx php-fpm supervisor git

Lépjünk a webkiszolgáló által elérhető könyvtárba, húzzuk le a gitből az alkalmazást, és állítsuk be a szükséges jogosultságokat a mappára:


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

Ezután beállítjuk a nginx-et, a konfigurációnk itt található:

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

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

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


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

    listen 443 ssl http2;
    server_name pbx.vistep.hu;
    resolver 8.8.8.8;
    ssl_stapling on;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/pbx.vistep.hu/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/pbx.vistep.hu/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; # tiltott fájlok
        }

        location ~* /(?:uploads|files)/.*.php$ {
                deny all; # tiltott feltöltött szkriptek
        }

        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; # statikus adat cache
        }

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

A konfiguráció elemzése, a biztonsági kérdések, a tanúsítvány beszerzése és még a webszerver választása is túlmutat ezen a cikken - erről sokat írtak már. Az alkalmazásnak nincsenek korlátozásai, http és https alatt is működik.

Nálunk https van, let’s encrypt tanúsítvánnyal.

Ha mindent helyesen csináltál, akkor a linkre kattintva ilyesmit kellene látnod:

Asterisk és Bitrix24 integráció

Bitrix24 beállítása

Két webhookot fogunk létrehozni.

Bejövő webhook.

Adminisztrátori fiók alatt (id 1) navigálj az alábbi úton: Alkalmazások -> Webhookok -> Webhook hozzáadása -> Bejövő webhook

Asterisk és Bitrix24 integráció

Töltsd ki a bejövő webhook paramétereit a képernyőképek alapján:

Asterisk és Bitrix24 integráció

Asterisk és Bitrix24 integráció

És kattints a mentésre.

A mentés után a Bitrix24 egy URL-t biztosít a bejövő webhookhoz, például:

Asterisk és Bitrix24 integráció

Mentsd el a saját URL-edet befejező /profile/ nélkül - ezt fogod használni az alkalmazásban a bejövő hívások kezelésére.

Ez nálam: https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/

Kimenő webhook.

Alkalmazások -> Webhookok -> Webhook hozzáadása -> Kimenő webhook

Részletek újra a képernyőképeken:

Asterisk és Bitrix24 integráció

Asterisk és Bitrix24 integráció

Mentjük, és megkapjuk az engedélyezési kódot.

Asterisk és Bitrix24 integráció

Ez nálam: xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6. Ezt is másold el, mert szükséged lesz rá a kimenő hívások lebonyolításához.

Fontos!

A Bitrix24 szerveren SSL-tanúsítványt kell beállítani (használhatja a letsencrypt-et), különben a Bitrix API nem fog működni. Ha Ön felhőalapú verziót használ, nem kell aggódnia – ott már van SSL.

Fontos!

A «Kezelési cím» mezőben egy az internetről elérhető címet kell megadni!

Végül telepítjük a CallMeOut-ot, mint alkalmazást a hívások lebonyolításához (hogy a számra kattintva a PBX-en parancs kerüljön a hívás kezdeményezésére).

A menüben válasszuk: Továbbiak -> Telefonálás -> Továbbiak -> Beállítások, és állítsuk be az «Alapértelmezett hívószám» mezőben az Alkalmazás: CallMeOut értéket, majd kattintsunk a «Mentés» gombra.

Asterisk és Bitrix24 integráció

Asterisk beállítása

A sikeres Asterisk és Bitrix24 közötti interakció érdekében hozzá kell adnunk az AMI-felhasználót a manager.conf fájlhoz:

[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

Továbbá van néhány trükk, amelyet a dialplanon keresztül kell megvalósítani (nálunk ez az extensions.ael).

Az egész fájlt megadom, majd utána magyarázatokat adok:

globals {
    WAV=\/var\/www\/pbx.vistep.ru\/callme\/records\/wav; \/\/Ideiglenes mappa WAV fájlokhoz
    MP3=\/var\/www\/pbx.vistep.ru\/callme\/records\/mp3; \/\/Ahol az mp3 fájlokat tároljuk
    URLRECORDS=https:\/\/pbx.vistep.ru\/callme\/records\/mp3;
    RECORDING=1; \/\/ Felvétel, 1 - bekapcsolva.
};

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()); \/\/ Beállítjuk a CallerID-t, ha a Bitrix24-ből megismertük
        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(=== A CallMeDISPOSITION már be volt állítva ===));  
}

}


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=${STRFTTIME(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});
}

};

Kezdjük az elején: utasítás globals.

Változó URLRECORDS tárolja a beszélgetések rögzítési fájljainak URL-jét, melyet a Bitrix24 fog használni a névjegykártya frissítésére.

Ezután a makróra vagyunk kíváncsiak recording.

Itt, a beszélgetések rögzítése mellett beállítunk egy változót FullFname.

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

Ez tárolja az adott fájl teljes URL-jét (a makró mindenhol hívva van).

Nézzük az kimenő hívást:

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

Tegyük fel, hogy a 89991234567 számra telefonálunk, először erre a helyre kerülünk:

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

azaz a beszélgetés rögzítésére szolgáló makró hívódik meg, és a szükséges változók beállításra kerülnek.

Ezután

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

rögzítjük, ki indította a hívást és rögzítjük a hívás kezdeti időpontját.

És a befejezése után, egy külön kontextusban 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});
}

letiltjuk a CDR táblába való rögzítést ennél az extendernél (nincs szükség rá ott), beállítjuk a hívás befejezési időpontját, kiszámítjuk a hívás időtartamát, ha a hívás eredménye ismeretlen — beállítjuk (változó CallMeDISPOSITION) és utolsó lépésként eljuttatjuk mindent a Bitrix-nek egy rendszeres curl híváson keresztül.

És még egy kis varázslat — a bejövő hívás:

888999 => {
	&recording(${CALLERID(number)},${EXTEN});
        Answer();
        ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp()); // beállítjuk a CallerID-t, ha tudtuk a Bitrix24-ből
        Set(CallStart=${STRFTIME(epoch,,%s)}); // elkezdjük a hívás idejének számítását
        Queue(Q1,tT);
        Set(CallMeDISPOSITION=${CDR(disposition)}); 
        Hangup();
        }

Itt csak egy sorra vagyunk kíváncsiak.

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

Ez azt mondja az ATEGRÁCIÓNAK, hogy állítsa be a CallerID(name) egyenlőnek a változóval CallMeCallerIDName.

A CallMeCallerIDName változót pedig a CallMe alkalmazás állítja be (ha van név a Bitrix24 rendszerben a hívó számhoz — beállítjuk azt CallerID(name), ha nincs — nem csinálunk semmit).

Alkalmazás beállítása

Az alkalmazás beállítási fájlja — /var/www/pbx.vistep.ru/config.php

Az alkalmazás paramétereinek leírása:

  • CallMeDEBUG — ha 1, akkor a naplófájlba minden esemény rögzítésre kerül, amelyet az alkalmazás kezel, 0 — semmit sem írunk.
  • tech — SIP/PJSIP/IAX/etc
  • authToken — Bitrix24 hitelesítési token, a kimenő webhook hitelesítési kódja
  • bitrixApiUrl — Bejövő webhook URL, profile nélkül
  • extenziók — Külső számok listája
  • context — Híváskezdeményezés kontextusa
  • listener_timeout — Az események feldolgozásának sebessége az Asterisk-től
  • asterisk — Asterisk-hez való csatlakozási beállítások tömbje:
  • host — Asterisk szerver IP-je vagy hosztneve
  • séma — Csatlakozási séma (tcp://, tls://)
  • port — Port
  • username — Felhasználónév
  • secret — Jelszó
  • connect_timeout — Kapcsolódási időkorlát
  • read_timeout — Olvasási időkorlát

példa a beállítási fájlra:

 <?php
return array(

        'CallMeDEBUG' => 1, // hibakeresési üzenetek a naplóban: 1 - írunk, 0 - nem írunk
        'tech' => 'SIP',
        'authToken' => 'xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6', // bitrix hitelesítési token
        'bitrixApiUrl' => 'https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/', // bitrix API url (bejövő webhook)
        'extenziók' => array('888999'), // külső számok listája, vesszővel elválasztva
        'context' => 'dial_out', // kimenő kontextus a hívás kezdeményezéséhez
        'asterisk' => array( // Asterisk-hez való csatlakozási beállítások
                    'host' => '10.100.111.249',
                    'scheme' => 'tcp://',
                    'port' => 5038,
                    'username' => 'callme',
                    'secret' => 'JD3clEB8_f23r-3ry84gJ',
                    'connect_timeout' => 10000,
                    'read_timeout' => 10000
                ),
        'listener_timeout' => 300, // Az Asterisk-től származó események feldolgozásának sebessége

);

Supervisor beállítása

A Supervisor felelős az Asterisk CallMeIn.php eseménykezelő folyamatának elindításáért, amely figyelemmel kíséri a bejövő hívásokat és interakcióba lép a Bitrix24-tel (kártya megjelenítése, kártya elrejtése stb.).

A létrehozandó beállítási fájl:

/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

Alkalmazás elindítása és újraindítása:

supervisorctl start callme
supervisorctl restart callme

Az alkalmazás működésének állapotának megtekintése:

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

Zárás

Elég bonyolult lett, de biztos vagyok benne, hogy egy tapasztalt rendszergazda sikeresen be tudja vezetni és örömet szerezni felhasználóinak.

Ahogy ígértem, link a GitHub-on.

Kérdések, javaslatok — kérem a hozzászólásokban. Ha érdekli a fejlesztés folyamata ennek az integrációnak, írja meg, a következő cikkemben megpróbálom részletesebben bemutatni.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster