def zipcode_selection(): """Ensures a zipcode has been selected before proceeding with call flow, by: - If a get param is sent, store it and return. - If the context already has a zipcode, return. - If a language choice was passed back, pull it out of settings, store it and return. - If nothing was sent, prompt the user with available choices. This only needs to be set once during the life of a call. """ # Twimlet use if 'zipcode' in g.request_params.keys(): write_context('zipcode', g.request_params['zipcode']) # Internal app use if not get_zip(): errors = [] r = twiml.Response() # Collect and wipe digits if a choice was submitted if 'Digits' in g.request_params.keys(): sel = g.request_params.get('Digits') if len(sel) == 5: write_context('zipcode', sel) elif sel == '9': r.redirect(url_for('.index')) return r else: errors.append('%s is not a valid zip code, please try again.' % sel) del g.request_params['Digits'] # Prompt and gather if zip is not valid or no choice was submitted if not get_zip(): if request.path.startswith(url_for('.member')): reason = 'To help us identify your representatives,' elif request.path.startswith(url_for('.voting')): reason = 'To help us find your election office,' else: reason = None with r.gather(numDigits=5, timeout=settings.INPUT_TIMEOUT) as rg: if len(errors): rg.say(' '.join(errors)) if reason: rg.say(reason) rg.say("""please use the telephone keypad to enter your five-digit zip code now.""") r.redirect(request.path) return r return True
def call_election_office(): r = twiml.Response() zipcode = get_zip() offices = data.election_offices_for_zip(zipcode) if not len(offices): r.redirect('.voting') return r offices_with_phones = [office for office in offices if office.get('phone')] office = None if len(offices_with_phones) == 1: office = offices_with_phones[0] elif len(offices_with_phones) > 1: if 'Digits' in g.request_params.keys(): office = offices_with_phones[int(g.request_params.get('Digits')) - 1] else: with r.gather(numDigits=1, timeout=settings.INPUT_TIMEOUT) as rg: for i, office in enumerate(offices_with_phones): rg.say('Press %d to call %s at %s.' % (i + 1, office.get('authority_name'), office.get('phone'))) return r if office and office.get('phone'): r.say("Connecting you to your election office at") r.say(" %s" % office['phone']) with r.dial() as rd: rd.number(office['phone']) else: r.say("We're sorry, no phone number is available for this office.") flush_context('zipcode') return next_action(default=url_for('.voting')) return r
def voting(): r = twiml.Response() zipcode = get_zip() offices = data.election_offices_for_zip(zipcode) if not len(offices): r.say("""We were unable to find any offices for that zip code.""") flush_context('zipcode') r.redirect(url_for('.voting')) return r if 'Digits' in g.request_params.keys(): if g.request_params['Digits'] == '3': flush_context('zipcode') r.redirect(url_for('.voting')) return r return handle_selection(r, menu='voting', selection=g.request_params['Digits']) with r.gather(numDigits=1, timeout=settings.INPUT_TIMEOUT) as rg: if len(offices) > 1: rg.say("Multiple offices were found in your zip code.") rg.say("""Voter information, including polling place locations and how to register to vote, is available from:""") for office in offices: if office.get('authority_name'): rg.say(office['authority_name']) if office.get('street'): rg.say("Street address: %s, %s %s" % (office['street'], office['city'], office['state'])) if office.get('mailing_street'): rg.say("Mailing address: %s, %s %s, %s" % (office['mailing_street'], office['mailing_city'], office['state'], office['mailing_zip'])) if office.get('phone'): rg.say("Telephone number: %s" % office['phone']) if len([office.get('phone') for office in offices if office.get('phone')]): rg.say("Press 1 to call your election office.") rg.say("""Press 2 to repeat this information. Press 3 to enter a new zip code.""") rg.say("""To return to the previous menu, press 9.""") r.redirect(url_for('.voting')) return r
def bioguide_selection(): """Ensures a Bioguide ID is present in request params before proceeding with call flow. This is not stored in the context, only passed in params. Logic as follows: - If a get param is sent, return. - If a list of possible legislators is stored in context, and a choice was passed, append the choice's Bioguide ID to params and return. - If no list of legislators is present in context, prompt for zipcode and load legislators, then prompt for a selection. """ r = twiml.Response() # Handle twimlet-style params if 'bioguide_id' in g.request_params.keys(): digits = g.request_params.get('Digits') if digits == '9': if re.search(r'member\/[\w\d\/]+', request.path): r.redirect(url_for('.member', bioguide_id=g.request_params['bioguide_id'])) else: del g.request_params['bioguide_id'] r.redirect(url_for('.member')) return r elif digits == '0': r.redirect(url_for('.index')) return r return True # If Digits = 0, we're entering a new zip or going back if g.request_params.get('Digits') == '0': if len(read_context('legislators', [])): flush_context('zipcode') flush_context('legislators') r.redirect(url_for('.member')) return r else: r.redirect(url_for('.index')) return r # Make sure there's a legislators list in the call context. # If not, short-circuit to zip collection and repost to get legislator list # before prompting for a selection. legislators = read_context('legislators', []) if 'Digits' in g.request_params.keys() and len(legislators): if len(legislators) < 8 and g.request_params['Digits'] == '9': r.redirect(url_for('.index')) return r sel = int(g.request_params['Digits']) del g.request_params['Digits'] try: legislator = read_context('legislators')[sel - 1] g.request_params['bioguide_id'] = legislator['bioguide_id'] return True except: del g.request_params['Digits'] r.say('%d is not a valid selection, please try again.' % sel) # If we don't have a bioguide, or legislators, or a zip selection, # skip this and get a zip code first. if not len(legislators) and not get_zip() and not 'Digits' in g.request_params.keys(): return zipcode_selection() # If we do have a zip code selection, store it before trying to get legislators. if not len(legislators) and not get_zip(): zipcode_selection() # If we have a zip and no legislators, load them. if not len(legislators): load_members_for(get_zip()) legislators = read_context('legislators', []) # If there are legislators, prompt for a choice. If still nothing, fail and get a new zip. if len(legislators): with r.gather(numDigits=1, timeout=settings.INPUT_TIMEOUT) as rg: if len(legislators) > 3: rg.say("""Since your zip code covers more than one congressional district, you will be provided with a list of all possible legislators that may represent you. Please select from the following names:""") else: rg.say("""We identified your representatives in Congress.""") rg.say("""Please select from the following:""") options = [(l['fullname'], l['bioguide_id']) for l in legislators] script = " ".join("Press %i for %s." % (index + 1, o[0]) for index, o in enumerate(options)) script += " Press 0 to enter a new zip code." if len(legislators) < 8: script += " Press 9 to return to the previous menu." rg.say(script) else: r.say("We were unable to locate any representatives for") r.say("%s." % get_zip()) flush_context('zipcode') try: del g.request_params['Digits'] except: pass r.redirect(request.path) return r