def make_single(): params, campaign = parse_params(request) if not params or not campaign: abort(400) i = int(request.values.get('call_index', 0)) params['call_index'] = i (uid, prefix) = parse_target(params['targetIds'][i]) (current_target, cached) = Target.get_uid_or_cache(uid, prefix) if cached: # save Target to database db.session.add(current_target) db.session.commit() resp = twilio.twiml.Response() if not current_target.number: play_or_say(resp, campaign.audio('msg_invalid_location')) return str(resp) target_phone = current_target.number.e164 # use full E164 syntax here play_or_say(resp, campaign.audio('msg_target_intro'), title=current_target.title, name=current_target.name) if current_app.debug: current_app.logger.debug( 'Call #{}, {} ({}) from {} in call.make_single()'.format( i, current_target.name, target_phone, params['userPhone'])) userPhone = PhoneNumber(params['userPhone'], params['userCountry']) resp.dial(target_phone, callerId=userPhone.e164, timeLimit=current_app.config['TWILIO_TIME_LIMIT'], timeout=current_app.config['TWILIO_TIMEOUT'], hangupOnStar=True, action=url_for('call.complete', **params)) return str(resp)
def make_single(): params, campaign = parse_params(request) if not params or not campaign: abort(400) i = int(request.values.get('call_index', 0)) params['call_index'] = i (uid, prefix) = parse_target(params['targetIds'][i]) (current_target, cached) = Target.get_or_cache_key(uid, prefix) if cached: # save Target to database db.session.add(current_target) db.session.commit() resp = VoiceResponse() if not current_target.number: play_or_say(resp, campaign.audio('msg_invalid_location'), lang=campaign.language_code) return str(resp) if current_target.offices: if campaign.target_offices == TARGET_OFFICE_DISTRICT: office = random.choice(current_target.offices) target_phone = office.number elif campaign.target_offices == TARGET_OFFICE_BUSY: # TODO keep track of which ones we have tried undialed_offices = current_target.offices # then pick a random one office = random.choice(undialed_offices) target_phone = office.number #elif campaign.target_offices == TARGET_OFFICE_CLOSEST: # office = find_closest(current_target.offices, params['userLocation']) # target_phone = office.phone else: office = None target_phone = current_target.number else: office = None target_phone = current_target.number play_or_say(resp, campaign.audio('msg_target_intro'), title=current_target.title, name=current_target.name, office_type = office.name if office else '', lang=campaign.language_code) if current_app.debug: current_app.logger.debug(u'Call #{}, {} ({}) from {} in call.make_single()'.format( i, current_target.name, target_phone.e164, params['userPhone'])) try: parsed = PhoneNumber(params['userPhone'], params['userCountry']) userPhone = parsed.e164 except phonenumbers.NumberParseException: current_app.logger.error('Unable to parse %(userPhone)s for %(userCountry)s' % params) # press onward, but we may not be able to actually dial userPhone = params['userPhone'] # sending a twiml.Number to dial init will not nest properly # have to add it after creation d = Dial(None, caller_id=userPhone, time_limit=current_app.config['TWILIO_TIME_LIMIT'], timeout=current_app.config['TWILIO_TIMEOUT'], hangup_on_star=True, action=url_for('call.complete', **params)) \ .number(target_phone.e164, sendDigits=target_phone.extension) resp.append(d) return str(resp)
def create(): """ Places a phone call to a user, given a country, phone number, and campaign. Required Params: userPhone campaignId Optional Params: userCountry (defaults to US) userLocation (zipcode) targetIds record (boolean) ref (string) """ # parse the info needed to make the call params, campaign = parse_params(request) # find outgoing phone number in same country as user phone_numbers = campaign.phone_numbers(params['userCountry']) if not phone_numbers: msg = "no numbers available for campaign %(campaignId)s in %(userCountry)s" % params return abort(400, msg) # validate phonenumber for country try: parsed = PhoneNumber(params['userPhone'], params['userCountry']) userPhone = parsed.e164 except phonenumbers.NumberParseException: current_app.logger.error('Unable to parse %(userPhone)s for %(userCountry)s' % params) # press onward, but we may not be able to actually dial userPhone = params['userPhone'] if Blocklist.user_blocked(params['userPhone'], params['userIPAddress'], user_country=params['userCountry']): abort(429, {'kthx': 'bai'}) # submission tripped blocklist if campaign.status == 'archived': result = jsonify(campaign=campaign.status) return result # compute campaign targeting now, to return to calling page if campaign.segment_by == SEGMENT_BY_CUSTOM: targets_list = [t for t in campaign.target_set] if campaign.target_ordering == 'shuffle': # do randomization now random.shuffle(targets_list) # limit to maximum if campaign.call_maximum: targets_list = targets_list[:campaign.call_maximum] # save to params so order persists for this caller params['targetIds'] = [t.uid for t in targets_list] target_response = { 'segment': 'custom', 'objects': [{'name': t.name, 'title': t.title, 'phone': t.number.e164} for t in targets_list] } else: target_response = { 'segment': campaign.segment_by, 'display': campaign.targets_display() } # start call session for user try: from_number = random.choice(phone_numbers) call_session_data = { 'campaign_id': campaign.id, 'location': params['userLocation'], 'from_number': from_number, 'direction': 'outbound' } if current_app.config['LOG_PHONE_NUMBERS']: call_session_data['phone_number'] = params['userPhone'] # user phone numbers are hashed by the init method # but some installations may not want to log at all call_session = Session(**call_session_data) if 'ref' in request.values: call_session.referral_code = request.values.get('ref')[:64] db.session.add(call_session) db.session.commit() params['sessionId'] = call_session.id # initiate outbound call call = current_app.config['TWILIO_CLIENT'].calls.create( to=userPhone, from_=from_number, url=url_for('call.connection', _external=True, **params), timeout=current_app.config['TWILIO_TIMEOUT'], status_callback=url_for("call.status_callback", _external=True, **params), status_callback_event=['ringing','completed'], record=request.values.get('record', False)) if campaign.embed: script = campaign.embed.get('script') redirect = campaign.embed.get('redirect') else: script = '' redirect = '' result = jsonify(campaign=campaign.status, call=call.status, script=script, redirect=redirect, fromNumber=from_number, targets=target_response) result.status_code = 200 if call.status != 'failed' else 500 except TwilioRestException, err: twilio_error = stripANSI(err.msg) abort(400, twilio_error)
def create(): """ Places a phone call to a user, given a country, phone number, and campaign. Required Params: userPhone campaignId Optional Params: userCountry (defaults to US) userLocation (zipcode) targetIds """ # parse the info needed to make the call params, campaign = parse_params(request) # find outgoing phone number in same country as user phone_numbers = campaign.phone_numbers(params['userCountry']) if not phone_numbers: msg = "no numbers available for campaign %(campaignId)s in %(userCountry)s" % params return abort(400, msg) # validate phonenumber for country try: parsed = PhoneNumber(params['userPhone'], params['userCountry']) userPhone = parsed.e164 except phonenumbers.NumberParseException: current_app.logger.error( 'Unable to parse %(userPhone)s for %(userCountry)s' % params) # press onward, but we may not be able to actually dial userPhone = params['userPhone'] # start call session for user try: from_number = random.choice(phone_numbers) call_session_data = { 'campaign_id': campaign.id, 'location': params['userLocation'], 'from_number': from_number, } if current_app.config['LOG_PHONE_NUMBERS']: call_session_data['phone_number'] = params['userPhone'] # user phone numbers are hashed by the init method # but some installations may not want to log at all call_session = Session(**call_session_data) db.session.add(call_session) db.session.commit() params['sessionId'] = call_session.id # initiate outbound call call = current_app.config['TWILIO_CLIENT'].calls.create( to=userPhone, from_=from_number, url=url_for('call.connection', _external=True, **params), timeLimit=current_app.config['TWILIO_TIME_LIMIT'], timeout=current_app.config['TWILIO_TIMEOUT'], status_callback=url_for("call.complete_status", _external=True, **params)) if campaign.embed: script = campaign.embed.get('script') else: script = '' result = jsonify(campaign=campaign.status, call=call.status, script=script) result.status_code = 200 if call.status != 'failed' else 500 except TwilioRestException, err: twilio_error = stripANSI(err.msg) abort(400, twilio_error)