Jaringan kasebut duwe macem-macem pilihan kanggo nggabungake IP-PBX Asterisk lan CRM Bitrix24, nanging kita mutusake kanggo nulis dhewe.
Fungsional, kabeh standar:
- Kanthi ngeklik link karo nomer telpon klien ing Bitrix24, Asterisk nyambungake nomer internal pangguna atas jenenge sing klik iki digawe karo nomer telpon klien. Ing Bitrix24, rekaman telpon direkam, lan ing mburi telpon, rekaman obrolan ditarik munggah.
- Telpon teka ing Asterisk saka njaba - ing antarmuka Bitrix24, kita nuduhake kertu klien menyang karyawan sing nomer telpon kasebut teka.
Yen ora ana klien kuwi, mbukak kertu kanggo nggawe timbal anyar.
Sanalika telpon wis rampung, kita nggambarake iki ing kertu lan narik munggah rekaman obrolan.
Ing ngisor potong, aku bakal menehi pitutur marang kowe carane nyetel kabeh kanggo dhewe lan menehi link menyang github - ya, ya, njupuk lan gunakake!
Gambaran umum
Kita disebut integrasi CallMe. CallMe minangka aplikasi web cilik sing ditulis nganggo PHP.
Teknologi lan layanan sing digunakake
- PHP 5.6
Pustaka AMI PHP - pengarang
- nginx + php fpm
- pengawas
- AMI (Asterisk Manager Interface)
- Bitrix webhooks (implementasi REST API sing disederhanakake)
prasetel
Ing server karo Asterisk, sampeyan kudu nginstal server web (kita duwe nginx + php-fpm), supervisor lan git.
Printah instalasi (CentOS):
yum install nginx php-fpm supervisor git
Kita ngliwati direktori sing kasedhiya kanggo server web, narik aplikasi saka git lan nyetel hak sing dibutuhake kanggo folder kasebut:
cd /var/www
git clone https://github.com/ViStepRU/callme.git
chown nginx. -R callme/
Sabanjure, konfigurasi nginx, konfigurasi kita dumunung ing
/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;
}
}
Aku bakal ninggalake analisis konfigurasi, masalah keamanan, entuk sertifikat, lan malah milih server web ing njaba ruang lingkup artikel - akeh sing wis ditulis babagan iki. Aplikasi kasebut ora ana watesan, bisa digunakake ing http lan https.
Kita duwe https, ayo enkripsi sertifikat.
Yen sampeyan nindakake kabeh kanthi bener, banjur kanthi ngeklik link sampeyan bakal bisa ndeleng kaya iki
Nyetel Bitrix24
Ayo nggawe loro webhooks.
webhook mlebu.
Ing akun administrator (kanthi id 1) pindhah menyang dalan: Aplikasi -> Webhooks -> Tambah webhook -> Webhook mlebu
Isi parameter webhook sing mlebu kaya ing gambar:
Lan klik simpen.
Sawise disimpen, Bitrix24 bakal nyedhiyakake URL webhook sing mlebu, contone:
Simpen versi URL sampeyan tanpa mburine /profil/ - bakal digunakake ing aplikasi kanggo nggarap telpon mlebu.
Aku duwe https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/
Webhook metu.
Aplikasi -> Webhooks -> Tambah Webhook -> Outgoing Webhook
Rincian ana ing gambar:
Simpen lan entuk kode wewenang
Aku duwe xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6
. Sampeyan uga kudu nyalin menyang dhewe, iku perlu kanggo nelpon metu.
Penting!
Sertifikat ssl kudu dikonfigurasi ing server Bitrix24 (sampeyan bisa nggunakake letsencrypt), yen ora, api BitrixXNUMX ora bisa digunakake. Yen sampeyan duwe versi awan, aja kuwatir - ssl wis ana.
Penting!
Ing lapangan "Alamat Prosesor", alamat sing bisa diakses saka Internet kudu dituduhake!
Lan kanthi tutul pungkasan, ayo nginstal CallMeOut minangka aplikasi kanggo nelpon (supaya kanthi ngeklik nomer ing PBX, prentah bakal mabur kanggo nggawe telpon).
Ing menu, pilih: Liyane -> Telephony -> Liyane -> Setelan, lebokake ing "Nomer kanggo telpon metu kanthi standar" Aplikasi: CallMeOut banjur klik "Simpen"
persiyapan tanda bintang
Kanggo interaksi sing sukses antarane Asterisk lan Bitrix24, kita kudu nambah pangguna AMI callme menyang 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
Sabanjure, ana sawetara trik sing kudu dileksanakake nggunakake dialplan (kita duwe extensions.ael).
Aku bakal ngutip kabeh file, banjur aku bakal menehi katrangan:
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});
}
};
Ayo diwiwiti saka wiwitan: direktif global.
Variabel URLRECORDS nyimpen URL menyang file rekaman obrolan, miturut Bitrix24 bakal narik menyang kertu kontak.
Sabanjure, kita kasengsem ing makro makro Rekaman.
Ing kene, saliyane ngrekam obrolan, kita bakal nyetel variabel kasebut Jeneng Lengkap.
Set(FullFname=${URLRECORDS}/${datedir}/${fname}.mp3);
Iku nyimpen URL lengkap menyang file tartamtu (makro diarani nang endi wae).
Ayo analisa telpon metu:
_. => {
&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});
}
Ayo kita nelpon 89991234567, sing pisanan kita tekan ing kene:
&recording(${CALLERID(number)},${EXTEN});
sing. makro rekaman telpon diarani lan variabel sing perlu disetel.
luwih
Set(__CallIntNum=${CALLERID(num)})
Set(CallStart=${STRFTIME(epoch,,%s)});
kita ngrekam sapa sing miwiti telpon lan ngrekam wektu wiwitan telpon.
Lan sawise rampung, ing konteks khusus 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});
}
mateni entri ing tabel CDR kanggo extension iki (ora perlu ana), nyetel wektu pungkasan telpon, ngetung durasi, yen asil telpon ora dikenal - nyetel (variabel Telpon Aku DISPOSITION) lan, langkah pungkasan, ngirim kabeh kanggo Bitrix liwat sistem curl.
Lan sihir liyane - telpon mlebu:
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();
}
Kene kita mung kasengsem ing siji baris.
ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp());
Dheweke ujar nginstal PBX CallerID(jeneng) variabel CallMeCallerIDName.
Variabel CallMeCallerIDName dhewe, banjur disetel dening aplikasi CallMe (yen Bitrix24 duwe jeneng lengkap kanggo nomer panelpon, kita bakal nyetel minangka CallerID(jeneng), ora - kita ora bakal nindakake apa-apa).
Setelan aplikasi
File setelan aplikasi - /var/www/pbx.vistep.ru/config.php
Katrangan saka parameter aplikasi:
- TelponMeDEBUG - yen 1, banjur kabeh acara sing diproses dening aplikasi bakal ditulis menyang file log, 0 - kita ora nulis apa-apa
- tech SIP/PJSIP/IAX/etc
- authToken - Token wewenang Bitrix24, kode wewenang webhook sing metu
- bitrixApiUrl β URL webhook sing mlebu, tanpa profil/
- ekstensif - dhaptar nomer njaba
- konteks - konteks kanggo asale telpon
- listener_timeout - kacepetan Processing acara saka asterisk
- asterisk - larik kanthi setelan sambungan menyang tanda bintang:
- inang - ip utawa hostname saka server tanda bintang
- rencana - diagram sambungan (tcp: //, tls: //)
- port - pelabuhan
- jeneng panganggo - Jeneng panganggo
- rahasia - sandi
- connect_timeout - sambungan wektu entek
- maca_wektu entek - maca wektu entek
conto file setelan:
<?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
);
Setelan supervisor
Supervisor digunakake kanggo miwiti proses handler acara Asterisk CallMeIn.php, kang ngawasi telpon mlebu lan sesambungan karo Bitrix24 (nuduhake kertu, ndhelikake kertu, etc.).
File setelan kanggo nggawe:
/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
Miwiti lan miwiti maneh aplikasi:
supervisorctl start callme
supervisorctl restart callme
ndeleng status aplikasi:
supervisorctl status callme
callme RUNNING pid 11729, uptime 17 days, 16:58:07
kesimpulan
Ternyata cukup angel, nanging aku yakin manawa administrator sing berpengalaman bakal bisa ngetrapake lan nyenengake para pangguna.
Kaya janjine,
Pitakonan, saran - mangga ing komentar. Uga, yen sampeyan kasengsem carane pangembangan integrasi iki tindak, nulis, lan ing artikel sabanjurΓ© aku bakal nyoba kanggo mbukak kabeh ing liyane rinci.
Source: www.habr.com