![](https://habrastorage.org/webt/d2/bl/rd/d2blrdldi6khjwtmv0hylxi7vvq.png)
このネットワークには、Asterisk IP-PBXとBitrix24 CRMを統合するためのさまざまなオプションがありますが、独自に作成することにしました。
機能面では、すべてが標準です:
- Bitrix24のクライアントの電話番号のリンクをクリックすることにより、アスタリスクは、このクリックがコミットされたユーザーの内部番号とクライアントの電話番号を接続します。 Bitrix24では、通話記録が記録され、通話の終わりに会話記録が強化されます。
- アスタリスクの外部から電話がかかります-Bitrix24インターフェースでは、この電話がかかってきた番号の従業員にクライアントのカードを表示します。
そのようなクライアントがない場合は、新しいリードを作成するためにカードを開きます。
通話が完了するとすぐに、これをカードに反映し、会話の録音を強化します。
猫の下で、すべてを自分用に設定し、GitHubにリンクを張る方法を説明します。
概要
統合CallMeと呼びました。 CallMeは、PHPで書かれた小さなWebアプリケーションです。
使用されている技術とサービス
- PHP 5.6
- PHP AMIライブラリ
- 作曲家
- Nginx + php-fpm
- 監督者
- AMI(アスタリスク管理インターフェース)
- Bitrix Webhook(簡易REST API実装)
プリセット
Asteriskを搭載したサーバーに、Webサーバー(nginx + php-fpmがあります)、supervisor、gitをインストールする必要があります。
インストールコマンド(CentOS):
yum install nginx php-fpm supervisor git
Webサーバーからアクセス可能なディレクトリに移動し、gitaからアプリケーションをプルして、フォルダーに必要な権限を設定します。
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; } }
構成の分析、セキュリティの問題、証明書の取得、さらに記事の範囲外のWebサーバーの選択までは残しておきます。これについては多くのことが書かれています。 アプリケーションには制限がなく、httpとhttpsで機能します。
httpsがあります。証明書を暗号化しましょう。
すべてを正しく行った場合、リンクをたどると、同様のものが表示されます
![](https://habrastorage.org/webt/_0/ag/ij/_0agijgm_tagwpymgdnehhbpbrg.png)
Bitrix24の構成
2つのwebhookを作成しましょう。
着信webhook。
管理者アカウント(ID 1)の下で、パスに沿って進みます:アプリケーション-> Webhooks-> Webhookの追加->受信Webhook
![](https://habrastorage.org/webt/wr/ge/e-/wrgee-n17vzvnqfixsipxgiwg1w.png)
スクリーンショットのように、着信Webhookのパラメーターを入力します。
![](https://habrastorage.org/webt/mg/kw/hh/mgkwhhqed4oxivgf-ngxwjxnrqi.png)
![](https://habrastorage.org/webt/51/q4/z6/51q4z6zbhgg5tn03fpqmvvumc14.png)
保存をクリックします。
保存後、Bitrix24は、次のような着信Webhook URLを提供します。
![](https://habrastorage.org/webt/su/ul/vh/suulvhnquhept_hkecbni3zmqzk.png)
末尾/プロファイル/なしでURLのバージョンを保存します-着信呼び出しを処理するためにアプリケーションで使用されます。
https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/
発信Webhook。
アプリケーション-> Webhook-> Webhookの追加-> Outbound Webhook
スクリーンショットの詳細:
![](https://habrastorage.org/webt/50/uc/jb/50ucjbiwvtyqcylie_piamvp1py.png)
![](https://habrastorage.org/webt/ph/63/rv/ph63rv-br9gxrjmk80qk0lpe4rw.png)
保存して認証コードを取得します
![](https://habrastorage.org/webt/to/ui/wa/touiwa_xq2j4svjcdmndny9fkfw.png)
xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6
ます。 また、自分自身にコピーする必要があり、発信呼び出しを行う必要があります。
重要!
Bitrix24サーバーでSSL証明書を構成する必要があります(letsencryptを使用できます)。そうしないと、Bitrix APIは機能しません。 クラウドバージョンを使用している場合は、心配しないでください。SSLは既に存在します。
重要!
[ハンドラアドレス]フィールドに、インターネットアドレスからアクセスできることを示す必要があります。
最後に、CallMeOutを呼び出し用のアプリケーションとしてインストールします(PBXの番号をクリックすることで、呼び出しを行うためのコマンドが表示されます)。
メニューで、[その他]-> [テレフォニー]-> [その他]-> [設定]を選択し、「デフォルトの発信番号」を入力します。アプリケーション:CallMeOut、[保存]をクリックします。
![](https://habrastorage.org/webt/wl/ki/r8/wlkir8agmixr4lvmnezvdrqtaoo.png)
アスタリスクを構成する
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}); } };
最初から始めましょう: globalsディレクティブ。
URLRECORDS変数は、会話記録ファイルへの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 => { 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に送信します。
そしてもう少し魔法-着信コール:
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(); }
ここで興味があるのは1行だけです。
ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp());
彼女は、 CallerID(名前)を変数CallMeCallerIDNameに設定するようにPBXに指示します。
CallMeCallerIDName変数自体は、CallMeアプリケーションによって順番に設定されます(Bitrix24に発信者の番号のフルネームがある場合、 CallerID(name)として設定します、いいえ、何もしません)。
アプリケーションのセットアップ
アプリケーション設定ファイル-/var/www/pbx.vistep.ru/config.php
アプリケーション設定の説明:
- CallMeDEBUG -1の場合、アプリケーションによって処理されたすべてのイベントがログファイルに書き込まれます、0-何も書き込まない
- tech -SIP / PJSIP / IAX /など
- authToken - Bitrix24認証トークン、発信webhook認証コード
- bitrixApiUrl-プロファイルなしの着信WebhookのURL /
- 拡張 -外部番号のリスト
- context-元の呼び出しのコンテキスト
- listener_timeout-アスタリスクからのイベント処理速度
- アスタリスク -アスタリスク接続設定の配列:
- host-アスタリスクサーバーの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は、着信呼び出しを監視し、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
おわりに
それは非常に難しいことが判明しましたが、経験豊富な管理者が自宅でユーザーを実装し、満足させることができると確信しています。
約束どおり、 githubにリンクします。
ご質問、ご要望-コメントしてください。 また、この統合の開発がどのように行われているかに興味がある場合は、書いてください。次の記事では、すべてをより詳細に開示するようにします。