発信通話の1日あたりの個別の制限(有料ルートの制限)

この記事では、FreePBXの非典型的な問題をどのように解決したかを説明したいと思います。 「典型的ではない」という定義では、追加のツールなしでは標準的な手段では解決できないことを意味します。



背景



顧客を呼び出すことに従事している従業員のグループがあります。 発信通話を節約するために、異なる方向に異なる電話番号が使用されます。 これは、アウトバウンドルートの番号のテンプレート(マスク)を使用して簡単に解決できます。 ただし、モバイルへの通話などの指示の一部は、まだ支払われていません。 そのため、月末に会社の電話サービスの請求額がXXXドルを超えないように、対応する通話の方向を厳密に制御し、必要に応じて制限する必要があります。



挑戦する



マネージャーのグループに個別の1日の制限を設定します。 制限を使い果たした場合、特定の宛先への発信呼び出しを拒否します。 しきい値に達すると、> 50%、> 90%、> 100%が従業員のメールに通知を送信します。 従業員が1日の1日の制限を完全に使い果たしていない場合、残高は翌日に移動します。



はじめに



最初に、ダイヤルを制限する番号を決定する必要があります。 私たちの場合、これらはカザフスタンの携帯電話会社です。 対応するウィキペディアの記事を見つけ、番号テンプレート(マスク)を作成しようとします。 FreePBXには本格的な正規表現を使用する機能がないため、23の可能なプレフィックスを3つのパターンにパックできました。



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
      
      







主なパラメーターの説明:



内線番号2055がすでにわかっているVasya Pupkinを作成しましょう。







メインシステムの形成に進みます。ロジックは次のとおりです。



対応する内部番号のブロックの位置を保存するために、次の形式のXMLファイルを作成します。



XML
 <?xml version="1.0" encoding="UTF-8" ?> <bocks> <!-- BLOCKS START --> <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クエリと神聖なコード。

 #  import send_email import flags print ('###########START_MOBILE_LIMIT############') import pymysql mainconn = pymysql.connect(host='10.10.2.1', user='user', passwd='password', db='asteriskcdrdb', charset='utf8') maincur = mainconn.cursor() maincur.execute("""SELECT SUM(billsec) AS sec, src FROM cdr WHERE disposition = 'ANSWERED' AND (dst LIKE '8700%' OR dst LIKE '8701%' OR dst LIKE '8702%' OR dst LIKE '8705%' OR dst LIKE '8707%' OR dst LIKE '8708%' OR dst LIKE '8747%' OR dst LIKE '8771%' OR dst LIKE '8775%' OR dst LIKE '8776%' OR dst LIKE '8777%' OR dst LIKE '8778%') AND DATE(calldate) = DATE(CURDATE()) AND src in (2055,2066,2077) GROUP BY src;""") row = maincur.fetchone() print ('ROW COUNT: ' + str(self.maincur.rowcount)) while row is not None: #row[1] -   #row[0] -     #   flags.UpdateUserCurrentLimit(str(row[1]), str(row[0])) per = row[0] * 100 / flags.checkUserLimit(row[1]) flag = flags.checkFlag(row[1]) #   ,      manager_mail = send_email.getEmail(row[1]) # %   print (row[1] + ' (' + str(round(per,0)) + '%): ' + str(row[0])) #  if per >= 50 and per < 90: message = 'Nomer ' + row[1] + ', limit ischerpan na ' + str(round(per, 0)) + '%' if flag == 0: print ('go email to ' + send_email.getEmail(row[1])) send_email.send_message(manager_mail, message) flags.changeFlag(row[1], 1) flags.insertLog(row[1], per) print (message) elif per > 90 and per < 100: message = 'Nomer ' + row[1] + ', limit ischerpan na ' + str(round(per, 0)) + '%' if flag == 1: print ('go email to ' + send_email.getEmail(row[1])) send_email.send_message(manager_mail, message) flags.changeFlag(row[1], 2) flags.insertLog(row[1], per) print (message) elif per >= 100: message = 'Nomer ' + row[1] + ', limit polnostiu ischerpan' if flag != 3: print ('go email to ' + send_email.getEmail(row[1])) send_email.send_message(manager_mail, message) flags.changeFlag(row[1], 3) flags.insertLog(row[1], per) #     flags.commentBlocks(str(row[1])) import subprocess #     subprocess.call(['./dialplan_reload.sh']) print (message) row = maincur.fetchone() maincur.close() mainconn.close() print ('############END_MOBILE_LIMIT#############')
      
      







営業日の終わりに、未使用の制限を追加します。



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() ############################################ cur.execute (""" UPDATE users SET mobile_limit_flag=%s """, (0))
      
      







起こりうる問題を解決するには、制限しきい値の変更に関するログデータに書き込みます。



LOG
 #    def insertLog(ext, per): import pymysql conn = pymysql.connect(host='10.10.2.1', user='user', passwd='password', db='crm', charset='utf8') cur = conn.cursor() cur.execute (""" INSERT INTO mobile_limit (extension, percent) VALUES (%s, %s) """, (ext, per)) conn.commit() print('insert', cur.rowcount) cur.close() conn.close()
      
      







ここに問題の曲がった解決策があります。 スクリプト2.0のバージョンでは、許可ブロックを動的に生成します。これにより、変更を加えてもシステムをより柔軟に使用できるようになります。



All Articles