Optiones variae sunt ad integrationem IP-PBX Asteriscus et CRM Bitrix24 in retiacula, sed adhuc nostra scribere decrevimus.
Secundum functionality, omnia signa sunt;
- Deprimendo in nexu cum numero telephonico clientis in Bitrix24, Asterisk connectit numerum internum utentis cuius causa electronica facta est cum numero telephonico clientis. In Bitrix24, recordatio vocationis commemoratur et, in fine vocationis, recordatio colloquii evellitur.
- Asteriscus vocationem accipit ab extra - in bitrix24 instrumenti clientis cardo demonstramus operario ad cuius numerus haec vocatio pervenerat.
Si cliens talis non est, chartam aperiemus ad novum plumbum creandum.
Ut primum vocatio peracta est, hoc in schedula cogitamus ac memoriam colloquii evellere.
Infra incisam Dicam tibi quomodo omnia tibi proponas et tibi nexum github - ita, sic, sume et utere!
communia
Nostram integrationem vocavimus CallMe. CallMe parva applicationis telae in PHP scripta est.
Technologies et officia usus
- PHP 5.6
PHP AMI bibliotheca - Composer:
- Nginx + php-fpm
- supervisoris
- AMI (Asteriscus Procurator Interface)
- Bitrix webhooks (simplicior CETERA API exsecutio)
Pre-occasum
In servo cum Asterisco, interretialem interretialem instituere debes (nobis enim est nginx+php-fpm), supervisoris et git.
Mandatum instruitur (CentOS);
yum install nginx php-fpm supervisor git
Ad indicem pervium ad telam server itur, applicationem ex Git collige et necessaria iura ad folder pone:
cd /var/www
git clone https://github.com/ViStepRU/callme.git
chown nginx. -R callme/
Deinde configurare nginx, config nostrum situm est
/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;
}
}
Relinquo parteming config, quaestiones securitatis, obtinens libellum nec non eligens servo telae extra ambitum articuli - multum de hoc scriptum est. Applicatio restrictiones non habet, operatur in utraque https et https.
Utimur https, libellum encrypt.
Si omnia recte fecistis, strepitando in nexu aliquid simile videre debes
Bitrix24 erigens
Duo webhooks faciamus.
Advenientis webhook.
Sub ratione administratoris (cum id 1), viam sequere: Applications -> Webhooks -> addere webhook -> invenientes webhook
Imple in parametris telae advenientis sicut in eenshotsscray:
Ac deprime nisi.
Post salvificam, Bitrix24 Domicilium telae advenientis providebit, exempli gratia:
Serva tuam versionem URL sine finali /profile/-, in applicatione ad operandum cum advenientis vocat.
Hoc habeo https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/
Munus webhook.
Applications -> Webhooks -> addere webhook -> Outgoing webhook
Singula rursus in eenshotsscray sunt:
Salvum ac potestatem codice
Hoc habeo xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6
. Tu quoque tibi illam imitari debes, opus ad exitum vocat.
Magni momenti!
Testimonium SSL configurari debet in servo Bitrix24 (letsencrypt uti potes), secus Bitrix api non laborabit. Si versionem nubem habes, noli solliciti esse - iam Γl est.
Magni momenti!
"Processus Oratio" campus electronicam adibilem e Interrete continere debet!
Et ut finalis tactus, nostrum CallMeOut instituat ut applicationem ad vocationes faciendas (ut cum numerum in PBX deprimas, mandatum vocationis originis avolabit).
In menu, lego: More -> Telephonia -> Occasus More -> Occasus, in "Default egressus numerus" Applicatio: CallMeOut et preme "Save"
Profecta asterisco
Pro prospero commercio inter Asteriscum et Bitrix24, necesse est ut procuratorem AMI usoris callme addere.
[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
Deinde plures sunt praestigiae quae per dialplanum perficiendum opus sunt (nobis hoc est extensiones.ael).
Totum fasciculum dabo, deinde rationem dabo:
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});
}
};
Incipiamus ab initio: directivum GLOBALS.
variabilis URLRECORDS Domicilium ad tabulariorum monumentorum refert, secundum quae Bitrix24 eas in contactum card colliget.
Deinde quaeritur in tortor tortor muniat.
Hic, praeter actis sermonibus, variabiles ponemus FullFname.
Set(FullFname=${URLRECORDS}/${datedir}/${fname}.mp3);
Domicilium plenum ad fasciculi specifici reponit (mactura ubique appellatur).
Sit scriptor exitus vocationem analyze:
_. => {
&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});
}
Dicamus quod 89991234567 vocamus, primum hic venimus;
&recording(${CALLERID(number)},${EXTEN});
illae. Colloquium microform macrons vocatur et necessariae variabiles ponuntur.
adhuc
Set(__CallIntNum=${CALLERID(num)})
Set(CallStart=${STRFTIME(epoch,,%s)});
Memoriam facimus qui vocationem initiaverunt et tempus vocationis initium memoriae mandamus.
Et ad eius completionem in speciali contextu 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});
}
inactivare ingressum ad mensam CDR pro extensione hac (ibi non opus est), finem vocationis pone, durationem calculare, si effectus vocationis non est notus - constitutus (variabilis CallMeDISPOSITION) et, ultimo gradu, omnia mitte ad Crispum Bitricem per systema.
Et paulo plus magicae - vocatio advenientis;
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();
}
Hic tantum interest in una linea.
ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp());
PBX ut install narrat illa CallerID (nomen) aequalis variabilis CallMeCallerIDName.
Ipsa variabilis CallMeCallerIDName, vicissim, ab applicatione CallMe ponitur (si Bitrix24 plenum nomen habet pro numero salutatoris, pone eam pro CallerID (nomen), non - nihil facimus).
Erexerit applicationem
Applicationem occasus fasciculi - /var/www/pbx.vistep.ru/config.php
Descriptionem applicationis parametri:
- CallMeDEBUG β si 1, tunc omnia, quae per applicationem processit, scribentur ad fasciculi stipes, 0 β nihil scribimus
- tech - SIP/PJSIP/IAX/etc
- authToken - Bitrix24 auctoritatis indicium, licentia webhook codice
- bitrixApiUrl - Domicilium webhook advenientis, sine profile/
- extensiones - list of extra numerum
- context - context ad originem vocationis
- listener_timeout - celeritas res dispensando ab asterisco
- Asteriscus - ordinatis occasus pro asterisco connectens;
- exercitum - IP vel hostname asterisco server
- ratio β connexio schematis (tcp://, tls://)
- portum - port
- More - Username
- secreto - password
- connect_timeout - nexu timeout
- read_timeout - legere timeout
exempli gratia occasus file:
<?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
);
Supervisoris setup
Supervisoris processus tractatoris eventus ab Asterisco CallMeIn.php deducere adhibetur, quem monitores ineuntes vocat et reciprocus cum Bitrix24 (showem card, card celare, etc.).
Optiones lima creari:
/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
Lorem ac sileo applicationem:
supervisorctl start callme
supervisorctl restart callme
Viewing applicationem status operating suus:
supervisorctl status callme
callme RUNNING pid 11729, uptime 17 days, 16:58:07
conclusio,
Versa est satis perplexa, sed scio peritum administratorem eam efficere et suis utentibus placere posse.
sicut promiserat,
Interrogationes, suggestiones - eas in commenta relinquere placet. Item, si interest quomodo progressionem integrationis huius perrexerit, scribe, et sequenti articulo omnia subtilius revelare conabor.
Source: www.habr.com