Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ Π½Π° Asterisk ΠΈ Bitrix24

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ Π½Π° Asterisk ΠΈ Bitrix24
Има Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΎΠΏΡ†ΠΈΠΈ Π·Π° ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° IP-PBX Asterisk ΠΈ CRM Bitrix24 Π² ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π°, Π½ΠΎ всС ΠΏΠ°ΠΊ Ρ€Π΅ΡˆΠΈΡ…ΠΌΠ΅ Π΄Π° напишСм своя собствСна.

По ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ Π½Π° функционалността всичко Π΅ стандартно:

  • Π©Ρ€Π°ΠΊΠ²Π°ΠΉΠΊΠΈ Π²ΡŠΡ€Ρ…Ρƒ Π»ΠΈΠ½ΠΊ с Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½Π΅Π½ Π½ΠΎΠΌΠ΅Ρ€ Π½Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π² Bitrix24, Asterisk ΡΠ²ΡŠΡ€Π·Π²Π° Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ½ΠΈΡ Π½ΠΎΠΌΠ΅Ρ€ Π½Π° потрСбитСля, ΠΎΡ‚ Ρ‡ΠΈΠ΅Ρ‚ΠΎ ΠΈΠΌΠ΅ Π΅ Π½Π°ΠΏΡ€Π°Π²Π΅Π½ΠΎ ΠΊΠ»ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ, с тСлСфонния Π½ΠΎΠΌΠ΅Ρ€ Π½Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π’ Bitrix24 сС записва запис Π½Π° Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Π° ΠΈ Π² края Π½Π° Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Π° сС изтСгля запис Π½Π° Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Π°.
  • Asterisk ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π° ΠΎΠ±Π°ΠΆΠ΄Π°Π½Π΅ ΠΎΡ‚Π²ΡŠΠ½ - Π² интСрфСйса Π½Π° Bitrix24 ΠΏΠΎΠΊΠ°Π·Π²Π°ΠΌΠ΅ клиСнтската ΠΊΠ°Ρ€Ρ‚Π° Π½Π° слуТитСля, Π½Π° Ρ‡ΠΈΠΉΡ‚ΠΎ Π½ΠΎΠΌΠ΅Ρ€ Π΅ пристигнало Ρ‚ΠΎΠ²Π° ΠΎΠ±Π°ΠΆΠ΄Π°Π½Π΅.
    Ако няма Ρ‚Π°ΠΊΡŠΠ² ΠΊΠ»ΠΈΠ΅Π½Ρ‚, Ρ‰Π΅ ΠΎΡ‚Π²ΠΎΡ€ΠΈΠΌ ΠΊΠ°Ρ€Ρ‚Π°Ρ‚Π° Π·Π° създаванС Π½Π° Π½ΠΎΠ² Π»ΠΈΠΉΠ΄.
    Π’Π΅Π΄Π½Π°Π³Π° слСд ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡Π²Π°Π½Π΅ Π½Π° Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Π° отразявамС Ρ‚ΠΎΠ²Π° Π½Π° ΠΊΠ°Ρ€Ρ‚Π°Ρ‚Π° ΠΈ ΠΈΠ·Π²Π°ΠΆΠ΄Π°ΠΌΠ΅ запис Π½Π° Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Π°.

По-Π΄ΠΎΠ»Ρƒ Ρ‰Π΅ Π²ΠΈ ΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊ Π΄Π° настроитС всичко Π·Π° сСбС си ΠΈ Ρ‰Π΅ Π²ΠΈ Π΄Π°ΠΌ Π²Ρ€ΡŠΠ·ΠΊΠ° към github - Π΄Π°, Π΄Π°, Π²Π·Π΅ΠΌΠ΅Ρ‚Π΅ Π³ΠΎ ΠΈ Π³ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅!

ΠžΠ±Ρ‰ΠΎ описаниС

НарСкохмС Π½Π°ΡˆΠ°Ρ‚Π° интСграция CallMe. CallMe Π΅ ΠΌΠ°Π»ΠΊΠΎ ΡƒΠ΅Π± ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, написано Π½Π° PHP.

Използвани Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ ΠΈ услуги

  • PHP 5.6
  • PHP AMI Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°
  • ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ€Π°ΠΌ
  • Nginx + php-fpm
  • Ρ€ΡŠΠΊΠΎΠ²ΠΎΠ΄ΠΈΡ‚Π΅Π»
  • AMI (Asterisk Manager интСрфСйс)
  • Bitrix webhooks (опростСна рСализация Π½Π° REST API)

ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»Π½Π° настройка

На ΡΡŠΡ€Π²ΡŠΡ€ със Asterisk трябва Π΄Π° инсталиратС ΡƒΠ΅Π± ΡΡŠΡ€Π²ΡŠΡ€ (ΠΏΡ€ΠΈ нас Π΅ nginx+php-fpm), supervisor ΠΈ 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

НСка създадСм Π΄Π²Π΅ ΡƒΠ΅Π±ΠΊΡƒΠΊΠΈΡ‡ΠΊΠΈ.

Входяща ΡƒΠ΅Π±ΠΊΡƒΠΊΠΈΡ‡ΠΊΠ°.

Под администраторския Π°ΠΊΠ°ΡƒΠ½Ρ‚ (с ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ 1) слСдвайтС ΠΏΡŠΡ‚Ρ: ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ -> Webhooks -> Add webhook -> Incoming webhook

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ Π½Π° Asterisk ΠΈ Bitrix24

ΠŸΠΎΠΏΡŠΠ»Π½Π΅Ρ‚Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΡ‚Π΅ Π½Π° входящия webhook, ΠΊΠ°ΠΊΡ‚ΠΎ Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½Π° Π΅ΠΊΡ€Π°Π½Π½ΠΈΡ‚Π΅ снимки:

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ Π½Π° Asterisk ΠΈ Bitrix24

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ Π½Π° Asterisk ΠΈ Bitrix24

И Ρ‰Ρ€Π°ΠΊΠ½Π΅Ρ‚Π΅ Π²ΡŠΡ€Ρ…Ρƒ Π·Π°ΠΏΠ°Π·Π²Π°Π½Π΅.

Π‘Π»Π΅Π΄ Π·Π°ΠΏΠ°Π·Π²Π°Π½Π΅ Bitrix24 Ρ‰Π΅ прСдостави URL адрСса Π½Π° входящия webhook, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ Π½Π° Asterisk ΠΈ Bitrix24

Π—Π°ΠΏΠ°Π·Π΅Ρ‚Π΅ Π²Π°ΡˆΠ°Ρ‚Π° URL вСрсия Π±Π΅Π· крайния /ΠΏΡ€ΠΎΡ„ΠΈΠ»/ ​​- Ρ‚ΠΎΠΉ Ρ‰Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с входящи обаТдания.

ΠΈΠΌΠ°ΠΌ Ρ‚ΠΎΠ²Π° https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/

Π˜Π·Ρ…ΠΎΠ΄ΡΡ‰Π° ΡƒΠ΅Π±ΠΊΡƒΠΊΠΈΡ‡ΠΊΠ°.

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ -> Webhooks -> Add webhook -> Outgoing webhook

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΡΡ‚ΠΈΡ‚Π΅ са ΠΎΡ‚Π½ΠΎΠ²ΠΎ Π½Π° Π΅ΠΊΡ€Π°Π½Π½ΠΈΡ‚Π΅ снимки:

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ Π½Π° Asterisk ΠΈ Bitrix24

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ Π½Π° Asterisk ΠΈ Bitrix24

Π—Π°ΠΏΠ°Π·Π΅Ρ‚Π΅ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Ρ‚Π΅ ΠΊΠΎΠ΄Π° Π·Π° оторизация

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ Π½Π° Asterisk ΠΈ Bitrix24

ΠΈΠΌΠ°ΠΌ Ρ‚ΠΎΠ²Π° xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6. Врябва ΡΡŠΡ‰ΠΎ Π΄Π° Π³ΠΎ ΠΊΠΎΠΏΠΈΡ€Π°Ρ‚Π΅ Π·Π° сСбС си; трябва Π²ΠΈ, Π·Π° Π΄Π° ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π°Ρ‚Π΅ изходящи повиквания.

Π’Π°ΠΆΠ½ΠΎ!

SSL ΡΠ΅Ρ€Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΡŠΡ‚ трябва Π΄Π° бъдС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½ Π½Π° ΡΡŠΡ€Π²ΡŠΡ€Π° Bitrix24 (ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ letsencrypt), Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π΅Π½ случай API Π½Π° Bitrix няма Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ. Ако ΠΈΠΌΠ°Ρ‚Π΅ ΠΎΠ±Π»Π°Ρ‡Π½Π° вСрсия, Π½Π΅ сС притСснявайтС - тя Π²Π΅Ρ‡Π΅ ΠΈΠΌΠ° ssl.

Π’Π°ΠΆΠ½ΠΎ!

ΠŸΠΎΠ»Π΅Ρ‚ΠΎ β€œΠΠ΄Ρ€Π΅Ρ Π½Π° процСсора” трябва Π΄Π° ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° адрСс, Π΄ΠΎΡΡ‚ΡŠΠΏΠ΅Π½ ΠΎΡ‚ Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚!

И ΠΊΠ°Ρ‚ΠΎ послСдСн Ρ‰Ρ€ΠΈΡ…, Π½Π΅ΠΊΠ° инсталирамС нашия CallMeOut ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π° ΠΏΡ€ΠΎΠ²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€ΠΈ (Ρ‚Π°ΠΊΠ° Ρ‡Π΅ ΠΊΠΎΠ³Π°Ρ‚ΠΎ Ρ‰Ρ€Π°ΠΊΠ½Π΅Ρ‚Π΅ Π²ΡŠΡ€Ρ…Ρƒ Π½ΠΎΠΌΠ΅Ρ€Π° Π½Π° PBX, ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° Π·Π° Π·Π°ΠΏΠΎΡ‡Π²Π°Π½Π΅ Π½Π° Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Π° Ρ‰Π΅ ΠΈΠ·Ρ‡Π΅Π·Π½Π΅).

Π’ ΠΌΠ΅Π½ΡŽΡ‚ΠΎ ΠΈΠ·Π±Π΅Ρ€Π΅Ρ‚Π΅: ΠžΡ‰Π΅ -> ВСлСфония -> ΠžΡ‰Π΅ -> Настройки, Π·Π°Π΄Π°ΠΉΡ‚Π΅ Π² β€œΠΠΎΠΌΠ΅Ρ€ Π·Π° изходящо ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ ΠΏΠΎ подразбиранС” ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: CallMeOut ΠΈ натиснСтС β€œΠ—Π°ΠΏΠ°Π·Π²Π°Π½Π΅β€

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ Π½Π° Asterisk ΠΈ Bitrix24

НастройванС Π½Π° Π·Π²Π΅Π·Π΄ΠΈΡ‡ΠΊΠ°

Π—Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ взаимодСйствиС ΠΌΠ΅ΠΆΠ΄Ρƒ Asterisk ΠΈ Bitrix24 трябва Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ AMI user callme към 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Π—ΠΠŸΠ˜Π‘Π˜ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° URL адрСса Π½Π° Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅Ρ‚Π΅ Π·Π° запис Π½Π° Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€ΠΈ, спорСд ΠΊΠΎΠΈΡ‚ΠΎ Bitrix24 Ρ‰Π΅ Π³ΠΈ ΠΈΠ·Ρ‚Π΅Π³Π»ΠΈ Π² ΠΊΠ°Ρ€Ρ‚Π°Ρ‚Π° Π·Π° ΠΊΠΎΠ½Ρ‚Π°ΠΊΡ‚.

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° сС интСрСсувамС ΠΎΡ‚ ΠΌΠ°ΠΊΡ€ΠΎ макроса запис.

Π’ΡƒΠΊ, Π² допълнСниС към записа Π½Π° Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€ΠΈ, Ρ‰Π΅ Π·Π°Π΄Π°Π΄Π΅ΠΌ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°Ρ‚Π° Пълно ΠΈΠΌΠ΅.

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 Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° Π·Π° Ρ‚ΠΎΠ²Π° Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ (Π½Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Ρ‚Π°ΠΌ), Π·Π°Π΄Π°ΠΉΡ‚Π΅ крайния час Π½Π° Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Π°, изчислСтС ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠΈΡ‚Π΅Π»Π½ΠΎΡΡ‚Ρ‚Π°, Π°ΠΊΠΎ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΡŠΡ‚ ΠΎΡ‚ Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Π° Π½Π΅ Π΅ извСстСн - Π·Π°Π΄Π°ΠΉΡ‚Π΅ (ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° CallMeDISPOSITION) ΠΈ послСдната ΡΡ‚ΡŠΠΏΠΊΠ°, ΠΈΠ·ΠΏΡ€Π°Ρ‚Π΅Ρ‚Π΅ всичко Π½Π° Bitrix Ρ‡Ρ€Π΅Π· систСмния curl.

И ΠΎΡ‰Π΅ ΠΌΠ°Π»ΠΊΠΎ магия - входящо ΠΎΠ±Π°ΠΆΠ΄Π°Π½Π΅:

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 Π΄Π° инсталира Caller ID (ΠΈΠΌΠ΅) Ρ€Π°Π²Π½ΠΎ Π½Π° ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° CallMeCallerIDName.

Π‘Π°ΠΌΠ°Ρ‚Π° ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° CallMeCallerIDName ΠΎΡ‚ своя страна сС Π·Π°Π΄Π°Π²Π° ΠΎΡ‚ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ CallMe (Π°ΠΊΠΎ Bitrix24 ΠΈΠΌΠ° пълно ΠΈΠΌΠ΅ Π·Π° Π½ΠΎΠΌΠ΅Ρ€Π° Π½Π° обаТдащия сС, Π·Π°Π΄Π°ΠΉΡ‚Π΅ Π³ΠΎ ΠΊΠ°Ρ‚ΠΎ Caller ID (ΠΈΠΌΠ΅), Π½Π΅ - няма Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ Π½ΠΈΡ‰ΠΎ).

Настройка Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ

Π€Π°ΠΉΠ» с настройки Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ - /var/www/pbx.vistep.ru/config.php

ОписаниС Π½Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΡ‚Π΅ Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ:

  • CallMeDEBUG β€” Π°ΠΊΠΎ 1, всички ΡΡŠΠ±ΠΈΡ‚ΠΈΡ, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π΅Π½ΠΈ ΠΎΡ‚ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ, Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ записани Π² Π»ΠΎΠ³ Ρ„Π°ΠΉΠ»Π°, 0 β€” Π½Π΅ пишСм Π½ΠΈΡ‰ΠΎ
  • Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ - SIP/PJSIP/IAX/ΠΈ Π΄Ρ€
  • authToken β€” Π’ΠΎΠΊΠ΅Π½ Π·Π° оторизация Π½Π° Bitrix24, ΠΊΠΎΠ΄ Π·Π° оторизация Π½Π° изходящ webhook
  • bitrixApiUrl β€” URL Π½Π° входящия webhook, Π±Π΅Π· ΠΏΡ€ΠΎΡ„ΠΈΠ»/
  • Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΡ β€” списък с външни Π½ΠΎΠΌΠ΅Ρ€Π°
  • контСкст β€” контСкст Π·Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅
  • ΡΠ»ΡƒΡˆΠ°Ρ‚Π΅Π»_Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚ β€” скорост Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΡ ΠΎΡ‚ Π·Π²Π΅Π·Π΄ΠΈΡ‡ΠΊΠ°
  • Π·Π²Π΅Π·Π΄ΠΈΡ‡ΠΊΠ° β€” масив с настройки Π·Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅ към Π·Π²Π΅Π·Π΄ΠΈΡ‡ΠΊΠ°Ρ‚Π°:
  • Π΄ΠΎΠΌΠ°ΠΊΠΈΠ½ β€” 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

);

Настройка Π½Π° ΡΡƒΠΏΠ΅Ρ€Π²Π°ΠΉΠ·ΡŠΡ€

Supervisor сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° стартиранС Π½Π° процСса Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΡ ΠΎΡ‚ Asterisk CallMeIn.php, ΠΊΠΎΠΉΡ‚ΠΎ слСди входящитС повиквания ΠΈ взаимодСйства с Bitrix24 (ΠΏΠΎΠΊΠ°ΠΆΠΈ ΠΊΠ°Ρ€Ρ‚Π°, скрий ΠΊΠ°Ρ€Ρ‚Π° ΠΈ Ρ‚.Π½.).

Π€Π°ΠΉΠ» с настройки, ΠΊΠΎΠΉΡ‚ΠΎ трябва Π΄Π° бъдС създадСн:

/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

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Оказа сС доста слоТно, Π½ΠΎ съм сигурСн, Ρ‡Π΅ ΠΎΠΏΠΈΡ‚Π΅Π½ администратор Ρ‰Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° Π³ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈ ΠΈ Π΄Π° Π·Π°Ρ€Π°Π΄Π²Π° своитС ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΠΈ.

ΠšΠ°ΠΊΡ‚ΠΎ Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΎ, Π»ΠΈΠ½ΠΊ към github.

Π’ΡŠΠΏΡ€ΠΎΡΠΈ, прСдлоТСния - моля, оставСтС Π³ΠΈ Π² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΡ‚Π΅. ОсвСн Ρ‚ΠΎΠ²Π°, Π°ΠΊΠΎ сС интСрСсуватС ΠΊΠ°ΠΊ Π΅ ΠΏΡ€ΠΎΡ‚Π΅ΠΊΠ»ΠΎ Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ Π½Π° Ρ‚Π°Π·ΠΈ интСграция, ΠΏΠΈΡˆΠ΅Ρ‚Π΅, Π° Π² слСдващата статия Ρ‰Π΅ сС ΠΎΠΏΠΈΡ‚Π°ΠΌ Π΄Π° разкрия всичко ΠΏΠΎ-ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€