call.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #!/usr/bin/env python3
  2. # encoding:utf-8
  3. import json
  4. import time
  5. from datetime import datetime
  6. from src.core.callcenter import registry
  7. from src.core.callcenter.agent import AgentMonitorService, AgentActionLogService
  8. from src.core.callcenter.cache import Cache
  9. from src.core.callcenter.constant import SAAS_ID, HOLD_MUSIC_PATH
  10. from src.core.callcenter.enumeration import CallCause, Direction, NextType, DeviceType, CdrType, AgentServiceState, \
  11. AgentScene, WorkStatus, AgentLogState, ServiceDirect
  12. from src.core.callcenter.api import AgentCallRequest, CallInfo, HangupCallRequest, CheckInCallRequest, \
  13. DeviceInfo, NextCommand, MakeCallContext
  14. from src.core.callcenter.esl.constant.sip_header_constant import sipHeaderServiceId, sipHeaderCtiFlowId
  15. from src.core.callcenter.snowflake import Snowflake
  16. from src.core.callcenter.push import PushHandler
  17. from src.core.callcenter.data_handler import *
  18. class CallService:
  19. def __init__(self, client, app):
  20. self.client = client
  21. self.logger = app.logger
  22. self.cache = Cache(app)
  23. self.snowflake = Snowflake()
  24. self.push_handler = PushHandler(app.logger)
  25. self.data_handle_server=DataHandleServer(app)
  26. self.agent_monitor_service = AgentMonitorService(app)
  27. self.agent_actionlog_service = AgentActionLogService(app)
  28. def call(self, request: AgentCallRequest):
  29. call_id = 'C' + str(self.snowflake.next_id())
  30. device_id = 'D' + str(self.snowflake.next_id())
  31. # now = lambda: int(round(time.time() * 1000))
  32. now = datetime.now().timestamp()
  33. self.logger.info("CallService 人工外呼 agent:%s makecall, ctiFlowId:%s, callId:%s, callerDisplay:%s, called:%s"%
  34. (request.caller, request.cti_flow_id, call_id, request.caller_display, request.called))
  35. agent = self.cache.get_agent_info(request.saas_id, request.agent_id)
  36. route_gateway = self.cache.get_route_gateway(request.saas_id)
  37. call_info = CallInfo(cti_flow_id=request.cti_flow_id, call_id=call_id, agent_key=agent.agent_number, sip_server=agent.sip_server,
  38. caller=agent.agent_number, called=request.called, direction=Direction.OUTBOUND.code,
  39. caller_display=request.caller_display, called_display=request.called_display,
  40. call_type=request.call_type, call_time=now, follow_data=request.follow_data,
  41. uuid1=request.uuid1, uuid2=request.uuid2, saas_id=SAAS_ID,
  42. 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=[])
  43. 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,
  44. agent_key=agent.agent_number, caller_display=route_gateway.name, cdr_type=CdrType.INBOUND.code,
  45. conference=None, agent_name=None, from_agent=None, caller=None, called=None, display=None, called_location=None, caller_location=None, ring_start_time=None, ring_end_time=None, answer_time=None, bridge_time=None, end_time=None, talk_time=None, sip_protocol=None, channel_name=None, hangup_cause=None, ring_cause=None, sip_status=None, record=None, record_time=None, record_start_time=None, state=None, apparent_number=None,
  46. )
  47. call_info.device_list.append(device_id)
  48. call_info.next_commands.append(NextCommand(device_id, NextType.NEXT_CALL_OTHER.code))
  49. call_info.device_info_map = {device_id: device_info}
  50. self.cache.add_call_info(call_info)
  51. context = MakeCallContext(display=request.called, caller=request.called, called=request.caller,
  52. call_id=call_id, device_id=device_id, device_type=device_info.device_type,
  53. call_type=call_info.call_type, sip_server=call_info.sip_server,
  54. sip_header_map={sipHeaderCtiFlowId: request.cti_flow_id})
  55. self.client.make_call(context)
  56. self.do_after_manual_call(call_info, agent.agent_number)
  57. return call_id
  58. def do_after_manual_call(self, call_info: CallInfo, agent_id):
  59. agent_monitor = self.data_handle_server.get_agent_monitor(call_info.saas_id, agent_number=agent_id)
  60. agent = self.data_handle_server.get_agent(call_info.saas_id, agent_number=agent_id)
  61. self.agent_monitor_service.update_dialing(agent_monitor)
  62. self.push_handler.push_on_call_ring(call_info.saas_id, flow_id=call_info.cti_flow_id, user_id=agent_id, scene=AgentScene.MANUAL, call_id=call_info.call_id, service_direct=ServiceDirect.MANUAL_CALL.service_direct)
  63. self.agent_actionlog_service.insert_service_state(agent_monitor, AgentServiceState.DIALING, AgentLogState.DIALING)
  64. self.data_handle_server.create_record(call_info.call_id, call_info.called, 2, service_category=0, category=1 , user_id=agent.user_id, user_name=agent.agent_name)
  65. def hold(self, call_id, device_id):
  66. self.logger.info('hold, custom_device_id=%s'%device_id)
  67. self.client.bridge_break(call_id, device_id)
  68. self.cache.set_need_play_hold_music(call_id)
  69. self.logger.info('hold success custom_device_id=%s'%device_id)
  70. # def hold(self, call_info: CallInfo, device_id):
  71. # devices = call_info.device_list
  72. # # try:
  73. # # devices.remove(device_id)
  74. # # except:
  75. # # pass
  76. # # custom_device_id = devices[0]
  77. # custom_device_id = device_id
  78. # self.logger.info('hold, custom_device_id=%s'%custom_device_id)
  79. # self.client.bridge_break(call_info.call_id, custom_device_id)
  80. # self.cache.set_need_play_hold_music(call_info.call_id)
  81. # self.logger.info('hold success custom_device_id=%s'%custom_device_id)
  82. def cancel_hold(self, call_info: CallInfo, device_id):
  83. self.client.bridge_call(call_info.call_id, call_info.device_list[0], call_info.device_list[1])
  84. def transfer(self, call_info: CallInfo, agent_number, service_id):
  85. registry.CALL_TRANSFER_REQUESTS.labels(f"{call_info.bucket_type}").inc()
  86. caller = call_info.called
  87. call_id = call_info.call_id
  88. agent = self.cache.get_agent_info(call_info.saas_id, agent_number)
  89. device_id = 'T' + str(self.snowflake.next_id())
  90. # now = lambda: int(round(time.time() * 1000))
  91. now = datetime.now().timestamp()
  92. device_info = DeviceInfo(device_id=device_id, caller=caller, display=caller, called=agent_number, call_id=call_id,
  93. call_time=now, cdr_type=CdrType.TRANSFER.code, device_type=DeviceType.AGENT.code,
  94. cti_flow_id=None, agent_key=agent_number, agent_name=None, from_agent=None, called_location=None, caller_location=None, ring_start_time=None, ring_end_time=None, answer_time=None, bridge_time=None, end_time=None, talk_time=None, sip_protocol=None, channel_name=None, hangup_cause=None, ring_cause=None, sip_status=None, record=None, record_time=None, record_start_time=None, state=None, apparent_number=None, caller_display=None)
  95. call_info.device_list.append(device_id)
  96. # call_info.caller = agent_number
  97. call_info.device_info_map[device_id] = device_info
  98. call_info.next_commands.append(NextCommand(device_info.device_id, NextType.NEXT_TRANSFER_CALL.code, call_info.device_list[0]))
  99. call_info.agent_key = agent_number
  100. self.logger.info('transfer, agent_number=%s, device_id=%s, call_info=%s'% (agent_number, device_id, call_info))
  101. # agent.sip_server
  102. self.cache.add_call_info(call_info)
  103. self.cache.add_agent_info(agent=agent, call_id=call_id, device_id=device_id)
  104. sip_header_map = {sipHeaderServiceId: service_id}
  105. context = MakeCallContext(display=call_info.caller, caller=call_info.caller, called=agent_number,
  106. call_id=call_id, device_id=device_id, device_type=device_info.device_type,sip_server=agent.sip_server,
  107. call_type=call_info.call_type, service_id=service_id, sip_header_map=sip_header_map)
  108. self.client.make_call(context)
  109. def hangup_by_scene(self, request: HangupCallRequest):
  110. scene = AgentScene.get_by_code(request.scene)
  111. if scene and AgentScene.MANUAL == scene:
  112. self.do_manual_hang(request)
  113. elif scene and not AgentScene.MANUAL == scene:
  114. self.do_robot_hang(request)
  115. def do_manual_hang(self, request: HangupCallRequest):
  116. self.hangup_call(request.call_id)
  117. agent_monitor = self.data_handle_server.get_agent_monitor(saas_id=request.saas_id, agent_number=request.agent_id)
  118. self.agent_actionlog_service.insert_service_state(agent_monitor, AgentServiceState.HANGING, AgentLogState.MANUAL_HANG_UP)
  119. def do_robot_hang(self, request: HangupCallRequest):
  120. self.hangup_call(request.call_id)
  121. def hangup_all(self, call_info: CallInfo, case_enum=CallCause.DEFAULT):
  122. devices = call_info.device_list
  123. if not devices:
  124. self.logger.info('hangupCallAll skip 已全部挂断 callId: %s', call_info.call_id)
  125. return
  126. self.logger.info("hangup_all, call_id:%s, devices=%s, case=%s"%(call_info.call_id, json.dumps(devices), case_enum))
  127. for device in devices:
  128. self.client.kill_call(call_info.call_id, device, case_enum)
  129. def hangup_call(self, call_id):
  130. call_info = self.cache.get_call_info(call_id)
  131. if not call_info:
  132. self.logger.info('hangup call not exist callId: %s', call_id)
  133. return
  134. devices = call_info.device_list
  135. if not devices:
  136. self.logger.info('hangup deviceList is null callId: %s', call_id)
  137. return
  138. self.logger.info("hangup_all, call_id:%s, devices=%s" % (call_info.call_id, json.dumps(devices)))
  139. for device in devices:
  140. self.client.kill_call(call_info.call_id, device, CallCause.RESTART)
  141. def checkin_call(self, request: CheckInCallRequest):
  142. agent = self.cache.get_agent_info(request.saas_id, request.agent_number)
  143. return self.client.show_channel(agent.device_id)