Ejemplo n.º 1
0
def incoming():
    from_number = sanitize_phone_number(request.values.get('From'))
    if not from_number:
        app.logger.info('Incoming weirdness with caller ID blocked')
        return render_xml(
            'hang_up.xml',
            message=
            'Call with your caller ID unblocked to get through. Goodbye!')

    enrolled = confirm = False

    volunteer = Volunteer.query.filter_by(phone_number=from_number).first()
    if volunteer:
        enrolled = True

    gather_times = get_gather_times()
    url_kwargs = {'gather': gather_times}

    if request.values.get('Digits') == '1':
        if volunteer:
            if request.args.get('confirm'):
                db.session.delete(volunteer)
                db.session.commit()

                app.logger.info(
                    'Volunteer {} removed by call'.format(from_number))
                return render_xml(
                    'hang_up.xml',
                    with_song=True,
                    message=(
                        'You will no longer receive calls. To sign back up, '
                        'call this number or go to calls dot B M I R dot org.'
                    ))
            else:
                confirm = True
                url_kwargs['confirm'] = 'y'
                del url_kwargs['gather']
        else:
            submission = Submission(phone_number=from_number)
            db.session.add(submission)
            db.session.commit()
            app.logger.info('Volunteer {} added by call'.format(from_number))
            return redirect(
                protected_external_url('volunteers.verify',
                                       id=submission.id,
                                       phoned='y'))

    app.logger.info(
        'Got incoming weirdness call from {} (enrolled = {})'.format(
            from_number, enrolled))
    return render_xml(
        'incoming_weirdness.xml',
        action_url=protected_external_url('weirdness.incoming', **url_kwargs),
        confirm=confirm,
        enrolled=enrolled,
        gather_times=gather_times,
    )
Ejemplo n.º 2
0
def verify(id):
    submission = Submission.query.filter_by(id=id).first_or_404()

    if request.values.get('AnsweredBy') == 'machine_start':
        app.logger.warning(
            "Couldn't verify submission id={} because of answering machine start"
            .format(submission.id))
        return render_xml('hang_up.xml')

    gather_times = get_gather_times()

    confirmed = request.values.get('Digits') == '1'
    if confirmed:
        if submission.create_volunteer():
            app.logger.info('Volunteer {} added by call'.format(
                submission.phone_number))
        else:
            app.logger.warning(
                "Couldn't create volunteer for submission id={}".format(
                    submission.id))
            return Response(status=409)  # Conflict

    return render_xml(
        'verify.xml',
        action_url=protected_external_url('volunteers.verify',
                                          id=submission.id,
                                          gather=gather_times),
        phoned=bool(request.args.get('phoned')),
        confirmed=confirmed,
        gather_times=gather_times,
    )
Ejemplo n.º 3
0
def incoming():
    if request.args.get('voicemail'):
        return render_xml('hang_up.xml',
                          with_song=True,
                          message='Did you want to re-record that? Too bad.')

    call_status = request.values.get('DialCallStatus')
    calling_enabled = UserCodeConfig.get('broadcast_enable_incoming')

    if call_status == 'completed':
        app.logger.info('Broadcast hung up on incoming caller')
        return render_xml('hang_up.xml', with_song=True)

    elif (call_status in ('busy', 'no-answer', 'failed')
          or not calling_enabled):
        lottery_enabled = UserCodeConfig.get(
            'random_broadcast_misses_to_weirdness')
        if (random.randint(
                1, constants.INCOMING_CALLERS_RANDOM_CHANCE_OF_WEIRDNESS) == 1
                and lottery_enabled):
            app.logger.info('Incoming broadcast call missed (calling {}) won '
                            'lottery. Calling volunteer.'.format(
                                'enabled' if calling_enabled else 'disabled'))
            return outgoing_weirdness()
        else:
            app.logger.info(
                'Sending incoming broadcast call missed (calling {}) '
                'from broadcast to voicemail (lottery {})'.format(
                    'enabled' if calling_enabled else 'disabled',
                    'enabled' if lottery_enabled else 'disabled'))
            return render_xml('voicemail.xml',
                              action_url=protected_external_url(
                                  'broadcast.incoming', voicemail='y'),
                              transcribe_callback_url=protected_external_url(
                                  'broadcast.transcribe'))

    else:
        app.logger.info('Incoming broadcast call ringing')
        return render_xml(
            'call.xml',
            record=True,
            action_url=protected_external_url('broadcast.incoming'),
            from_number=app.config['BROADCAST_NUMBER'],
            to_sip_address='{}@{}'.format(app.config['BROADCAST_SIP_USERNAME'],
                                          app.config['TWILIO_SIP_DOMAIN']),
        )
Ejemplo n.º 4
0
def whisper():
    confirmed = bool(request.values.get('Digits'))
    has_gathered = bool(request.args.get('has_gathered'))
    app.logger.info('Whispering to {} (confirmed = {}, gathered = {})'.format(
        request.values.get('To'), confirmed, has_gathered))
    return render_xml(
        'whisper.xml',
        confirmed=confirmed,
        has_gathered=has_gathered,
        action_url=protected_external_url('weirdness.whisper',
                                          has_gathered='y'),
    )
Ejemplo n.º 5
0
def submit():
    submission = Submission.create_from_json(request.get_json())

    if submission.valid_phone:
        # Do we already have a volunteer?
        volunteer = Volunteer.query.filter_by(
            phone_number=submission.phone_number).first()

        # A volunteer already exists for this phone number
        if volunteer:
            for attr, value in submission.get_volunteer_kwargs().items():
                setattr(volunteer, attr, value)

            db.session.add(volunteer)
            db.session.commit()
            app.logger.info('Volunteer {} updated by form'.format(
                volunteer.phone_number))

            try:
                app.twilio.messages.create(
                    body=
                    'Thanks for updating your BMIR Phone Experiment submission.',
                    from_=app.config['WEIRDNESS_NUMBER'],
                    to=submission.phone_number,
                )
            except TwilioRestException:  # skip coverage
                pass

        else:
            app.logger.info('Submission {} created (valid phone)'.format(
                submission.phone_number))
            app.twilio.calls.create(
                machine_detection='Enable',
                machine_detection_silence_timeout=3000,
                url=protected_external_url('volunteers.verify',
                                           id=submission.id),
                from_=app.config['WEIRDNESS_NUMBER'],
                to=submission.phone_number,
            )
    else:
        app.logger.info('Submission {} created (invalid phone)'.format(
            submission.phone_number))

    return Response(status=200)
Ejemplo n.º 6
0
def outgoing():
    # We can come from the broadcast outgoing route, where we may want to change behaviour
    is_broadcast = parse_sip_address(
        request.values.get('From')) == app.config['BROADCAST_SIP_USERNAME']

    # If our submit action on the dialed call comes back with status completed,
    # that means the dialed party hung up. If this happens in the first 30 secs,
    # we'll dial someone else -- otherwise let's hang up on the caller
    if (request.values.get('DialCallStatus') == 'completed'
            and int(request.values.get('DialCallDuration', -1)) >= 30):
        context = {}
        if not is_broadcast:
            context = {
                'message':
                ('Congratulations! You have won! You will receive a FREE '
                 'Microsoft Zune in 3 to 5 business days.'),
                'with_song':
                True,
            }
        app.logger.info('Outgoing weirdness call completed')
        return render_xml('hang_up.xml', **context)
    else:
        # 1 in 30 chance we're calling the BMIR broadcast phone (unless this
        # call came routed from the broadcast desk)
        if (not is_broadcast
                # Make sure this wasn't an outside caller who won the lottery
                and
                not request.values.get('To') == app.config['BROADCAST_NUMBER']
                and random.randint(
                    1, constants.WEIRDNESS_RANDOM_CHANCE_OF_RINGING_BROADCAST)
                == 1 and UserCodeConfig.get('random_weirdness_to_broadcast')):
            app.logger.info(
                'Outgoing weirdness call won lottery, dialing broadcast phone')
            return render_xml(
                'call.xml',
                timeout=20,
                record=True,
                from_number=app.config['WEIRDNESS_NUMBER'],
                action_url=protected_external_url('weirdness.outgoing'),
                to_sip_address='{}@{}'.format(
                    app.config['BROADCAST_SIP_USERNAME'],
                    app.config['TWILIO_SIP_DOMAIN'],
                ))

        # Otherwise it's a new call OR the person we called didn't confirm.
        multiring = UserCodeConfig.get('weirdness_multiring')
        volunteers = Volunteer.get_random_opted_in(multiring=multiring)

        if volunteers:
            to_numbers = [volunteer.phone_number for volunteer in volunteers]
            app.logger.info('Outgoing weirdness call to {}'.format(
                to_numbers[0] if len(to_numbers) == 1 else to_numbers))
            return render_xml(
                'call.xml',
                record=True,
                timeout=20,
                from_number=app.config['WEIRDNESS_NUMBER'],
                to_numbers=to_numbers,
                action_url=protected_external_url('weirdness.outgoing'),
                whisper_url=protected_external_url('weirdness.whisper'),
            )
        else:
            app.logger.info(
                'Outgoing weirdness call found no volunteers. Hanging up.')
            return render_xml(
                'hang_up.xml',
                message='You lose. Thanks for playing! Better luck next time!',
                with_song=True,
            )