예제 #1
0
    def answer_queued_call(self, switchboard_uuid, queued_call_id, user_uuid):
        if not Switchboard(switchboard_uuid, self._confd).exists():
            raise NoSuchSwitchboard(switchboard_uuid)

        try:
            queued_channel = self._ari.channels.get(channelId=queued_call_id)
        except ARINotFound:
            raise NoSuchCall(queued_call_id)

        endpoint = User(user_uuid, self._confd).main_line().interface()
        caller_id = assemble_caller_id(
            queued_channel.json['caller']['name'],
            queued_channel.json['caller']['number']).encode('utf-8')

        channel = self._ari.channels.originate(
            endpoint=endpoint,
            app=DEFAULT_APPLICATION_NAME,
            appArgs=[
                'switchboard', 'switchboard_answer', switchboard_uuid,
                queued_call_id
            ],
            callerId=caller_id,
            originator=queued_call_id,
        )

        return channel.id
예제 #2
0
    def create_from_user(self, initiator_call, exten, flow, timeout,
                         user_uuid):
        if not Channel(initiator_call, self.ari).exists():
            raise TransferCreationError('initiator channel not found')

        if Channel(initiator_call, self.ari).user() != user_uuid:
            raise UserPermissionDenied(user_uuid, {'call': initiator_call})

        try:
            transferred_call = Channel(initiator_call,
                                       self.ari).only_connected_channel().id
        except TooManyChannels as e:
            raise TooManyTransferredCandidates(e.channels)
        except NotEnoughChannels as e:
            raise TransferCreationError('transferred channel not found')

        context = User(user_uuid, self.confd_client).main_line().context()

        return self.create(transferred_call,
                           initiator_call,
                           context,
                           exten,
                           flow,
                           variables={},
                           timeout=timeout)
예제 #3
0
    def connect_user(self, call_id, user_uuid):
        channel_id = call_id
        endpoint = User(user_uuid, self._confd).main_line().interface()

        try:
            channel = self._ari.channels.get(channelId=channel_id)
        except ARINotFound:
            raise NoSuchCall(channel_id)

        try:
            app_instance = self._state_persistor.get(channel_id).app_instance
        except KeyError:
            raise CallConnectError(call_id)

        new_channel = self._ari.channels.originate(
            endpoint=endpoint,
            app=APPLICATION_NAME,
            appArgs=[app_instance, 'dialed_from', channel_id])

        # if the caller hangs up, we cancel our originate
        originate_canceller = channel.on_event(
            'StasisEnd', lambda _, __: self.hangup(new_channel.id))
        # if the callee accepts, we don't have to cancel anything
        new_channel.on_event('StasisStart',
                             lambda _, __: originate_canceller.close())
        # if the callee refuses, leave the caller as it is

        return new_channel.id
예제 #4
0
 def originate_user(self, request, user_uuid):
     if 'line_id' in request and not request['from_mobile']:
         context = User(user_uuid, self._confd).line(request['line_id']).context()
     else:
         context = User(user_uuid, self._confd).main_line().context()
     new_request = {
         'destination': {'context': context,
                         'extension': request['extension'],
                         'priority': 1},
         'source': {'user': user_uuid,
                    'from_mobile': request['from_mobile']},
         'variables': request['variables']
     }
     if 'line_id' in request:
         new_request['source']['line_id'] = request['line_id']
     return self.originate(new_request)
예제 #5
0
    def create_from_user(self, initiator_call, destination, location,
                         completions, timeout, user_uuid):
        if Channel(initiator_call, self.ari).user() != user_uuid:
            raise UserPermissionDenied(user_uuid, {'call': initiator_call})

        if destination == 'line':
            try:
                destination_interface = User(
                    user_uuid,
                    self.confd_client).line(location['line_id']).interface()
            except (InvalidUserUUID, InvalidUserLine):
                raise RelocateCreationError('invalid line for user',
                                            details={
                                                'user_uuid': user_uuid,
                                                'line_id': location['line_id']
                                            })
            destination = 'interface'
            location['interface'] = destination_interface
            variables = {}
        elif destination == 'mobile':
            try:
                user = User(user_uuid, self.confd_client)
                mobile = user.mobile_phone_number()
                line_context = user.main_line().context()
            except (InvalidUserUUID, InvalidUserLine):
                details = {'user_uuid': user_uuid}
                raise RelocateCreationError(
                    'invalid user: could not find main line', details=details)
            destination = 'extension'
            location = {'exten': mobile, 'context': line_context}
            variables = {'WAZO_DEREFERENCED_USERUUID': user_uuid}

        relocate = Relocate(self.state_factory)
        relocate.initiator = user_uuid
        relocate.recipient_variables = variables

        return self.create(initiator_call,
                           destination,
                           location,
                           completions,
                           timeout,
                           relocate=relocate)
예제 #6
0
 def originate_user(self, request, user_uuid):
     context = User(user_uuid, self._confd).main_line().context()
     new_request = {
         'destination': {
             'context': context,
             'extension': request['extension'],
             'priority': 1
         },
         'source': {
             'user': user_uuid
         },
         'variables': request['variables']
     }
     return self.originate(new_request)
예제 #7
0
    def originate(self, request):
        source_user = request['source']['user']
        endpoint = User(source_user, self._confd).main_line().interface()
        variables = request.get('variables', {})
        variables.setdefault('CONNECTEDLINE(all)',
                             request['destination']['extension'])

        channel = self._ari.channels.originate(
            endpoint=endpoint,
            extension=request['destination']['extension'],
            context=request['destination']['context'],
            priority=request['destination']['priority'],
            variables={'variables': variables})
        return channel.id
예제 #8
0
    def create_from_user(self, initiator_call, exten, flow, user_uuid):
        if not ari_helpers.channel_exists(self.ari, initiator_call):
            raise TransferCreationError('initiator channel not found')

        if Channel(initiator_call, self.ari).user() != user_uuid:
            raise TransferCreationError(
                'initiator call does not belong to authenticated user')

        try:
            transferred_call = Channel(initiator_call,
                                       self.ari).only_connected_channel()
        except TooManyChannels as e:
            raise TooManyTransferredCandidates(e.channels)
        except NotEnoughChannels as e:
            raise TransferCreationError('transferred channel not found')

        context = User(user_uuid, self.confd_client).main_line().context()

        return self.create(transferred_call,
                           initiator_call,
                           context,
                           exten,
                           flow,
                           variables={})
예제 #9
0
    def originate(self, request):
        requested_context = request['destination']['context']
        requested_extension = request['destination']['extension']
        requested_priority = request['destination']['priority']

        if not ami.extension_exists(self._ami, requested_context, requested_extension, requested_priority):
            raise InvalidExtension(requested_context, requested_extension)

        source_user = request['source']['user']
        variables = request.get('variables', {})
        dial_echo_request_id = None

        if request['source']['from_mobile']:
            source_mobile = User(source_user, self._confd).mobile_phone_number()
            if not source_mobile:
                raise CallCreationError('User has no mobile phone number', details={'user': source_user})
            source_context = User(source_user, self._confd).main_line().context()
            if not ami.extension_exists(self._ami, source_context, source_mobile, priority=1):
                details = {'user': source_user,
                           'mobile_exten': source_mobile,
                           'mobile_context': source_context}
                raise CallCreationError('User has invalid mobile phone number', details=details)
            endpoint = 'local/s@wazo-originate-mobile-leg1/n'
            context, extension, priority = 'wazo-originate-mobile-leg2', 's', 1

            variables.setdefault('_XIVO_USERUUID', source_user)
            variables.setdefault('WAZO_DEREFERENCED_USERUUID', source_user)
            variables.setdefault('WAZO_ORIGINATE_MOBILE_PRIORITY', '1')
            variables.setdefault('WAZO_ORIGINATE_MOBILE_EXTENSION', source_mobile)
            variables.setdefault('WAZO_ORIGINATE_MOBILE_CONTEXT', source_context)
            variables.setdefault('XIVO_FIX_CALLERID', '1')
            variables.setdefault('XIVO_ORIGINAL_CALLER_ID', '"{exten}" <{exten}>'.format(exten=requested_extension))
            variables.setdefault('WAZO_ORIGINATE_DESTINATION_PRIORITY', str(requested_priority))
            variables.setdefault('WAZO_ORIGINATE_DESTINATION_EXTENSION', requested_extension)
            variables.setdefault('WAZO_ORIGINATE_DESTINATION_CONTEXT', requested_context)
            variables.setdefault('WAZO_ORIGINATE_DESTINATION_CALLERID_ALL', '"{exten}" <{exten}>'.format(exten=source_mobile))
            dial_echo_request_id = self._dial_echo_manager.new_dial_echo_request()
            variables.setdefault('_WAZO_DIAL_ECHO_REQUEST_ID', dial_echo_request_id)

            channel = self._ari.channels.originate(endpoint=endpoint,
                                                   extension=extension,
                                                   context=context,
                                                   priority=priority,
                                                   variables={'variables': variables})
            try:
                channel_id = self._dial_echo_manager.wait(dial_echo_request_id, timeout=5)
            except DialEchoTimeout:
                details = {
                    'mobile_extension': source_mobile,
                    'mobile_context': source_context,
                }
                raise CallCreationError('Could not dial mobile number', details=details)
            channel = self._ari.channels.get(channelId=channel_id)

        else:
            if 'line_id' in request['source']:
                endpoint = User(source_user, self._confd).line(request['source']['line_id']).interface()
            else:
                endpoint = User(source_user, self._confd).main_line().interface()

            context, extension, priority = requested_context, requested_extension, requested_priority

            variables.setdefault('XIVO_FIX_CALLERID', '1')
            variables.setdefault('CONNECTEDLINE(name)', extension)
            variables.setdefault('CONNECTEDLINE(num)', '' if extension.startswith('#') else extension)
            variables.setdefault('CALLERID(name)', extension)
            variables.setdefault('CALLERID(num)', extension)
            variables.setdefault('WAZO_CHANNEL_DIRECTION', 'to-wazo')

            channel = self._ari.channels.originate(endpoint=endpoint,
                                                   extension=extension,
                                                   context=context,
                                                   priority=priority,
                                                   variables={'variables': variables})

        call = self.make_call_from_channel(self._ari, channel)
        call.dialed_extension = request['destination']['extension']
        return call