DavidLiu 3 ay önce
ebeveyn
işleme
2854def952

+ 3 - 3
src/core/callcenter/acd.py

@@ -12,7 +12,7 @@ from src.core.callcenter.api import CallInfo, AgentActionRequest, DelayAction
 from apscheduler.schedulers.background import BackgroundScheduler
 from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED, FIRST_COMPLETED
 
-from src.core.callcenter.constant import saasId
+from src.core.callcenter.constant import SAAS_ID
 from src.core.callcenter.enumeration import AnswerFlag, DelayActionEnum
 
 
@@ -42,7 +42,7 @@ class AcdService:
             self.call_service.hold(call_id, device_id)
             self.wait_timeout(call_id)
         # 获得空闲坐席
-        agent_number = self.agent_service.assign(AgentActionRequest(saas_id=saasId, service_id=service_id))
+        agent_number = self.agent_service.assign(AgentActionRequest(saas_id=SAAS_ID, service_id=service_id))
         if not agent_number:
             # 如果没有空闲坐席,播放等待音
             text = "AcdService transferToAgent agentNumber is empty serviceId:%s,called:%s,callId:%s"%(service_id, call_info.called, call_info.call_id)
@@ -88,7 +88,7 @@ class AcdService:
                 # print("AcdService tryTransferAgent callInfoCache is null ", call_id)
                 self.logger.info("AcdService tryTransferAgent callInfoCache is null %s", call_id)
                 continue
-            agent_number = self.agent_service.assign(AgentActionRequest(saas_id=saasId, service_id=task_service_id))
+            agent_number = self.agent_service.assign(AgentActionRequest(saas_id=SAAS_ID, service_id=task_service_id))
             if not agent_number:
                 text = "AcdService tryTransferAgent agentNumber is Empty %s %s"% (call_id, json.dumps(call_info.device_list))
                 # print(text, flush=True)

+ 20 - 0
src/core/callcenter/agent.py

@@ -16,6 +16,7 @@ from src.core import with_app_context
 from src.core.callcenter.api import AgentActionRequest, AgentQueryRequest, AgentRequest, AgentEventData, \
     AgentStateData, HumanServiceQueryRequest, AgentMonitorData, CallInfo, DeviceInfo, AgentDelayStateData
 from src.core.callcenter.cache import Cache
+from src.core.callcenter.constant import CENTER_AGENT_HEARTBEAT, SAAS_ID
 from src.core.callcenter.dao import *
 from src.core.callcenter.data_handler import DataHandleServer
 from src.core.callcenter.enumeration import AgentState, AgentCheck, AgentHeartState, AgentServiceState, AgentLogState, \
@@ -772,6 +773,22 @@ class AgentStateService:
         self.agent_monitor_service = AgentMonitorService(app)
         self.agent_actionlog_service = AgentActionLogService(app)
 
+        self.daemon_stopping = False
+        self.agent_heartbeat_expire = 30
+        threading.Thread(target=self.agent_heartbeat_daemon).start()
+
+    def agent_heartbeat_daemon(self):
+        while not self.daemon_stopping:
+            key = CENTER_AGENT_HEARTBEAT % SAAS_ID
+            members = self.redis_handler.redis.hgetall(key)
+            if not members:
+                continue
+            for k, v in members.items():
+                sec = datetime.now().timestamp() - float(v)
+                if sec > self.agent_heartbeat_expire:
+                    self.logger.error("agent heartbeat expired, %s %s", k, v)
+                    self.busy(SAAS_ID, k, k)
+
     def idle(self, saas_id, agent_id, phone_num):
         human_service = self.data_handle_server.get_human_service_service(saas_id, agent_id)
         if human_service is None:
@@ -976,3 +993,6 @@ class AgentStateService:
         idle_agents = sorted(idle_agents, key=lambda agent: agent.assign_time, reverse=False)
         return idle_agents[0].phone_num
 
+    def __del__(self):
+        self.daemon_stopping = True
+

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

@@ -186,7 +186,7 @@ class AgentDelayStateData(BaseApi):
 
 class HangupCallRequest(BaseApi):
     def __init__(self, saas_id=None, flow_id=None, agent_id=None, called=None, call_id=None, scene=None):
-        # saasId(必填)
+        # SAAS_ID(必填)
         self.saas_id = saas_id
         self.flow_id = flow_id
         # 呼叫唯一id(选填)

+ 2 - 2
src/core/callcenter/call.py

@@ -7,7 +7,7 @@ from datetime import datetime
 from src.core.callcenter import registry
 from src.core.callcenter.agent import AgentMonitorService, AgentActionLogService
 from src.core.callcenter.cache import Cache
-from src.core.callcenter.constant import saasId, HOLD_MUSIC_PATH
+from src.core.callcenter.constant import SAAS_ID, HOLD_MUSIC_PATH
 from src.core.callcenter.enumeration import CallCause, Direction, NextType, DeviceType, CdrType, AgentServiceState, \
     AgentScene, WorkStatus, AgentLogState, ServiceDirect
 from src.core.callcenter.api import AgentCallRequest, CallInfo, HangupCallRequest, CheckInCallRequest, \
@@ -43,7 +43,7 @@ class CallService:
                              caller=agent.agent_number, called=request.called, direction=Direction.OUTBOUND.code,
                              caller_display=request.caller_display, called_display=request.called_display,
                              call_type=request.call_type, call_time=now, follow_data=request.follow_data,
-                             uuid1=request.uuid1, uuid2=request.uuid2, saas_id=saasId,
+                             uuid1=request.uuid1, uuid2=request.uuid2, saas_id=SAAS_ID,
                              core_uuid=None, conference=None, group_id=None, hidden_customer=0, number_location=None, agent_name=None, login_type=None, ivr_id=None, task_id=None, media_host=None, client_host=None, record=None, record2=None, record_time=None, answer_flag=None, wait_time=None, answer_count=0, hangup_dir=None, sdk_hangup=0, hangup_code=None, answer_time=None, end_time=None, talk_time=None, first_queue_time=None, queue_start_time=None, queue_end_time=None, overflow_count=0, cdr_notify_url=None, queue_level=None, transfer_agent=None, device_list=[], device_info_map = {}, process_data = {}, next_commands=[], call_details=[])
         device_info = DeviceInfo(cti_flow_id=request.cti_flow_id, device_id=device_id, call_time=now, call_id=call_id, device_type=DeviceType.AGENT.code,
                                  agent_key=agent.agent_number, caller_display=route_gateway.name, cdr_type=CdrType.INBOUND.code,

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

@@ -5,7 +5,7 @@ import json
 
 from src.core.callcenter.enumeration import CallStage, CallType
 
-saasId = "mdj"
+SAAS_ID = "mdj"
 
 UTF_8 = "UTF-8"
 SPACE = " "

+ 2 - 2
src/core/callcenter/esl/client.py

@@ -17,7 +17,7 @@ from src.core.callcenter import BizException
 from src.core.callcenter.cache import Cache
 from src.core.callcenter.api import MakeCallContext, DelayAction, CallInfo, DeviceInfo, NextCommand
 from src.core.callcenter.callback import Callback
-from src.core.callcenter.constant import SK, EMPTY, WaitingHangupMusicPath, saasId, HOLD_MUSIC_PATH
+from src.core.callcenter.constant import SK, EMPTY, WaitingHangupMusicPath, SAAS_ID, HOLD_MUSIC_PATH
 from src.core.callcenter.esl.constant.esl_constant import BRIDGE_VARIABLES, BRIDGE, HANGUP, NORMAL_CLEARING, SIP_HEADER, \
     SPACE, SOFIA, \
     ORIGINATE, PARK, SET, EAVESDROP, SMF_ALEG, EXECUTE, PLAYBACK, PAUSE, TRANSFER, UUID_TRANSFER, UUID_BROADCAST, \
@@ -596,7 +596,7 @@ class OutboundClient:
             call_info = CallInfo(call_id=call_id, agent_key=destination,
                                  caller=caller, called=called, direction=Direction.INBOUND.code,
                                  call_type=call_type, call_time=now,
-                                 uuid1=call_id, uuid2=device_id, saas_id=saasId, bucket_type=bucket_type,
+                                 uuid1=call_id, uuid2=device_id, saas_id=SAAS_ID, bucket_type=bucket_type,
                                  core_uuid=None, cti_flow_id=None, conference=None, group_id=None, hidden_customer=0, caller_display=None, called_display=None, number_location=None, agent_name=None, login_type=None, ivr_id=None, task_id=None, media_host=None, sip_server=None, client_host=None, record=None, record2=None, record_time=None, answer_flag=None, wait_time=None, answer_count=0, hangup_dir=None, sdk_hangup=0, hangup_code=None, answer_time=None, end_time=None, talk_time=None, first_queue_time=None, queue_start_time=None, queue_end_time=None, overflow_count=0, cdr_notify_url=None, queue_level=None, transfer_agent=None,device_list=[], device_info_map = {}, follow_data = {}, process_data = {}, next_commands=[], call_details=[])
             device_custom = DeviceInfo(device_id=device_id, call_time=now,
                                      call_id=call_id, device_type=DeviceType.CUSTOMER.code,