#!/usr/bin/env python3 # encoding:utf-8 import time from datetime import datetime import src.core.callcenter.cache as Cache from src.core.callcenter.constant import saasId, HOLD_MUSIC_PATH from src.core.callcenter.enumeration import CallCause, Direction, NextType, DeviceType, CdrType, AgentServiceState from src.core.callcenter.api import AgentCallRequest, CallInfo, HangupCallRequest, CheckInCallRequest, \ DeviceInfo, NextCommand, MakeCallContext from src.core.callcenter.esl.constant.sip_header_constant import sipHeaderServiceId, sipHeaderCtiFlowId from src.core.callcenter.snowflake import Snowflake from src.core.callcenter.data_handler import * class CallService: def __init__(self, client, logger): self.client = client self.logger = logger self.snowflake = Snowflake() self.dataHandleServer=dataHandleServer(client.app) def call(self, request: AgentCallRequest): call_id = 'C' + str(self.snowflake.next_id()) device_id = 'D' + str(self.snowflake.next_id()) # now = lambda: int(round(time.time() * 1000)) now = datetime.utcnow().timestamp() agent = Cache.get_agent_info(request.saas_id, request.agent_id) route_gateway = Cache.get_route_gateway(request.saas_id) call_info = CallInfo(cti_flow_id=request.cti_flow_id, call_id=call_id, agent_key=agent.agent_number, sip_server=agent.sip_server, caller=agent.agent_number, called=request.called, direction=Direction.INBOUND.code, caller_display=request.caller_display, called_display=request.called_display, call_type=request.call_type.code, call_time=now, follow_data=request.follow_data, uuid1=request.uuid1, uuid2=request.uuid2, saas_id=saasId) 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) call_info.device_list.append(device_id) call_info.next_commands.append(NextCommand(device_id, NextType.NEXT_CALL_OTHER.code)) call_info.device_info_map = {device_id: device_info} Cache.add_call_info(call_info) context = MakeCallContext(display=request.called, caller=request.called, called=request.caller, call_id=call_id, device_id=device_id, device_type=device_info.device_type, call_type=call_info.call_type, sip_server=call_info.sip_server, sip_header_map={sipHeaderCtiFlowId: request.cti_flow_id}) self.client.make_call_new(context) # 创建一条通话记录 self.dataHandleServer.create_record({ "session_id": call_id, "time_begin": datetime.utcnow(), "category": 1, "agent_num":request.agent_id, "phone": request.called }) # 变更坐席状态为拨号中 self.dataHandleServer.update_agent_monitor_service_state(request.agent_id, AgentServiceState.DIALING.code) return call_id def hold(self, call_info: CallInfo, device_id): devices = call_info.device_list try: devices.remove(device_id) except: pass custom_device_id = devices[0] print('debugger::hold, custom_device_id=%s'%custom_device_id, flush=True) # self.client.sync_invoke_method("bridge_break", method_args=(custom_device_id,)) # self.client.sync_invoke_method("hold_play", method_args=(custom_device_id,HOLD_MUSIC_PATH)) self.client.bridge_break(call_info.call_id, custom_device_id) Cache.set_need_play_hold_music(call_info.call_id) print('debugger::hold success custom_device_id=%s'%custom_device_id, flush=True) def cancel_hold(self, call_info: CallInfo, device_id): self.client.bridge_call(call_info.call_id, call_info.device_list[0], call_info.device_list[1]) def transfer(self, call_info: CallInfo, agent_number, service_id): caller = call_info.called call_id = call_info.call_id agent = Cache.get_agent_info(call_info.saas_id, call_info.agent_key) device_id = 'D' + str(self.snowflake.next_id()) # now = lambda: int(round(time.time() * 1000)) now = datetime.utcnow().timestamp() device_info = DeviceInfo(device_id=device_id, caller=caller, display=caller, called=agent_number, call_id=call_id, call_time=now, cdr_type=CdrType.TRANSFER.code, device_type=DeviceType.AGENT.code) call_info.device_list.append(device_id) call_info.caller = agent_number call_info.device_info_map[device_id] = device_info call_info.next_commands.append(NextCommand(device_info.device_id, NextType.NEXT_TRANSFER_CALL.code, call_info.device_list[0])) call_info.agent_key = agent_number # agent.sip_server Cache.add_call_info(call_info) Cache.add_agent_info(agent=agent, call_id=call_id, device_id=device_id) sip_header_map = {sipHeaderServiceId: service_id} context = MakeCallContext(display=call_info.called, caller=call_info.called, called=agent_number, call_id=call_id, device_id=device_id, device_type=device_info.device_type, call_type=call_info.call_type, service_id=service_id, sip_header_map=sip_header_map) self.client.make_call_new(context) def hangup(self, request: HangupCallRequest): call_info = Cache.get_call_info(request.call_id) if not call_info: self.logger.info('hangup call not exist callId: %s', request.call_id) return devices = call_info.device_list if not devices: self.logger.info('hangup deviceList is null callId: %s', request.call_id) return self.hangup_all(call_info, CallCause.AGENT_HANGUP_CALL) def hangup_all(self, call_info: CallInfo, case_enum=CallCause.DEFAULT): devices = call_info.device_list if not devices: self.logger.info('hangupCallAll skip 已全部挂断 callId: %s', call_info.call_id) return for device in devices: self.client.hangup_call(call_info.call_id, device, case_enum) def hangup_call(self, call_id): call_info = Cache.get_call_info(call_id) if not call_info: self.logger.info('hangup call not exist callId: %s', call_id) return devices = call_info.device_list if not devices: self.logger.info('hangup deviceList is null callId: %s', call_id) return for device in devices: self.client.hangup_call(call_info.call_id, device, CallCause.RESTART) def checkin_call(self, request: CheckInCallRequest): agent = Cache.get_agent_info(request.saas_id, request.agent_number) return self.client.show_channel(agent.device_id)