1.5 Added the address_mailed field, the restriction that voters chosen
for the phone bank be those with a phone number on file, and the
restrictions on when a user can change a voter's contact
information
1.4 Added information about phone bank lockout
1.3 Added party affiliation to screenshots
Changed "contact_" permissions to "eblocks_" permissions
Changed "contact_" var names to "eblocks_" var names
1.2 Added gender to screenshots
Added "prime" voters
1.1 Initial version
The goal of this application is to allow anyone with a Clark Community Network account to get names, addresses, and phone numbers of people in primary states so that they can make phone calls to them and send them handwritten letters and postcards. The letter-writing functionality is more important than the phone bank functionality. There is also reporting functionality, which is less important than either.
Our overriding goal is to get this out there as soon as possible. Every daylight hour we delay costs us 10-100 letters sent.
Authentication is handled by Scoop. This is eventually going to change, so the code that gets the authenticated user should be localized to method.
You will have access to a cookie called forclark_session. This contains the session ID of the authenticated user. To get the user ID of the authenticated user, restrict sessions.id on the session ID and select the uid field.
A user with no session cookie or with one that doesn't match an entry in sessions should be sent to the login URL. You can specify a failure message in the form variable "login_message". The login URL is currently http://www.forclark.com/.
To get a user's permissions, restrict users to the authenticated user ID. join users.perm_group against perm_groups.perm_group_id, and select group_perms to get the user's permission string.
The user's permission string is a comma-separated list of permissions with a comma prepended, eg. ",perm1,perm2,perm3". Thus you can see whether a user has a permission by comparing the string against the permission name with a comma prepended.
There are three permissions specific to this application: "eblocks_use", "eblocks_admin" and "eblocks_trusted". eblocks_use is used to determine whether or not the user can even use this application. eblocks_admin is used to determine whether the user has access to the reporting features (see below). eblocks_trusted is used to exempt a user from the normal timeout features (also see below, but not as far below as for eblocks_admin) and to give them the voters most valuable to us.
I recommend implementing one method that takes the session ID and gets the user's permission string from it. If nothing comes back, send the user to the login URL. If something comes back, make a note of which of the permissions for this application this user has.
Configuration variables are stored in the "vars" table. To get the value of a variable, restrict vars on the "name" field and retrieve the "value" field. "conf(foo)" is used in this document as shorthand for "the current value of the configuration variable 'foo'".
I recommend implementing a method to get a site-wide configuration variable. Put this method in the same file as the session ID-user Id mapper.
For convenience of display, we're going to store a user's total number of phone calls and letters written in the userprefs table. This looks like this: uid int(11) prefname varchar(200) prefvalue(text) The two values for prefname are "eblocks_letters" and "eblocks_calls". Every time a user completes a call or a letter, increment the user's appropriate pref value. You can use this to display those values; the CCN will also use it.
These are field names in the "voters" table. Note that these field names may (and hopefully will) change, so you should use constants or be ready to change them.
Name: HONOR FIRSTNAM MIDNAME LASTNAME JR eg. Mr. Bob F Jones III Address: MADD MCITY MSTATE MZIPCODE Phone: PHONE Misc: PARTY GENDER Those fields come with the voter registration database. We've added these fields for this application: prime int(1) address_assigned int(11) address_notes text address_mailed char(1) phone_assigned int(11) phone_resolution varchar(50) phone_notes text
The contact list screen has two modes: letter-writing mode and phone call mode. In the first version of the code these will operate almost exactly the same. The only difference is the database fields affected, the fields shown to the user, and the time-based availability of phone call mode. Letter-writing mode is more important.
The user visits the main application screen. It defaults to letter-writing but they can choose to make phone calls instead. This is the mode of the screen.
If the user has no voters assigned to them for the current mode (and has not reached their quota--see below), then they are assigned conf(eblocks_chunk_addresses) voters not previously assigned to have letters written to them, or conf(eblocks_chunk_phone_numbers) voters not previously assigned to be called. This is done by setting the voter's address_reserved or phone_number_reserved to the user's ID.
The main application screen shows the addresses or phone numbers assigned to the user. After writing a letter or making a phone call, they'll select a resolution from a drop-down (phone only) and possibly add some notes, then click the submit button. The voter they called or wrote will then disappear from their list and they'll get a thank-you message (conf(thanks_for_call) or conf(thanks_for_mail)).
When the user completes their last letter or phone call, a special congratulatory message will be displayed (conf(thanks_for_call_chunk) or conf(thanks_for_mail_chunk)) and the user's list will be refilled to the appropriate chunk size.
When there are fewer than the maximum number of voters in the user's list, a "Refill my list" button will show up at the bottom of the screen. Clicking this button will top off the user's list of assignments to the maximum. We don't refill the list automatically because letting the user work down a list gives more of a sense of accomplishment.
A tally keeps track of how many letters and phone calls the current user has made. Both totals should show up on both pages, since the point, again, is motivation.
Voter records with the "prime" field set to 1 are especially valuable to us, and should take top priority when a user has the call_trusted permission. You can do this with an ORDER BY clause.
Apart from that, voter selection is effectively random. You can just choose the first 10 voters who are not currently assigned for the given mode. Order the voters in reverse order when looking for address vs. phone number, so that we get more coverage (we would rather have 100 people get letters and 100 other people get phone calls than have 100 people get both).
Voters without phone numbers should not be chosen for phone eBlocks.
Choose voters with party registration "D", "I", or "".
In future versions we'll try to match people better with voters who share their interests.
The purpose of the hourly limit timeout is to prevent abusive users from marking all the voters in our database as having been contacted. We can't prevent this altogether, but we can slow it down.
A user can't process more than conf(eblocks_max_hourly_addresses) addresses and conf(eblocks_max_hourly_phone_numbers) in any given hour. This is calculated by counting this user's resolved voter records for the past hour and the past day.
If a user completes all of one of their lists of voters or tops up their list, and fewer than one full chunk of voters is available due to their approaching limit, a message should be displayed to the effect of "{Only [n],No} records are being displayed because you've [almost] made your quota of [phone calls/letters] for the past hour. Please wait a while, or try [writing some letters/making some phone calls]".
Users who have the eblocks_admin or eblocks_trusted permissions are not subject to quota timeouts.
Every night at midnight Hawaii time, everyone's assignments expire. This is to keep people from unknowingly or maliciously holding on to assignments if they're not serious about making phone calls or writing letters. This can be done with a script run by cron which just deletes all unresolved assignments.
No one is exempt from the assignment release timeout. In version 2, users who have completed an assignemnt in the past day can be made exempt.
We don't want people calling New Hampshire voters at 2 in the morning. So the phone call feature should only be available at certain times of day: from conf(eblocks_weekday_phone_start) to conf(eblocks_weekday_phone_end) on weekdays and from conf(eblocks_weekend_phone_start) to conf(eblocks_weekend_phone_end) on weekends. All those times are EST.
When the phone lockout is in effect, the phone section of the application should display a message to that effect instead of offering phone numbers to call. The time the phone lockout will end should be mentioned.
This will hold us until we start going past South Carolina to states in different time zones. Then we'll need a more complex system. I'm not sure how it'll work.
They don't have to look like this, but this is the sort of thing I have in mind.
Letters | Phone calls
Thanks for completing a block of letters! We appreciate your help! In case you want to write more letters, we've assigned you a new block.
Letters | Phone calls
You've made so many phone calls that you're running up against your hourly limit. We recommend you take a break for a while, or write some letters instead. Please let us know if the limit is preventing you from volunteering as much as you'd like.