Ενσωμάτωση 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), επόπτη και git.

Εντολή εγκατάστασης (CentOS):

yum install nginx php-fpm supervisor git

Περνάμε τον κατάλογο που είναι διαθέσιμος στον διακομιστή web, τραβάμε την εφαρμογή από το git και ορίζουμε τα απαραίτητα δικαιώματα στο φάκελο:


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

Στη συνέχεια, διαμορφώστε το nginx, το config μας βρίσκεται στο

/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

Ας δημιουργήσουμε δύο webhook.

Εισερχόμενο webhook.

Κάτω από τον λογαριασμό διαχειριστή (με αναγνωριστικό 1) ακολουθήστε τη διαδρομή: Εφαρμογές -> Webhooks -> Προσθήκη webhook -> Εισερχόμενο webhook

Ενσωμάτωση Asterisk και Bitrix24

Συμπληρώστε τις παραμέτρους του εισερχόμενου webhook όπως στα στιγμιότυπα οθόνης:

Ενσωμάτωση Asterisk και Bitrix24

Ενσωμάτωση Asterisk και Bitrix24

Και κάντε κλικ στην αποθήκευση.

Μετά την αποθήκευση, το Bitrix24 θα παρέχει τη διεύθυνση URL του εισερχόμενου webhook, για παράδειγμα:

Ενσωμάτωση Asterisk και Bitrix24

Αποθηκεύστε την έκδοση της διεύθυνσης URL χωρίς το τέλος /προφίλ/ - θα χρησιμοποιηθεί στην εφαρμογή για εργασία με εισερχόμενες κλήσεις.

το έχω https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/

Εξερχόμενο webhook.

Εφαρμογές -> Webhook -> Προσθήκη Webhook -> Εξερχόμενο Webhook

Λεπτομέρειες υπάρχουν στα στιγμιότυπα οθόνης:

Ενσωμάτωση Asterisk και Bitrix24

Ενσωμάτωση Asterisk και Bitrix24

Αποθηκεύστε και λάβετε τον κωδικό εξουσιοδότησης

Ενσωμάτωση Asterisk και Bitrix24

το έχω xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6. Πρέπει επίσης να το αντιγράψετε στον εαυτό σας, είναι απαραίτητο για την πραγματοποίηση εξερχόμενων κλήσεων.

Σημαντικό!

Ένα πιστοποιητικό ssl πρέπει να ρυθμιστεί στον διακομιστή Bitrix24 (μπορείτε να χρησιμοποιήσετε letsencrypt), διαφορετικά το BitrixXNUMX api δεν θα λειτουργήσει. Εάν έχετε μια έκδοση cloud, μην ανησυχείτε - το 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

Στη συνέχεια, υπάρχουν μερικά κόλπα που θα πρέπει να εφαρμοστούν χρησιμοποιώντας το dialplan (έχουμε 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 θα τα τραβήξει στην κάρτα επαφής.

Στη συνέχεια, μας ενδιαφέρει η μακροεντολή εγγραφή.

Εδώ, εκτός από την εγγραφή συνομιλιών, θα ορίσουμε τη μεταβλητή FullFname.

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 για αυτήν την επέκταση (δεν χρειάζεται εκεί), ορίστε την ώρα λήξης της κλήσης, υπολογίστε τη διάρκεια, εάν το αποτέλεσμα της κλήσης δεν είναι γνωστό - ορίστε (μεταβλητή Call Me DISPOSITION) και, το τελευταίο βήμα, στείλτε τα πάντα στο 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 Αναγνωριστικό καλούντος (όνομα) μεταβλητός CallMeCallerIDName.

Η ίδια η μεταβλητή CallMeCallerIDName, με τη σειρά της, ορίζεται από την εφαρμογή CallMe (εάν το Bitrix24 έχει πλήρες όνομα για τον αριθμό του καλούντος, θα το ορίσουμε ως Αναγνωριστικό καλούντος (όνομα), όχι - δεν θα κάνουμε τίποτα).

Ρύθμιση της εφαρμογής

Αρχείο ρυθμίσεων εφαρμογής - /var/www/pbx.vistep.ru/config.php

Περιγραφή των παραμέτρων εφαρμογής:

  • CallMeDEBUG - εάν 1, τότε όλα τα συμβάντα που επεξεργάζεται η εφαρμογή θα εγγραφούν στο αρχείο καταγραφής, 0 - δεν γράφουμε τίποτα
  • tech SIP/PJSIP/IAX/κ.λπ
  • authToken — Διακριτικό εξουσιοδότησης Bitrix24, εξερχόμενος κωδικός εξουσιοδότησης webhook
  • bitrixApiUrl — URL του εισερχόμενου webhook, χωρίς προφίλ/
  • επεκτάσεις — λίστα εξωτερικών αριθμών
  • συμφραζόμενα — πλαίσιο για την προέλευση κλήσεων
  • listener_timeout - Ταχύτητα επεξεργασίας συμβάντων από τον αστερίσκο
  • αστερίσκος - έναν πίνακα με τις ρυθμίσεις σύνδεσης στον αστερίσκο:
  • οικοδεσπότης - ip ή όνομα κεντρικού υπολογιστή του διακομιστή αστερίσκου
  • σχέδιο — διάγραμμα σύνδεσης (tcp://, tls://)
  • λιμάνι - Λιμάνι
  • όνομα χρήστη - Όνομα χρήστη
  • μυστικό - Κωδικός πρόσβασης
  • connect_timeout - λήξη χρόνου σύνδεσης
  • read_timeout - διάβασμα χρονικού ορίου

παράδειγμα αρχείου ρυθμίσεων:

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

Προσθέστε ένα σχόλιο