この記事では、FreePBXの非典型的な問題をどのように解決したかを説明したいと思います。 「典型的ではない」という定義では、追加のツールなしでは標準的な手段では解決できないことを意味します。
背景
顧客を呼び出すことに従事している従業員のグループがあります。 発信通話を節約するために、異なる方向に異なる電話番号が使用されます。 これは、アウトバウンドルートの番号のテンプレート(マスク)を使用して簡単に解決できます。 ただし、モバイルへの通話などの指示の一部は、まだ支払われていません。 そのため、月末に会社の電話サービスの請求額がXXXドルを超えないように、対応する通話の方向を厳密に制御し、必要に応じて制限する必要があります。
挑戦する
マネージャーのグループに個別の1日の制限を設定します。 制限を使い果たした場合、特定の宛先への発信呼び出しを拒否します。 しきい値に達すると、> 50%、> 90%、> 100%が従業員のメールに通知を送信します。 従業員が1日の1日の制限を完全に使い果たしていない場合、残高は翌日に移動します。
はじめに
最初に、ダイヤルを制限する番号を決定する必要があります。 私たちの場合、これらはカザフスタンの携帯電話会社です。 対応する
ウィキペディアの記事を見つけ、番号テンプレート(マスク)を作成しようとします。 FreePBXには本格的な
正規表現を使用する機能がないため、23の可能なプレフィックスを3つのパターンにパックできました。
- 870 [5780-2] XXXXXXX
- 877 [15-8] XXXXXXX
- 8747XXXXXXX
Outbound Routesに適切なエントリを作成します。 この例では、内線番号2055の指示を開きます。

これを行うことで、対応するルールが構成ファイルに作成されます。
/etc/asterisk/extensions_additional.conf
FreePBXで設定を編集および適用すると、システムは毎回構成ファイルを上書きするため、必要なブロックを見つけてファイルに移動します。
/etc/asterisk/extensions_custom.conf
FreePBXはクロールしません。
ブロックは次のとおりです。
往路 exten => _877[15-8]XXXXXXX,1,Macro(user-callerid,LIMIT,EXTERNAL,) exten => _877[15-8]XXXXXXX/2055,1,Macro(user-callerid,LIMIT,EXTERNAL,) exten => _877[15-8]XXXXXXX/2055,n,ExecIf($[ "${CALLEE_ACCOUNCODE}" != "" ] ?Set(CDR(accountcode)=${CALLEE_ACCOUNCODE})) exten => _877[15-8]XXXXXXX/2055,n,Set(MOHCLASS=${IF($["${MOHCLASS}"=""]?default:${MOHCLASS})}) exten => _877[15-8]XXXXXXX/2055,n,ExecIf($["${KEEPCID}"!="TRUE" & ${LEN(${TRUNKCIDOVERRIDE})}=0]?Set(TRUNKCIDOVERRIDE=<7123456789>)) exten => _877[15-8]XXXXXXX/2055,n,Set(_NODEST=) exten => _877[15-8]XXXXXXX/2055,n,Gosub(sub-record-check,s,1(out,${EXTEN},)) exten => _877[15-8]XXXXXXX/2055,n,Macro(dialout-trunk,10,${EXTEN},,off) exten => _877[15-8]XXXXXXX/2055,n,Macro(outisbusy,)
アスタリスクの構成の構文に慣れている場合は、前の2つの手順をスキップして、自分で必要なブロックを作成できます。
これで、以前に作成したアウトバウンドルートを削除できるようになり、必要な許容ルールがextensions_custom.confに含まれるようになりました。 したがって、従業員がこれらのエリアに電話をかけることを許可しました。 さらにもっと。
制限は個別であり、通知をメールに送信する必要があるため、この情報をどこかに保存する必要があります。 より良い選択は、データベースを使用することです。 ここには2つのオプションがありました。
- 既存のアスタリスクデータベースを使用し、必要なフィールドをユーザーテーブルに追加します。
- 目的の構造のテーブルを使用してデータベースを作成します。
選択はオプション番号2に当てはまり、次のような結果になりました。
SQL Create table CREATE TABLE `users` ( `user_id` int(11) NOT NULL AUTO_INCREMENT, `user_name` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT ' ', `extension` varchar(5) CHARACTER SET utf8 DEFAULT '000' COMMENT ' ', `mobile_limit_flag` int(11) DEFAULT '0' COMMENT ' ', `mobile_limit` int(11) DEFAULT '0' COMMENT ' ', `base_mobile_limit` int(11) DEFAULT NULL COMMENT ' ', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
主なパラメーターの説明:
- base_mobile_limitは、一度に設定される個々のサブスクライバー制限(秒単位)を格納します。
- mobile_limitには、 未使用分を考慮した、現在の日の現在の制限が含まれます。
- mobile_limit_flagは、ユーザーが制限を超えたしきい値を決定します( 0-<50% 、 1-> 50および<90% 、 2-> 90%および<100% 、3-> 100%);
内線番号2055がすでにわかっているVasya Pupkinを作成しましょう。

メインシステムの形成に進みます。ロジックは次のとおりです。
- スケジュール(クラウン)に従って、スクリプトは各サブスクライバーが必要な方向にどれだけ話したかをチェックします。
- サブスクライバーが0.1または2のしきい値を超えた場合、mobile_limit_flagパラメーターは適切なパラメーターに変更され、電子メールメッセージが送信されます。
- サブスクライバが3のしきい値にある場合(制限が完全に使い果たされた場合)、対応する通知が電子メールで送信され、対応するブロックが構成ファイルでコメント化され、ダイヤルプランのリロードが実行されます。
対応する内部番号のブロックの位置を保存するために、次の形式のXMLファイルを作成します。
XML <?xml version="1.0" encoding="UTF-8" ?> <bocks> <block number="2055"> <element first="4" last="11"/> <element first="117" last="124"/> <element first="230" last="237"/> </block> <block number="2066"> <element first="14" last="21"/> <element first="127" last="134"/> <element first="240" last="247"/> </block> <block number="2077"> <element first="24" last="31"/> <element first="137" last="144"/> <element first="250" last="257"/> </block> <bocks>
携帯電話番号にアクセスするために3つのマスクを作成したため、各内線番号に対して3つの許可ブロックがあります。 XMLでは、これらの各ブロックの開始と終了の行番号を指定します。 次のコードを使用してそれらについてコメントします。
ブロックコメント機能 def commentBlocks(numb): import xml.etree.cElementTree as ET tree = ET.ElementTree(file='conf.xml') root = tree.getroot() f = open(r'extensions_custom.conf') lines = f.readlines() f.close() for elem in tree.iterfind('block[@number="'+numb+'"]/element'): lines[int(elem.get('first'))-2] = ";--\n" lines[int(elem.get('last'))] = "--;\n" f = open(r'extensions_custom.conf','w') f.writelines(lines) f.close()
そして実際に主な頭脳:
メインスクリプトたとえば、5分ごとなど、スケジュールに基づいて痙攣します。 ボーナスの壮大なSQLクエリと神聖なコード。
営業日の終わりに、未使用の制限を追加します。
AddUnusedLimit def AddUnusedLimit(ext): conn = pymysql.connect(host='10.10.2.2', user='user', passwd='password', db='crm', charset='utf8') cur = conn.cursor() cur.execute (""" UPDATE users SET mobile_limit=base_mobile_limit+mobile_limit WHERE extension=%s """, (ext)) conn.commit() print('changed', cur.rowcount) cur.close() conn.close()
mobile_limit_flagをデフォルト値の0に
リセットし、すべてのブロックのコメントを解除します。
uncommentBlocks def uncommentBlocks(): import xml.etree.cElementTree as ET tree = ET.ElementTree(file='conf.xml') root = tree.getroot() for elem in tree.iterfind('block/element'): first = int(elem.get('first')) last = int(elem.get('last')) lines[first-2] = "\n" lines[last] = "\n" f = open(r'/etc/asterisk/extensions_custom.conf') lines = f.readlines() f.close()
起こりうる問題を解決するには、制限しきい値の変更に関するログデータに書き込みます。
ここに問題の
曲がった解決策があります。 スクリプト2.0のバージョンでは、許可ブロックを動的に生成します。これにより、変更を加えてもシステムをより柔軟に使用できるようになります。