アスタリスク:日常生活でのAELの使用

画像



今日は、アスタリスクとCRMシステムの統合についてお話します。 CRM側からは、問題を考慮しません。CRMがすべての呼び出し(着信、発信、転送の両方)について知りたいことを知るだけで十分です。



取得したいもの:



呼び出しごとに、開始と停止の2つのイベントをCRMに送信する必要があります。 当然、多くの引数があります。



これを行うには、shスクリプトを呼び出します。



System(/etc/asterisk/scripts/crm.sh start ${GROUP} ${DSTNUM} ${CIDNUM} ${ID});   System(/etc/asterisk/scripts/crm.sh stop ${GROUP} ${DSTNUM} ${CIDNUM} ${ID} ${CDUR}); 
      
      





スクリプト自体の内容は興味深いものではありません。唯一の点は、これらの引数をCRM自体に渡し、時には何かを返すことさえあるということです。



 ${GROUP} -  / ${DSTNUM} - ,     (   popup   ) ${CIDNUM} -   ${ID} - ID  (      ,     ).   ID   ${UNIQUEID}    ${CDUR} -  
      
      





これら2つのスクリプトをマクロに書き込みます(ael workのマクロはextensions.confとは少し異なる方法で呼び出され、Gosubコマンドが使用されます。たとえば、サブスクライバーBが電話をピックアップするときのDialコマンドでマクロを呼び出す場合は、このことを知っておく必要がありますつまり、extensions.confのようにM(x)ではなく、U(x)を使用します)



 macro crm (GROUP, DSTNUM, CIDNUM, ID) { System(/etc/asterisk/scripts/crm.sh start ${GROUP} ${DSTNUM} ${CIDNUM} ${ID}); return; } macro crm-end (GROUP, DSTNUM, CIDNUM, ID) { MSet(CDUR=${CDR(billsec)}); System(/etc/asterisk/scripts/crm.sh stop ${GROUP} ${DSTNUM} ${CIDNUM} ${ID} ${CDUR}); return; }
      
      





発信通話の組織では、タスクは初歩的であることが判明したため、リストのみを提供します。



 context outgoing { _X. => { Set(GROUP=office1); Set(DSTNUM=${EXTEN}); Set(CIDNUM=${CALLERID(num)}); Set(ID=${UNIQUEID}); &record-crm(${STRFTIME(,,%G/%m/%d/)}${ID}); &crm(${GROUP},${DSTNUM},${CIDNUM},${ID}); Dial(SIP/trunk/${DSTNUM}); }; }
      
      





着信コールを処理するためのルールはもう少し興味深いものです。 内線番号をダイヤルするという提案を歓迎します。番号がダイヤルされていない場合は、CRMに呼び出しを送信します。



 context inc { 2758725 => { MSet(DSTNUM=${EXTEN}); MSet(GLOBAL(GROUP)=office1); Gosub(inc-crm,s,1(${EXTEN},${CALLERID(num)},${UNIQUEID})) ; }; } context inc-crm { s => { MSET(DSTNUM=${ARG1}); MSET(GLOBAL(CIDNUM)=${ARG2}); MSet(GLOBAL(ID)=${ARG3}); Background(welcome_message); &crm(${GROUP},${DSTNUM},${CIDNUM},${ID}); Gosub(redirect,${DB(crm/key)},1); }; }
      
      





着信コールに複数の番号がある場合、context incが必要です。変数の一部をグローバルに割り当てます。これは、変数がダイヤルプランのさまざまな部分に付随するためです。

&crm($ {GROUP}、$ {DSTNUM}、$ {CIDNUM}、$ {ID});

最初のリクエストをCRMに送信します。 クライアントが通常の場合、CRMは担当マネージャーの番号を返し、スクリプトはそれをAstDB(アスタリスク-rx“ database put crm key XXX”)に書き込みます。 クライアントが新規であるか、責任マネージャーが彼に割り当てられていない場合、CRMはグループ/キュー番号を返します(これは、開始/停止要求の送信に関して少し面倒でした)

CRMから大切な数字の組み合わせを受け取ったら、次に進みます。



 context redirect { 1000 => { &record-crm(${STRFTIME(,,%G/%m/%d/)}${ID}); &crm-group(${QUEUE_MEMBER_LIST(first)},,); Queue(first,tT,,,15,,,set-arg); }; _1XX => { &record-crm(${STRFTIME(,,%G/%m/%d/)}${ID}); &crm(${GROUP},${DSTNUM},${CIDNUM},${ID}); Dial(SIP/${EXTEN}); }; h => { NoOP(${MEMBERINTERFACE}); if ( ${EXISTS(${MEMBERINTERFACE})} ) { MSet(DSTNUM=${MEMBERINTERFACE:4}); &crm-end(${GROUP},${DSTNUM},${CIDNUM},${ID}); Hangup; }; &crm-group-end(${QUEUE_MEMBER_LIST(first)},,); }; }
      
      





1000-グループ番号。キューはここで呼び出されます。 この例では、キューは3人のエージェントに制限されます。 キューエージェントの数を増やしたい場合は、$ {QUEUE_MEMBER_LIST(first)}の後にカンマを追加し、マクロcrm-group / crm-group-endの数行を追加します。 マクロを呼び出すにはカンマが必要です。 マクロが期待する数の引数を渡す必要があります。より正確には、より多くの引数を渡すことができますが、ダイヤルプランでこれに言及すると、それは誓い、機能しません。 $ {QUEUE_MEMBER_LIST(first)}キューにエージェントが含まれています。最終的に、マクロに3つ以上の引数(エージェント+ 2つの空の引数)を渡すことがわかりますが、これは問題ではなくなりました。 ここでの主なことは、マクロで受け入れられている引数よりも多くのエージェントが存在しないことです。そうでない場合、全員がポップアップウィンドウを取得するわけではありません。



 macro crm-group ( member1, member2, member3 ) { if (${EXISTS(${member1:4})) { MSet(DSTNUM=${member1:4})); &crm(${GROUP},${DSTNUM},${CIDNUM},${ID}); }; if (${EXISTS(${member2:4})) { MSet(DSTNUM=${member2:4}); &crm(${GROUP},${DSTNUM},${CIDNUM},${ID}); }; if (${EXISTS(${member3:4})) { MSet(DSTNUM=${member3:4}); &crm(${GROUP},${DSTNUM},${CIDNUM},${ID}); }; return; }
      
      





エージェントが存在するかどうかを確認し、エージェントを受信コールとして割り当て、ポップアップウィンドウを表示するリクエストを送信します。



その後、最初にキューを呼び出します



 Queue(first,tT,,,15,,,set-arg);
      
      





ここでの主なことは、コンマと混同しないことです。 Habrのルールでは、絵文字/角かっこを使用すべきではないと言っているようですが、ここでは抵抗できませんでした=)

set-argマクロはGosubコマンドによって呼び出されます;マクロがextensions.confに書き込まれている場合、呼び出しはより早くコンマに書き込まれます。



 macro set-arg () { &crm-group-end(${QUEUE_MEMBER_LIST(first)},,); return; }
      
      





キューチームから引数を渡すことができなかったため、この小さなマクロに頼らなければなりませんでした。



 macro crm-group-end ( member1, member2, member3 ) { if ( ${EXISTS(${member1:4}) ) { if (${member1:4}!=${CHANNEL(peername)}){ MSet(DSTNUM=${member1:4}); &crm-end(${GROUP},${DSTNUM},${CIDNUM},${ID}); }; }; if ( ${EXISTS(${member2:4}) ) { if (${member2:4}!=${CHANNEL(peername)}){ MSet(DSTNUM=${member2:4}); &crm-end(${GROUP},${DSTNUM},${CIDNUM},${ID}); }; }; if ( ${EXISTS(${member3:4}) ) { if (${member3:4}!=${CHANNEL(peername)}){ MSet(DSTNUM=${member3:4}); &crm-end(${GROUP},${DSTNUM},${CIDNUM},${ID}); }; }; return; }
      
      





繰り返しますが、開始リクエストの場合と同様に、エージェントの可用性をチェックし、キューエージェントを電話を拾った人($ {CHANNEL})と比較し、一致がなければ停止を送信します(ポップアップウィンドウはもう必要ありません)。



マネージャーはクライアントと話をし、会話は終わりました。これについてCRMに通知する必要があります。 リダイレクトコンテキストに戻る



 h => { if ( ${EXISTS(${MEMBERINTERFACE})} ) { MSet(DSTNUM=${MEMBERINTERFACE:4}); &crm-end(${GROUP},${DSTNUM},${CIDNUM},${ID}); Hangup; }; &crm-group-end(${QUEUE_MEMBER_LIST(first)},,); };
      
      





ここで、$ {MEMBERINTERFACE}の存在、つまり、コールがエージェントの1つによって処理されたかどうかを確認します。処理された場合、このエージェントのCRM停止に送信します。コールが失敗した場合、キュー内のすべてのエージェントに停止を送信します。

通話を転送するオプションを検討する必要があります。 翻訳中にクライアントが失われないように、在席転送を使用します(features.confで#を割り当てました)。 CRMにリクエストを送信する機能で転送を補完するために、そのコンテキストを再割り当てします。 私の場合、グローバルセクションにTRANSFER_CONTEXT = transferを追加しただけなので、これはすべての呼び出しに対して行われます。



コンテキスト自体に進みましょう。

 context transfer { _1XX => { MSET(DSTNUM=${EXTEN}); &crm(${GROUP},${DSTNUM},${CIDNUM},${ID}); Dial(SIP/${DSTNUM}); }; h => { &crm-end(${GROUP},${DSTNUM},${CIDNUM},${ID}); }; }
      
      





着信コールを受信し、#100を押すと、番号100(コールの転送先)とクライアント番号を持つCRMに開始されます。 番号100のマネージャーはポップアップウィンドウを受け取り、同僚はクライアントの気分についていくつかの言葉を追加して電話を切ることができます。 転送は完璧です。 この時点で、あるマネージャーから別のマネージャーを呼び出すための停止要求が送信されます。



マネージャーとクライアントとの会話の最後に、2人の停止要求が送信されます-最初のマネージャーと2番目のマネージャーは両方ともクライアントと話しているためです。



作成者: Centos-admin.ru artzcomシステム管理者。



All Articles