call.py 10.0 KB

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