async def var_set(manager: Manager, message: Message): if message.get('Variable', '') != 'MIXMONITOR_FILENAME': return call = await _get_call(message) if not call: return var_file_name = message.get('Value', '') monitor_file_name = get_full_path(var_file_name) manager.log.info(f'record_file: {monitor_file_name}, call_id: {call.id}') ch, _ = await Channel.get_or_create( defaults={ 'name': message.get('Channel'), 'call': call, 'monitor_file_name': monitor_file_name, }, id=message.get('Uniqueid'), ) record = await CallRecord.create( call=call, channel=ch, file_name=monitor_file_name, ) if monitor_file_name: call.record = record await call.save()
async def new_channel(manager: Manager, message: Message): if message.get('Uniqueid', '') != message.get('Linkedid', ''): return src_num = get_number(message.get('CallerIDNum', '')) dst_num = get_number(message.get('Exten', '')) call_type = CallType.UNKNOWN from_pin = from_num = request_num = request_pin = '' if is_internal(src_num) and is_internal(dst_num): call_type = CallType.INTERNAL from_pin = src_num request_pin = dst_num elif is_internal(src_num) and is_external(dst_num): call_type = CallType.OUTBOUND from_pin = src_num request_num = dst_num elif is_external(src_num): call_type = CallType.INCOMING from_num = src_num request_num = dst_num await Call.create( id=message.get('Linkedid', ''), from_pin=from_pin, from_number=from_num, request_number=request_num, request_pin=request_pin, call_type=call_type, state=CallState.NEW, created_at=datetime.utcnow(), )
async def new_state(manager: Manager, message: Message): state = message.get('ChannelState', '') num = validate_numbers(message.get('CallerIDNum', ''), message.get('ConnectedLineNum', '')) call = calls.get(message.get('Uniqueid', '')) if not call or not num or state != '6' or is_group_numbers( num.request_pin): return call.state = CallState.CONNECTED call.voice_started_at = datetime.now() call.account_id = call.account_id or message.get('AccountCode') src_nums = (call.from_pin, call.from_number) dst_nums = (call.request_pin, call.request_number) if call.call_type == CallType.INCOMING: if num.src in src_nums and num.dst not in dst_nums: call.request_number = call.request_number or num.request_number call.request_pin = num.request_pin or call.request_pin elif num.dst in src_nums and num.src not in dst_nums: call.request_number = call.request_number or num.from_number call.request_pin = num.from_pin or call.request_pin await call.save()
async def join(manager: Manager, message: Message): queue = message.get('Queue', '') call = calls.get(message.get('Uniqueid', '')) if queue not in app_config.ats.group_numbers: app_config.ats.group_numbers.append(queue) if call: call.request_pin = queue if call.call_type == CallType.UNKNOWN: call.call_type = CallType.INCOMING await call.save()
async def dial(manager: Manager, message: Message): if message.get('SubEvent', '') != 'Begin': return pin = get_internal(message.get('Dialstring', '')) if not pin: return id1, id2 = message.get('UniqueID', ''), message.get('DestUniqueID', '') for ch in (channels.get(id1), channels.get(id2)): if ch and not ch.pin: ch.pin = pin await ch.save()
async def agent_called(manager: Manager, message: Message): request_pin = message.get('Queue', '') or message.get('Exten', '') call = await _get_call(message) if not call: return if call.call_type != CallType.INCOMING: call.call_type = CallType.INCOMING if not call.request_pin: call.request_pin = get_number(request_pin) if call.state != CallState.NEW: call.state = CallState.NEW await call.save()
async def new_channel(manager: Manager, message: Message): num = validate_numbers(message.get('CallerIDNum'), message.get('Exten')) call = None if 'from-queue' not in message.get('Context', '') and num: call = await Call.create( id=message.get('Uniqueid'), state=CallState.NEW, from_pin=num.from_pin, from_number=num.from_number, request_number=num.request_number, request_pin=num.request_pin, call_type=get_call_type(num), account_id=message.get('AccountCode'), ) calls[call.id] = call ch = await Channel.create( id=message.get('Uniqueid'), name=message.get('Channel'), from_number=num.src, request_number=num.dst, call=call, ) channels[ch.id] = ch
async def dial_end(manager: Manager, message: Message): if message.get('DialStatus', '') != 'ANSWER': return call = await _get_call(message) if not call: return call.state = CallState.CONNECTED call.voice_started_at = datetime.utcnow() request_pin = get_number(message.get('DestCallerIDNum', '')) if call.call_type == CallType.INCOMING and \ is_internal(request_pin) and \ (not call.request_pin or not is_group_numbers(request_pin)): call.request_pin = request_pin await call.save()
async def hangup(manager: Manager, message: Message): if message.get('Uniqueid', '') != message.get('Linkedid', ''): return call = await _get_call(message) if not call or call.state in (CallState.NOT_CONNECTED, CallState.MISSED, CallState.END): return call.finished_at = datetime.utcnow() if call.state == CallState.CONNECTED: call.state = CallState.END elif call.call_type == CallType.INCOMING: call.state = CallState.MISSED else: call.state = CallState.NOT_CONNECTED await call.save()
async def var_set(manager: Manager, message: Message): if message.get('Variable', '') != 'MIXMONITOR_FILENAME': return ch = channels.get(message.get('Uniqueid', '')) if not ch: return ch.monitor_file_name = message.get('Value')[-255:] await ch.save() call = calls.get(ch.id, ch.call) if not call: ch2 = await ch.bridged.filter(call=None).first() call = ch2.call if ch2 else call await CallRecord.create( call=call, channel=ch, file_name=ch.monitor_file_name, )
async def hangup(manager: Manager, message: Message): u_id = message.get('Uniqueid') call = calls.get(u_id) if u_id in channels: channels.pop(u_id) if not call: return if call.state == CallState.CONNECTED: call.state = CallState.END elif call.call_type == CallType.INCOMING: call.state = CallState.MISSED else: call.state = CallState.NOT_CONNECTED call.finished_at = datetime.now() call.account_id = call.account_id or message.get('AccountCode') await call.save() calls.pop(call.id)
async def bridge(manager: Manager, message: Message): if message.get('Bridgestate', '') not in ('Link', 'Unlink'): return b1 = channels.get(message.get('Uniqueid1', '')) b2 = channels.get(message.get('Uniqueid2', '')) if not b1 and not b2: return if b1 and b2: await b1.bridged.add(b2) await b2.bridged.add(b1) call: Call = b1.call or b2.call if not call: return if message.get('Bridgestate', '') == 'Link': call.state = CallState.CONNECTED call.voice_started_at = datetime.now() if call.call_type == CallType.INCOMING: call.request_pin = b1.pin or b2.pin or call.request_pin for num in (validate_numbers(b1.from_number, b1.request_number), validate_numbers(b2.from_number, b2.request_number), validate_numbers(message.get('CallerID1', ''), message.get('CallerID2', ''))): if not is_group_numbers(call.request_pin): break elif num and num.request_pin: call.request_pin = num.request_pin elif num and num.from_pin: call.request_pin = num.from_pin await call.save()
def _message(data): return Message.from_line(data)
async def _get_call(message: Message) -> Optional[Call]: return await Call.all().prefetch_related('tags', 'records').get_or_none(id=message.get('Linkedid', ''))
def __init__(self, message): if isinstance(message, str): message = Message.from_line(message) self.message = message
async def handle_message(manager: Manager, data: Dict[str, str]): message = Message(data) manager.protocol.handle_message(message) await sleep(0.03)