I spend the weekend of April 4-6 at New England GiveCamp, a weekend hackathon that pairs tech and design people with charities in the Boston and New England region.
This year, I worked for Generations Inc., a Boston-based charity that pairs senior citizens as literacy tutors for children.
The process they used for accepting volunteer applications was time- and labor-intensive. Basically, they used the Job Manager WordPress plugin to accept applications, which went into their WordPress install as a custom post type.
Then, a staff member would have to re-enter all that information into Salesforce, which they use to track volunteers, clients and related assignments.
Since Salesforce is the endpoint for managing all of Generations Inc.’s relationships, they wanted a way to take online applications and put them directly into Salesforce. So that was my project for the weekend.
Meet The Team
Generations Inc. was represented by Daniel Smith, who coordinates their VISTA program development, and Zachary Tapp, their IT coordinator.
I’ve been to five GiveCamps now, and this is the first time I enjoyed a client that has a professional IT manager. Let me tell you, it’s a huge help. Zachary not only managed his WordPress install properly, he’s got his Salesforce install on lock, too; which means the information I needed to do this project, and the questions I had about the underlying structure of the Salesforce records I was working with, were answered quickly and completely.
I took an immediate shine to Daniel, who was about as friendly a person as they come and really interested in the technical aspects of what we were doing this weekend, which was also a GiveCamp first. That is, all my clients have been interested in their projects; but none, until this year, really were interested in the nuts and bolts of what I was doing. Both Daniel and Zachary were.
Daniel also treated me on Saturday to a sizable pouch of Peretti’s loose cigarette tobacco. I’m not sure which blend it is (I should email him and ask), but it is an incredibly smooth smoke.
I worked on the project with Anna Sun, a Northeastern student who was attending her first GiveCamp.
Anna is spending a significant amount of money to learn proper programming from one of the nation’s top schools. I looked at some of the code she was working on for school and it was absolutely pristine, a model of proper architecture and elegance.
And then GiveCamp turned her over to me to slap together a WordPress plugin in a marathon weekend. My apologies to the community for corrupting a promising career.
Salesforce and WordPress
For those not familiar with it, Salesforce is arguably the world’s leading Web-based customer relationship management software.
What that means is that you put into Salesforce records representing your customers, employees, events, donations and the like, and Salesforce both tracks who is doing what and can generate reports that make it easier to, for example, target fund-raising campaigns to those most likely to contribute; manage annual membership renewals; or see who has which educational materials checked out.
In essence, Salesforce is a relational database system with a powerful report-writing system. It’s easy to use if it’s set up properly, but flexible enough so that in capable hands, it can pretty much keep watch over even the most complicated operations out there.
There’s only one out-of-the-box, Salesforce-provided WordPress plugin that I know of: It lets users make custom forms to generate lead and case records.
In the Salesforce world, a lead record is basically a contact form, which can be tagged in a number of ways to put it in front of the correct user, and which can be converted into a person record (or some other appropriate record type) if something comes of the lead. A case is basically a customer interaction, usually along the lines of a complaint or support request.
So an option available this weekend was to use that plugin to simply generate lead records, which the staff could then convert into person-based contact records. (In Salesforce, the base record types indicating an entity are person and business, both of which can be extended into different, customized types, such as a contact record.)
Going With The API
Ideally, that is what I should have used for this task: A form customized to generate a lead, with sufficient metadata to allow conversion into the appropriate kind of person record once the vetting process was complete.
However, that’s an extra step, and the workflow at Generations Inc. is to not begin with a lead, but to create a person record anytime a volunteer applies, even if that person is not ultimately placed as a tutor. Also, there is some special information Generations Inc. needs in order to initially vet a volunteer, and while I could have gotten that into a lead, getting it to map 100 percent with the relevant person record wasn’t something I felt confident about.
So instead, I opted to use the Salesforce SOAP API.
The Salesforce SOAP API Versus The REST API
Salesforce has a very robust developer portal, including a free sandbox account, both SOAP and REST APIs (plus a SQL-like query language), libraries in several languages, documentation that tends toward the better side of adequate and support forums populated by people who generally know what they are talking about.
In light of that, and the customer’s specific need to have certain information in every new record, the choice really came down to which API I should use.
I opted for SOAP because:
- The process of entering credentials is way easier in SOAP. The Salesforce REST API depends on OAuth. While this in and of itself isn’t a problem, I worried a bit about key expiration. Generations Inc. could always regenerate their consumer keys, and I could always create a settings panel to re-enter keys if they ever expired, but it seemed a bit complicated and error-prone, given that the SOAP API just requires a user account and a secret key which can also be regenerated.
- SOAP is easier to use server-side. Since I want to ensure that the records I am putting into Salesforce are clean, I’m going to sanitize them via PHP; since I’m in PHP anyway, it’s a little easier to spin up an object representing the record, fill out its properties, and send it in via SoapClient.
- I’m more familiar with SOAP. I prefer the structure of a SOAP request over that of a JSON request, and I trust it more. Also, SoapClient is going to give me back a less primitive response, meaning that what happened to my request at Salesforce is easier to discover and handle, especially if things went badly.
The solution itself was simple enough:
- Write functions to output the form and to process it.
- A shortcode controls where the form appears and is processed. The shortcode simply checks for form postback. If the form’s nonce exists in a $_POST variable and validates, the form is processed; if not, the form is shown.
- I create the Salesforce request with a SoapClient, check the response, and report results. If things went poorly, and the record couldn’t be inserted, I simply email the form’s contents to a specified contact. If things went well, I email that contact with the record number and name of the person inserted into Salesforce.
- Finally, there needs to be an admin screen to allow Generations Inc. to provide the email address that should get the notifications, a toggle as to whether to email notifications, and to store API credentials.
The actual time to create, configure and deploy the solution was about 10 hours. I’m not actually sure of that, however, since it was a typical GiveCamp weekend, meaning there was a lot of helping others, dining, talking and other distractions that meant I was never on task for more than about 90 minutes straight.
But that’s typical of how I program in any event.
A couple observations on things I continue to learn with each GiveCamp:
- I took the Amtrak Downeaster from Portland to North Station this year, and while it was far more comfortable than the bus (I booked a business class seat, which is well worth the extra $8), the axiom holds true: If it’s worth attending, it’s worth flying. In future years, I’ll book a Cape Air flight, like I did last year. It’s just too tiring to travel for 6-8 hours on public transit.
- Like last year, I spent the night at Microsoft NERD, but this year I purchased a $20 air mattress from Walmart, and it made all the difference. Almost as comfortable as sleeping at home.
All in all, it was another successful camp, and I’m very much looking forward to New England GiveCamp 2015.
All links in this post on delicious: https://delicious.com/dougvdotcom/new-england-givecamp-2014-recap