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()
Exemple #13
0
 def _message(data):
     return Message.from_line(data)
Exemple #14
0
 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', ''))
Exemple #16
0
 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)