Asterisk์™€ Bitrix24์˜ ํ†ตํ•ฉ

Asterisk์™€ Bitrix24์˜ ํ†ตํ•ฉ
๋„คํŠธ์›Œํฌ์—๋Š” IP-PBX Asterisk์™€ CRM Bitrix24๋ฅผ ํ†ตํ•ฉํ•˜๋Š” ๋‹ค์–‘ํ•œ ์˜ต์…˜์ด ์žˆ์ง€๋งŒ ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์šฐ๋ฆฌ๋Š” ์ง์ ‘ ์ž‘์„ฑํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋Šฅ์ ์œผ๋กœ ๋ชจ๋“  ๊ฒƒ์ด ํ‘œ์ค€์ž…๋‹ˆ๋‹ค.

  • Asterisk๋Š” Bitrix24์—์„œ ๊ณ ๊ฐ์˜ ์ „ํ™”๋ฒˆํ˜ธ๊ฐ€ ์žˆ๋Š” ๋งํฌ๋ฅผ ํด๋ฆญํ•˜์—ฌ ์ด ํด๋ฆญ์„ ๋Œ€์‹ ํ•œ ์‚ฌ์šฉ์ž์˜ ๋‚ด๋ถ€ ๋ฒˆํ˜ธ๋ฅผ ๊ณ ๊ฐ์˜ ์ „ํ™”๋ฒˆํ˜ธ์™€ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. Bitrix24์—๋Š” ํ†ตํ™” ๊ธฐ๋ก์ด ๊ธฐ๋ก๋˜์–ด ์žˆ์œผ๋ฉฐ ํ†ตํ™”๊ฐ€ ๋๋‚˜๋ฉด ๋Œ€ํ™” ๊ธฐ๋ก์ด ํ’€์—…๋ฉ๋‹ˆ๋‹ค.
  • ์™ธ๋ถ€์—์„œ Asterisk์— ์ „ํ™”๊ฐ€ ๋„์ฐฉํ•ฉ๋‹ˆ๋‹ค. Bitrix24 ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์ด ์ „ํ™”๊ฐ€ ๋„์ฐฉํ•œ ์ง์›์—๊ฒŒ ํด๋ผ์ด์–ธํŠธ ์นด๋“œ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
    ๊ทธ๋Ÿฌํ•œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—†์œผ๋ฉด ์ƒˆ ๋ฆฌ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์นด๋“œ๋ฅผ ์—ฝ๋‹ˆ๋‹ค.
    ํ†ตํ™”๊ฐ€ ์™„๋ฃŒ๋˜๋Š” ์ฆ‰์‹œ ์ด๋ฅผ ์นด๋“œ์— ๋ฐ˜์˜ํ•˜๊ณ  ๋Œ€ํ™”๋…น์Œ์„ ๋Œ์–ด์˜ฌ๋ฆฝ๋‹ˆ๋‹ค.

์ปท ์•„๋ž˜์—์„œ ๋ชจ๋“  ๊ฒƒ์„ ์ง์ ‘ ์„ค์ •ํ•˜๊ณ  github์— ๋Œ€ํ•œ ๋งํฌ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜ˆ, ์˜ˆ, ๊ฐ€์ ธ ์™€์„œ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค!

์ผ๋ฐ˜์ ์ธ ์„ค๋ช…

์šฐ๋ฆฌ๋Š” ํ†ตํ•ฉ CallMe๋ฅผ ํ˜ธ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค. CallMe๋Š” PHP๋กœ ์ž‘์„ฑ๋œ ์ž‘์€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋œ ๊ธฐ์ˆ  ๋ฐ ์„œ๋น„์Šค

  • PHP 5.6
  • PHP AMI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • ์ž‘๊ณก๊ฐ€
  • nginx + php fpm
  • ๊ฐ๋…์ž
  • AMI(๋ณ„ํ‘œ ๊ด€๋ฆฌ์ž ์ธํ„ฐํŽ˜์ด์Šค)
  • Bitrix ์›นํ›„ํฌ(๋‹จ์ˆœํ™”๋œ 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 -> Webhook -> Add webhook -> Incoming webhook

Asterisk์™€ Bitrix24์˜ ํ†ตํ•ฉ

์Šคํฌ๋ฆฐ์ƒท๊ณผ ๊ฐ™์ด ๋“ค์–ด์˜ค๋Š” Webhook์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

Asterisk์™€ Bitrix24์˜ ํ†ตํ•ฉ

Asterisk์™€ Bitrix24์˜ ํ†ตํ•ฉ

๊ทธ๋ฆฌ๊ณ  ์ €์žฅ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

์ €์žฅ ํ›„ Bitrix24๋Š” ๋“ค์–ด์˜ค๋Š” ์›นํ›„ํฌ์˜ URL์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Asterisk์™€ Bitrix24์˜ ํ†ตํ•ฉ

ํ›„ํ–‰ /profile/ ์—†์ด URL ๋ฒ„์ „์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด URL์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ˆ˜์‹  ์ „ํ™”๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๊ฐ€์ง€๊ณ ์žˆ๋‹ค https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/

๋ฐœ์‹  ์›นํ›….

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ -> Webhook -> Webhook ์ถ”๊ฐ€ -> ๋‚˜๊ฐ€๋Š” Webhook

์ž์„ธํ•œ ๋‚ด์šฉ์€ ์Šคํฌ๋ฆฐ์ƒท์— ์žˆ์Šต๋‹ˆ๋‹ค.

Asterisk์™€ Bitrix24์˜ ํ†ตํ•ฉ

Asterisk์™€ Bitrix24์˜ ํ†ตํ•ฉ

์ธ์ฆ ์ฝ”๋“œ ์ €์žฅ ๋ฐ ๋ฐ›๊ธฐ

Asterisk์™€ Bitrix24์˜ ํ†ตํ•ฉ

๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๊ฐ€์ง€๊ณ ์žˆ๋‹ค xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6. ๋˜ํ•œ ์ž์‹ ์—๊ฒŒ ๋ณต์‚ฌํ•ด์•ผ ํ•˜๋ฉฐ ๋ฐœ์‹  ์ „ํ™”๋ฅผ ๊ฑฐ๋Š” ๋ฐ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ค‘์š”!

Bitrix24 ์„œ๋ฒ„์—์„œ SSL ์ธ์ฆ์„œ๋ฅผ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(letsencrypt๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ). ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด BitrixXNUMX API๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํด๋ผ์šฐ๋“œ ๋ฒ„์ „์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ssl์€ ์ด๋ฏธ ์žˆ์Šต๋‹ˆ๋‹ค.

์ค‘์š”!

"ํ”„๋กœ์„ธ์„œ ์ฃผ์†Œ" ํ•„๋“œ์—๋Š” ์ธํ„ฐ๋„ท์—์„œ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์†Œ๋ฅผ ํ‘œ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค!

๋งˆ์ง€๋ง‰์œผ๋กœ CallMeOut์„ ์ „ํ™” ๊ฑธ๊ธฐ์šฉ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์„ค์น˜ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค(PBX์—์„œ ๋ฒˆํ˜ธ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ „ํ™”๋ฅผ ๊ฑธ๊ธฐ ์œ„ํ•œ ๋ช…๋ น์ด ๋‚ ์•„๊ฐ‘๋‹ˆ๋‹ค).

๋ฉ”๋‰ด์—์„œ ์ถ”๊ฐ€ -> ์ „ํ™” ํ†ต์‹  -> ์ถ”๊ฐ€ -> ์„ค์ •์„ ์„ ํƒํ•˜๊ณ  "๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐœ์‹  ์ „ํ™” ๋ฒˆํ˜ธ"๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ: CallMeOut์„ ํด๋ฆญํ•˜๊ณ  "์ €์žฅ"์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

Asterisk์™€ Bitrix24์˜ ํ†ตํ•ฉ

๋ณ„ํ‘œ ์„ค์ •

Asterisk์™€ Bitrix24 ๊ฐ„์˜ ์„ฑ๊ณต์ ์ธ ์ƒํ˜ธ ์ž‘์šฉ์„ ์œ„ํ•ด callme AMI ์‚ฌ์šฉ์ž๋ฅผ 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

๋‹ค์Œ์œผ๋กœ ๋‹ค์ด์–ผํ”Œ๋žœ(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๋ ˆ์ฝ”๋“œ Bitrix24๊ฐ€ ์—ฐ๋ฝ์ฒ˜ ์นด๋“œ๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๋Œ€ํ™” ๋…น์Œ ํŒŒ์ผ์˜ URL์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ ์šฐ๋ฆฌ๋Š” ๋งคํฌ๋กœ ๋งคํฌ๋กœ์— ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค ๋ฐฉ์†ก.

์—ฌ๊ธฐ์—์„œ๋Š” ๋Œ€ํ™”๋ฅผ ๋…น์Œํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ „์ฒด ์ด๋ฆ„.

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 ํ…Œ์ด๋ธ”์˜ ํ•ญ๋ชฉ์„ ๋„๊ณ (ํ•„์š”ํ•˜์ง€ ์•Š์Œ) ํ†ตํ™” ์ข…๋ฃŒ ์‹œ๊ฐ„์„ ์„ค์ •ํ•˜๊ณ  ํ†ตํ™” ๊ฒฐ๊ณผ๋ฅผ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ์ง€์† ์‹œ๊ฐ„์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ์ „ํ™”์ฃผ์„ธ์š” ์ฒ˜๋ถ„) ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„์—์„œ ์‹œ์Šคํ…œ ์ปฌ์„ ํ†ตํ•ด ๋ชจ๋“  ๊ฒƒ์„ Bitrix๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์กฐ๊ธˆ ๋” ๋งˆ์ˆ  - ์ˆ˜์‹  ์ „ํ™”:

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 ์„ค์น˜๋ผ๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. ๋ฐœ์‹ ๋ฒˆํ˜ธ(์ด๋ฆ„) ๋ณ€ํ•˜๊ธฐ ์‰ฌ์šด CallMe๋ฐœ์‹ ์ž ID์ด๋ฆ„.

CallMeCallerIDName ๋ณ€์ˆ˜ ์ž์ฒด๋Š” CallMe ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์˜ํ•ด ์„ค์ •๋ฉ๋‹ˆ๋‹ค(Bitrix24์— ๋ฐœ์‹ ์ž ๋ฒˆํ˜ธ์˜ ์ „์ฒด ์ด๋ฆ„์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค). ๋ฐœ์‹ ๋ฒˆํ˜ธ(์ด๋ฆ„), ์•„๋‹ˆ์˜ค - ์šฐ๋ฆฌ๋Š” ์•„๋ฌด๊ฒƒ๋„ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค).

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ค์ •

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ค์ • ํŒŒ์ผ - /var/www/pbx.vistep.ru/config.php

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ์„ค๋ช…:

  • ๋‚˜ํ•œํ…Œ ์ „ํ™”ํ•ด๋””๋ฒ„๊ทธ - 1์ด๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ฒ˜๋ฆฌํ•œ ๋ชจ๋“  ์ด๋ฒคํŠธ๊ฐ€ ๋กœ๊ทธ ํŒŒ์ผ์— ๊ธฐ๋ก๋˜๊ณ , 0์ด๋ฉด ์•„๋ฌด ๊ฒƒ๋„ ๊ธฐ๋กํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๊ธฐ์ˆ  SIP/PJSIP/IAX/๊ธฐํƒ€
  • ์ธ์ฆํ† ํฐ โ€” Bitrix24 ์ธ์ฆ ํ† ํฐ, ๋ฐœ์‹  ์›นํ›… ์ธ์ฆ ์ฝ”๋“œ
  • bitrixApiUrl โ€” ์ˆ˜์‹  ์›นํ›„ํฌ์˜ URL(profile/ ์—†์Œ)
  • ํ™•์žฅ โ€” ์™ธ๋ถ€ ๋ฒˆํ˜ธ ๋ชฉ๋ก
  • ๋ฌธ๋งฅ โ€” ํ˜ธ์ถœ ๋ฐœ์‹ ์— ๋Œ€ํ•œ ์ปจํ…์ŠคํŠธ
  • ๋ฆฌ์Šค๋„ˆ_์‹œ๊ฐ„ ์ดˆ๊ณผ - ๋ณ„ํ‘œ์—์„œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ์†๋„
  • ๋ณ„ํ‘œ - ๋ณ„ํ‘œ์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ ์„ค์ •์ด ์žˆ๋Š” ๋ฐฐ์—ด:
  • ์ฃผ์ธ - ๋ณ„ํ‘œ ์„œ๋ฒ„์˜ IP ๋˜๋Š” ํ˜ธ์ŠคํŠธ ์ด๋ฆ„
  • ๊ณ„ํš โ€” ์—ฐ๊ฒฐ ๋‹ค์ด์–ด๊ทธ๋žจ(tcp://, tls://)
  • ํฌํŠธ - ํฌํŠธ
  • ์‚ฌ์šฉ์ž ์ด๋ฆ„ - ์‚ฌ์šฉ์ž ์ด๋ฆ„
  • ๋น„๋ฐ€ - ๋น„๋ฐ€๋ฒˆํ˜ธ
  • ์—ฐ๊ฒฐ_์‹œ๊ฐ„ ์ดˆ๊ณผ - ์ ‘์† ์‹œ๊ฐ„ ์ดˆ๊ณผ
  • ์ฝ๊ธฐ ์‹œ๊ฐ„ ์ดˆ๊ณผ - ์ฝ๊ธฐ ์ œํ•œ ์‹œ๊ฐ„

์˜ˆ์ œ ์„ค์ • ํŒŒ์ผ:

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

);

๊ฐ๋…์ž ์„ค์ •

๊ฐ๋…์ž๋Š” ๋“ค์–ด์˜ค๋Š” ํ˜ธ์ถœ์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ  Bitrix24์™€ ์ƒํ˜ธ ์ž‘์šฉ(์นด๋“œ ํ‘œ์‹œ, ์นด๋“œ ์ˆจ๊ธฐ๊ธฐ ๋“ฑ)ํ•˜๋Š” Asterisk CallMeIn.php ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋งŒ๋“ค ์„ค์ • ํŒŒ์ผ:

/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

๊ฒฐ๋ก 

์ƒ๋‹นํžˆ ์–ด๋ ค์› ์ง€๋งŒ ์ˆ™๋ จ ๋œ ๊ด€๋ฆฌ์ž๊ฐ€ ์‚ฌ์šฉ์ž๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ๊ธฐ์˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค.

์•ฝ์†๋Œ€๋กœ ๊นƒํ—ˆ๋ธŒ ๋งํฌ.

์งˆ๋ฌธ, ์ œ์•ˆ - ์˜๊ฒฌ์„ ๋ณด๋‚ด์ฃผ์‹ญ์‹œ์˜ค. ๋˜ํ•œ์ด ํ†ตํ•ฉ ๊ฐœ๋ฐœ์ด ์–ด๋–ป๊ฒŒ ์ง„ํ–‰๋˜์—ˆ๋Š”์ง€์— ๊ด€์‹ฌ์ด ์žˆ์œผ์‹œ๋ฉด ๋‹ค์Œ ๊ธฐ์‚ฌ์—์„œ ๋ชจ๋“  ๊ฒƒ์„ ๋” ์ž์„ธํžˆ ๊ณต๊ฐœํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€