Integrace Asterisk a Bitrix24

Integrace Asterisk a Bitrix24
Existují různé možnosti pro integraci IP-PBX Asterisk a CRM Bitrix24 do sítě, ale přesto jsme se rozhodli napsat vlastní.

Z hlediska funkčnosti je vše standardní:

  • Kliknutím na odkaz s telefonním číslem klienta v Bitrix24 Asterisk spojí interní číslo uživatele, jehož jménem bylo kliknutí provedeno, s telefonním číslem klienta. V Bitrix24 se nahrává záznam hovoru a na konci hovoru se vytáhne nahrávka konverzace.
  • Asterisk přijímá hovor zvenčí - v rozhraní Bitrix24 ukazujeme klientskou kartu pracovníkovi, na jehož číslo tento hovor dorazil.
    Pokud takový klient neexistuje, otevřeme kartu pro vytvoření nového potenciálního zákazníka.
    Jakmile je hovor dokončen, odrazíme to na kartě a vytáhneme záznam rozhovoru.

Pod střihem vám řeknu, jak si vše nastavit pro sebe, a dám vám odkaz na github – ano, ano, vezměte si to a používejte!

Obecný popis

Naši integraci jsme nazvali CallMe. CallMe je malá webová aplikace napsaná v PHP.

Použité technologie a služby

  • PHP 5.6
  • PHP knihovna AMI
  • Hudební Skladatel
  • Nginx + php-fpm
  • vedoucí
  • Rozhraní AMI (Asterisk Manager Interface)
  • Bitrix webhooky (zjednodušená implementace REST API)

Přednastavení

Na server s Asterisk je potřeba nainstalovat webový server (u nás je to nginx+php-fpm), supervizor a git.

Instalační příkaz (CentOS):

yum install nginx php-fpm supervisor git

Přejdeme do adresáře přístupného webovému serveru, stáhneme aplikaci z Gitu a nastavíme potřebná práva ke složce:


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

Dále nakonfigurujeme nginx, naše konfigurace se nachází v

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

Parsování konfigurace, bezpečnostní problémy, získání certifikátu a dokonce i výběr webového serveru ponechám mimo rámec článku - o tom bylo napsáno hodně. Aplikace nemá žádná omezení, funguje přes http i https.

Používáme https, zašifrujeme certifikát.

Pokud jste vše udělali správně, tak kliknutím na odkaz byste měli vidět něco takového

Integrace Asterisk a Bitrix24

Nastavení Bitrix24

Vytvoříme dva webhooky.

Příchozí webhook.

Pod účtem správce (s ID 1) postupujte podle cesty: Aplikace -> Webhooky -> Přidat webhook -> Příchozí webhook

Integrace Asterisk a Bitrix24

Vyplňte parametry příchozího webhooku jako na snímcích obrazovky:

Integrace Asterisk a Bitrix24

Integrace Asterisk a Bitrix24

A klikněte na uložit.

Po uložení Bitrix24 poskytne URL příchozího webhooku, například:

Integrace Asterisk a Bitrix24

Uložte si svou verzi URL bez koncového /profilu/ - bude v aplikaci použit pro práci s příchozími hovory.

mám to https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/

Odchozí webhook.

Aplikace -> Webhooky -> Přidat webhook -> Odchozí webhook

Podrobnosti jsou opět na screenshotech:

Integrace Asterisk a Bitrix24

Integrace Asterisk a Bitrix24

Uložte a přijměte autorizační kód

Integrace Asterisk a Bitrix24

mám to xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6. Také si jej musíte zkopírovat pro sebe, potřebujete jej pro odchozí hovory.

Důležité!

SSL certifikát musí být nakonfigurován na serveru Bitrix24 (můžete použít letsencrypt), jinak Bitrix api nebude fungovat. Pokud máte cloudovou verzi, nebojte se – ta již má ssl.

Důležité!

Pole „Adresa procesoru“ musí obsahovat adresu dostupnou z internetu!

A na závěr si nainstalujme náš CallMeOut jako aplikaci pro volání (aby po kliknutí na číslo na ústředně odletěl příkaz pro uskutečnění hovoru).

V nabídce vyberte: Více -> Telefonie -> Více -> Nastavení, nastavte v „Výchozí číslo odchozího hovoru“ Aplikace: CallMeOut a klikněte na „Uložit“

Integrace Asterisk a Bitrix24

Nastavení hvězdičky

Pro úspěšnou interakci mezi Asterisk a Bitrix24 musíme přidat callme uživatele AMI do 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

Dále je zde několik triků, které bude potřeba implementovat přes dialplan (pro nás je to extensions.ael).

Poskytnu celý soubor a poté podám vysvětlení:

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

};

Začněme od začátku: směrnice globály.

Proměnná URLRECORDS ukládá URL k souborům záznamu konverzace, podle kterých je Bitrix24 natáhne do kontaktní karty.

Dále nás zajímá makro makro záznam.

Zde kromě nahrávání konverzací nastavíme proměnnou FullFname.

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

Ukládá celou URL do konkrétního souboru (makro se volá všude).

Pojďme analyzovat odchozí hovor:

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

Řekněme, že zavoláme na číslo 89991234567, nejprve se dostaneme sem:

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

těch. Zavolá se makro nahrávání konverzace a nastaví se potřebné proměnné.

Další

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

Zaznamenáváme, kdo inicioval hovor, a zaznamenáváme čas zahájení hovoru.

A po jeho dokončení ve zvláštním kontextu 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});
}

zakázat vstup do CDR tabulky pro tuto pobočku (tam není potřeba), nastavit čas ukončení hovoru, vypočítat dobu trvání, pokud není znám výsledek hovoru - nastavit (proměnná Zavolejte MeDISPOSITION) a v posledním kroku vše odešlete do Bitrixu přes systémový curl.

A ještě trochu kouzla - příchozí hovor:

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

Zde nás zajímá pouze jeden řádek.

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

Řekne ústředně, aby instalovala ID volajícího (jméno) rovná se proměnné CallMeCallerIDName.

Samotná proměnná CallMeCallerIDName je zase nastavena aplikací CallMe (pokud má Bitrix24 celé jméno pro číslo volajícího, nastavte jej jako ID volajícího (jméno), ne – nic neuděláme).

Nastavení aplikace

Soubor nastavení aplikace - /var/www/pbx.vistep.ru/config.php

Popis parametrů aplikace:

  • Volejte MeDEBUG — pokud 1, pak všechny události zpracované aplikací budou zapsány do log souboru, 0 — nic nezapisujeme
  • tech - SIP/PJSIP/IAX/atd
  • authToken — Autorizační token Bitrix24, autorizační kód odchozího webhooku
  • bitrixApiUrl — URL příchozího webhooku, bez profilu/
  • rozšíření — seznam externích čísel
  • kontext — kontext pro zahájení hovoru
  • listener_timeout — rychlost zpracování události z hvězdičky
  • hvězdička — pole s nastavením pro připojení k hvězdičce:
  • hostitel — IP nebo název hostitele serveru s hvězdičkou
  • systém — schéma připojení (tcp://, tls://)
  • přístav - přístav
  • uživatelské jméno - Uživatelské jméno
  • tajný - Heslo
  • connect_timeout — časový limit připojení
  • read_timeout - časový limit čtení

příklad souboru nastavení:

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

);

Nastavení supervizora

Správce se používá ke spuštění procesu obsluhy událostí z Asterisk CallMeIn.php, který sleduje příchozí hovory a spolupracuje s Bitrix24 (zobrazit kartu, skrýt kartu atd.).

Soubor nastavení, který má být vytvořen:

/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

Spusťte a restartujte aplikaci:

supervisorctl start callme
supervisorctl restart callme

Zobrazení provozního stavu aplikace:

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

Závěr

Ukázalo se, že je to poměrně složité, ale jsem si jistý, že zkušený správce to zvládne a potěší své uživatele.

Jak slíbil, odkaz na github.

Dotazy, návrhy - zanechte je prosím v komentářích. Také pokud vás zajímá, jak probíhal vývoj této integrace, napište a v dalším článku se pokusím vše poodhalit podrobněji.

Zdroj: www.habr.com

Přidat komentář