Drupal, Ubercart, and Salesforce Integration

A few of my recent projects have focused on integrating Drupal with Salesforce. This is accomplished by either using a form post (which is the most basic integration strategy most use) to tightly integrating Drupal modules and content types to business objects in Salesforce.

The community has provided many useful toolkits and source code samples to accomplish the task. But most are a means to an end and not a complete solution. As with any business process the logistics are just as important as the tools used. You should expect to program custom functions and modules in Drupal to address exceptions or features that are not covered in the tools available.

Janrain

This project focused on integrating webform submissions into the client's salesforce account. Although the community provided two webfore to Salesforce modules neither were stable enough nor supported the client's business processes. The client required that both analytics code and tracking be integrated into the form submission and pass along to custom fields in the business objects in Salesforce.

The solution was to leverage the newest Webform Module release (3.0 Beta branch) with supporting Webform Validation and extension modules (Webform PHP) to execute posting a submission array to the Salesforce webform submission system. One gotcha was making sure the form was submitted using "application/x-www-form-urlencoded" as for some reason webform wasn't send the data in the correct encoding type but instead sending the post as "multipart/form-data".

On the "Additional Processing" field for the website I used the following script to grab the fields from the website and send a post object to the Salesforce.com Servlet.

  1. // submitted webform values
  2. $f = $form_state['values']['submitted_tree'];
  3.  
  4. // log form submitted
  5. watchdog('SalesForce', 'Lead form submitted to SalesForce... '.print_r($f, true), array(), WATCHDOG_DEBUG);
  6.  
  7. // set description
  8. $desc = $f['description'];
  9.  
  10. // set field values to be posted to salesforce
  11. $fields = array(
  12. 'oid' => '{salesforceaccountid}',
  13. 'retURL' => 'http://www.example.com/',
  14. 'lead owner' => 'example user name',
  15. 'first_name' => $f['first_name'],
  16. 'last_name' => $f['last_name'],
  17. 'email' => $f['email'],
  18. 'phone' => $f['phone'],
  19. 'title' => $f['title'],
  20. 'company' => $f['company'],
  21. 'URL' => $f['website_url'],
  22. 'state' => $f['state'],
  23. 'country' => $f['country'],
  24. 'description' => $f['desc'],
  25. 'industry' => $f['industry'],
  26. 'lead_source' => $f['lead_source']
  27. );
  28.  
  29. // set salesforce url
  30. $url = 'http://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8';
  31.  
  32. // set the content type expected by salesforce
  33. $headers = array('Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8');
  34.  
  35. // assemble data into typical 'form submission' format expected by salesforce
  36. $data = http_build_query($fields, '', '&');
  37.  
  38. // invoke the http request to salesforce
  39. $result = drupal_http_request($url, $headers, 'POST', $data);
  40.  
  41. // log results, success or failure
  42. if ($result->code == 200) {
  43. watchdog('SalesForce', 'Successful lead form submission to SalesForce.', array(), WATCHDOG_DEBUG);
  44. } else {
  45. watchdog('SalesForce', 'Failed lead form submission to SalesForce... '.print_r($result, true), array(), WATCHDOG_ERROR);
  46. }

River Network

For this project I was tasked with integrating three separate parts of Drupal together to communicate with Salesforce.com: Drupal content types, Ubercart orders, and Webform submissions. As mentioned in the Janrain project the webform integration would leverage a similar solution using the Webform and manually defining the post elements to submit to the client's salesforce account. The solution will again leverage the newest Webform Module release (3.0 Beta branch) with supporting Webform Validation and extension modules (Webform PHP) to execute posting a submission array to the Salesforce webform submission system.

The next effort was integrating Ubercart orders into "Opportunity" business objects in Salesforce. Both the ubercart integration and the more advanced content type synchronization was accomplished leveraging the Salesforce API Module in addition to several patches and community extensions provided in issue queues and blog posts. It is unfortunate that many of the community extensions are not included in the official release. Perhaps that will change over time, but I found it was better to think of the module as a starting point that would require tweaks and modification from project to project. Rather than looking at it as a black box with amazing features that you just "use" like the one might do with the views or panels modules. Although the community has provided several bridge modules to link salesforce to webforms all were too ridged for the business and technical requirements of the project. And because of this, I had to write custom modules to extend or expand the ubercart order object, and added order completion hooks to not only capture order information but also link orders to Salesforce business objects.

Which brings me to the last and most technically complex aspect of the project. Syncing content types between Drupal and Salesforce. Sure you can bridge an interface between a Drupal content type and Salesforce utilizing the Salesforce API module. But if you have specific business rules and processes that also depend on customers purchasing the right to create said content types. Well, you find that the API is a great start but requires significant customization and extension to meet the projects goals. The primary challenge is supporting the field types from Salesforce into Drupal, one most cases a string field from Salesforce would equal a text field in CCK. But some field types in Salesforce include functions or business rules that in most cases, leverage data or system information not exposed to Drupal. For each field such as a "picklist" or "multipicklist" you will have to write handlers to conduct pre and post processing both into and out of Drupal so that the data can remain synced and usable in both systems. Perhaps I will provide a searchable database of rules for bridging the interface between Drupal and Salesforce in my Knowledge section in the near future.

Posted by: at 7:37 PM