Пример #1
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'],
                'all_lines': request['all_lines']
            },
            'variables': request['variables']
        }
        if 'line_id' in request:
            new_request['source']['line_id'] = request['line_id']
        if 'auto_answer_caller' in request:
            new_request['source']['auto_answer'] = request[
                'auto_answer_caller']
        return self.originate(new_request)
Пример #2
0
    def answer_queued_call(self,
                           tenant_uuid,
                           switchboard_uuid,
                           queued_call_id,
                           user_uuid,
                           line_id=None):
        logger.debug(
            'Answering queued call %s in tenant %s for switchboard %s with user %s line %s',
            queued_call_id,
            tenant_uuid,
            switchboard_uuid,
            user_uuid,
            line_id,
        )
        if not SwitchboardConfd(tenant_uuid, 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)

        try:
            user = User(user_uuid, self._confd, tenant_uuid=tenant_uuid)
            if line_id:
                line = user.line(line_id)
            else:
                line = user.main_line()
            endpoint = line.interface_autoanswer()
        except InvalidUserUUID as e:
            raise NoSuchConfdUser(e.details['user_uuid'])

        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',
                tenant_uuid,
                switchboard_uuid,
                queued_call_id,
            ],
            callerId=caller_id,
            originator=queued_call_id,
            variables={'variables': AUTO_ANSWER_VARIABLES},
        )

        return channel.id
Пример #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=DEFAULT_APPLICATION_NAME,
            appArgs=[app_instance, 'dialed_from', channel_id],
            originator=call_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 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:
            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)
Пример #5
0
    def send_fax_from_user(self, tenant_uuid, user_uuid, content, fax_infos):
        context = User(user_uuid, self._confd).main_line().context()

        fax_infos['context'] = context

        return self.send_fax(tenant_uuid,
                             content,
                             fax_infos,
                             user_uuid=user_uuid)
Пример #6
0
    def create_from_user(self, initiator_call, destination, location, completions, timeout, auto_answer, user_uuid):
        initiator_channel = Channel(initiator_call, self.ari)
        user = User(user_uuid, self.confd_client)
        variables = {}

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

        tenant_uuid = initiator_channel.tenant_uuid()
        if tenant_uuid:
            variables['WAZO_TENANT_UUID'] = tenant_uuid

        if destination == 'line':
            try:
                destination_interface = user.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
        elif destination == 'mobile':
            try:
                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

        if auto_answer:
            variables.update(AUTO_ANSWER_VARIABLES)
        relocate = Relocate(self.state_factory)
        relocate.initiator = user_uuid
        relocate.recipient_variables = variables

        return self.create(initiator_call, destination, location, completions, timeout, relocate=relocate)
Пример #7
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:
            user = User(source_user, self._confd)
            if 'line_id' in request['source']:
                endpoint = user.line(request['source']['line_id']).interface()
            elif request['source']['all_lines']:
                endpoint = "local/%s@usersharedlines" % (source_user, )
            else:
                endpoint = user.main_line().interface()

            context, extension, priority = requested_context, requested_extension, requested_priority

            if request['source']['auto_answer']:
                variables.update(AUTO_ANSWER_VARIABLES)

            variables.setdefault('XIVO_FIX_CALLERID', '1')
            variables.setdefault('WAZO_USERUUID', source_user)
            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