Browse Source

fix: 白名单

余尚辉 4 months ago
parent
commit
0f4d5f458d
3 changed files with 48 additions and 21 deletions
  1. 42 13
      src/core/callcenter/esl/client.py
  2. 1 1
      src/core/callcenter/views.py
  3. 5 7
      src/core/voip/bot.py

+ 42 - 13
src/core/callcenter/esl/client.py

@@ -479,17 +479,39 @@ class InboundClient:
 
 class OutboundClient:
 
-    def __init__(self, agent, logger):
+    def __init__(self, agent, logger,app):
         self.logger = logger
-        # self.whitelist = self.load_whitelist()
+        self.app = app
+        self.whitelist = []
+        self.update_whitelist()  # 初始化加载白名单
+
+        # 定时更新白名单
+        threading.Thread(target=self.refresh_whitelist, daemon=True).start()
+
         #threading.Thread(target=self.start, args=('0.0.0.0', 8084, agent, logger)).start()
         server_thread = threading.Thread(target=self.start, args=('0.0.0.0', 8084, agent, logger))
         server_thread.daemon = True  # 设置守护线程
         server_thread.start()
+
+    def update_whitelist(self):
+        with self.app.app_context():
+            phones = Whitelist.query.filter_by(del_flag=0).all()
+            self.whitelist = [phone.phone for phone in phones]
+            self.logger.info("Whitelist updated: %s", self.whitelist)
+
+    def refresh_whitelist(self):
+        while True:
+            time.sleep(3600) # 每 1小时 更新一次
+            self.update_whitelist()
+
     def load_whitelist(self):
-        phones = Whitelist.query.filter_by(del_flag=0).all()
-        phone_list = [phone.phone for phone in phones]
-        return phone_list
+        return self.whitelist
+
+    def load_agent_monitor(self):
+        with self.app.app_context():
+            agents = AgentMonitor.query.filter_by(check_state=0,service_state=2).all()
+            agent_nums = [agent.agent_num for agent in agents]
+            return agent_nums
 
     class ESLRequestHandler(socketserver.BaseRequestHandler):
         def setup(self):
@@ -504,14 +526,19 @@ class OutboundClient:
                     # print(json.loads(info.serialize('json')))
                     event_name = info.getHeader("Event-Name")
                     device_id = info.getHeader("unique-id")
-                    # caller_number = info.getHeader("Caller-Caller-ID-Number")  # 获取来电号码
+                    caller_number = info.getHeader("Caller-Caller-ID-Number")  # 获取来电号码
+                    whitelist = self.server.load_whitelist()
+                    agents = self.server.load_agent_monitor()
+                    # 直接转接到人工坐席
 
                      # 检查白名单
-                    # if caller_number in self.server.whitelist:
-                    #     self.server.logger.info("Caller %s is in whitelist, directly transferring call.", caller_number)
-                    #     # 直接转接到指定用户
-                    #     print('come in whitelist')
-                    #     return
+                    if caller_number in whitelist:
+                        # 随机取一个坐席号
+                        destination = random.choice(agents)
+                        # 直接转接到人工坐席
+                        self.server.logger.info("Caller %s is in whitelist, directly transferring call, agents: %s, destination: %s", caller_number, agents,destination)
+                        return
+                    
 
                     call_id = 'C' + str(Snowflake().next_id())
                     new_device_id = 'D' + str(Snowflake().next_id())
@@ -572,14 +599,16 @@ class OutboundClient:
 
 
     class CustomTCPServer(socketserver.TCPServer):
-        def __init__(self, server_address, RequestHandlerClass, agent, logger):
+        def __init__(self, server_address, RequestHandlerClass, agent, logger,whitelist_loader,load_agent_monitor):
             self.agent = agent
             self.logger = logger
+            self.load_whitelist = whitelist_loader
+            self.load_agent_monitor = load_agent_monitor
             super().__init__(server_address, RequestHandlerClass)
 
     def start(self, HOST='0.0.0.0', PORT=8084, agent=None, logger=None):
         # HOST, PORT = "0.0.0.0", 8084
         # 创建一个 TCP 服务器
-        with self.CustomTCPServer((HOST, PORT), self.ESLRequestHandler, agent, logger) as server:
+        with self.CustomTCPServer((HOST, PORT), self.ESLRequestHandler, agent, logger, self.load_whitelist, self.load_agent_monitor) as server:
             self.logger.info(f"ESL server listening on {HOST}:{PORT}")
             server.serve_forever()

+ 1 - 1
src/core/callcenter/views.py

@@ -16,7 +16,7 @@ from src.core.voip.bot import BotAgent
 
 agent = BotAgent(app.logger)
 inbound_client = InboundClient(agent, app.logger)
-outbound_client = OutboundClient(agent, app.logger)
+outbound_client = OutboundClient(agent, app.logger,app)
 call_service = CallService(inbound_client, app.logger)
 agent_service = AgentService(inbound_client, app.logger)
 agent_oper_service = AgentOperService(inbound_client, app.logger)

+ 5 - 7
src/core/voip/bot.py

@@ -78,9 +78,9 @@ class MyAudioMediaPort(pj.AudioMediaPort):
             if self.call.inputType == '1.0':
                 time_difference = int(current_time - self.call.inputLongStart)
                 # print('current_time - self.call.inputLongStart:',time_difference > 35, self.call.txtLock , play_complete)
-                if int(current_time - self.call.inputLongStart) > 35 and play_complete and asr_text:
+                if time_difference > 35 and play_complete:
                     self.user_asr_texts.append(f"DTMF({self.call.digit})DTMF")
-                    user_asr_text = asr_text if len(self.user_asr_texts) == 1 else '###'.join(self.user_asr_texts)
+                    user_asr_text = self.user_asr_texts[0] if len(self.user_asr_texts) == 1 else '###'.join(self.user_asr_texts)
                     self.user_asr_texts.clear()
                     self.call.chat(user_asr_text)
                     # print("测试超长", user_asr_text)
@@ -92,10 +92,9 @@ class MyAudioMediaPort(pj.AudioMediaPort):
                 if asr_text and not play_complete:
                     self.user_asr_texts.append(asr_text)
                 if (asr_text and play_complete) or (play_complete and self.user_asr_texts):
-                    if asr_text:  # 等价于 if asr_text is not None and asr_text != ""
+                    if asr_text:
                         self.user_asr_texts.append(asr_text)
-                    # self.user_asr_texts.append(asr_text)
-                    user_asr_text = asr_text if len(self.user_asr_texts) == 1 else '###'.join(self.user_asr_texts)
+                    user_asr_text = self.user_asr_texts[0] if len(self.user_asr_texts) == 1 else '###'.join(self.user_asr_texts)
                     self.user_asr_texts.clear()
                     self.call.chat(user_asr_text)
 
@@ -108,7 +107,6 @@ class MyAudioMediaPort(pj.AudioMediaPort):
                 self.call.cur_player_file, self.call.wait_time, self.call.inputType,self.call.action, self.call.node_id = self.get_player_file()
                 # 重置播放完成标志和超时计时器,确保新的播放从头开始计时
                 self.call.reset_wait_time()
-                # self.call.txtLock = False
                 self.call.send_bot_speaker(self.call.cur_player_file)
         except:
             pass
@@ -232,7 +230,6 @@ class MyCall(pj.Call):
     def reset_wait_time(self):
         self.play_complete_flag = False  # 重置播放完成标志
         self.play_start_time = None  # 重置开始计时时间
-        self.digit = ''
     def get_phone(self):
         import re
         call_info = self.getInfo()
@@ -336,6 +333,7 @@ class MyCall(pj.Call):
     def on_media_player_complete(self, player_id):
         print('player complete')
         self.player_complete_dict[player_id] = True
+        self.digit = ''
         self.inputLongStart = time.time()
         #播放完毕执行的动作
         self.say_end_action(self.action)