Mugo Web main content.

Salesforce and Marketo integration with eZ Publish

By: Thiago Campos Viana | September 5, 2014 | Business solutions, Case study, and integration

eZ Publish is a powerful Content Management System (CMS), but you typically don't try to build Customer Relationship Management (CRM) and E-mail Marketing features directly into it.  Instead, you usually integrate it with existing solutions. We recently integrated eZ Publish with Salesforce and Marketo on a subscription-based website.

Salesforce is best known for its CRM features; if you want to do CRM like a pro, it is one of the best options. Marketo is gaining popularity for its marketing automation solutions. A key ingredient in our solution is the Marketo integration with Salesforce, which made the integration with eZ Publish easier. We could manage the user information in just one place and Salesforce and Marketo would synchronize the information automatically.

We decided to use the Salesforce API and store most of the user profile data in Salesforce (aside from the account password); we do store some information both locally (in the CMS) and in Salesforce, like "first name" and "last name", but all other data are in Salesforce only. Thus, when a user registers on the website, we create a new lead in Salesforce. When the user edits their profile, we fetch the data from Salesforce and then update the profile in Salesforce. The management team is thus able to keep track of leads using the native Salesforce interface.

Because of the Marketo-Salesforce integration, we do not have to deal with creating and updating leads in Marketo. We use the Marketo API to schedule e-mail newsletter campaigns. Basically, you can define your campaigns in Marketo, specifying filters to be used when fetching the leads for a campaign and then track the results. Marketo will call a certain URL periodically (a "webhook") so you can define a webservice that will handle the webhook call and process the request. When Marketo calls your webservice, you can use the Marketo SOAP API to schedule one of your existing campaigns, according to the parameters received from Marketo's call. You can also produce e-mail content, such as the HTML body, in the CMS to be consumed by Marketo.

The result is a flexible and powerful system to manage leads and e-mail campaigns.

Salesforce API example

In order to use the Salesforce API you first need to download the Salesforce SOAP client. You will probably download the whole project, but all you really need is the soapclient folder, which you can put in your eZ Publish extension's classes folder. Once you regenerate the autoload array, you should be ready to use it in your eZ Publish project.

Below is some sample code showing how to create a Salesforce lead using the SOAP API.

<?php

/*--------------------------------------------------------\
|  Create a lead using the Salesforce account 
|  Get the LEADID and modify it in following file
|  userAuth.php in samples directory
\--------------------------------------------------------*/

//Used for sample convertLead from file convertLead.php
$convertLEADID = '00Q5000000DO0gJEAT';

//Used for sample fieldsToNull from file fieldsToNull.php
$LEADID = '00Q5000000DO0gs';

//Used for sample loginScopeHeader from file loginScopeHeader.php
$LOGINSCOPEHEADER = '00E200000004wk3EAA';

//Used in sample processSubmitRequest from file processSubmitRequest.php
$OBJECTID1 = '00Q5000000G7YV8';
$OBJECTID2 = '00Q5000000J4pQp';
$NEXTOBJECTID = '00530000000tH4t';

//Used for sending e-mail from file sendEmail.php
$EMAILID = 'your@email.com';

//Used for updating object from file update.php
$UPDATEOBJECTID1 = '00Q5000000K0KjM';
$UPDATEOBJECTID2 = '00Q5000000K1sL1';

//Used in callOptions
$YOURCLIENTID = 'YourClientId';
$NAMESPACE = 'aNamespace';

//Used for emailHeader from file emailHeader.php
$EMAILIDFORHEADER = 'email1@test.com';

/*--------------------------------------------------------\
|
|  For Enterprise Samples
|
\--------------------------------------------------------*/
//Need to login on account then create the lead
//Assign that id here and check the sample
$eLEADID = "00Q5000000DO0gJEAT"; 


class SalesForceProcessor
{

    /*
    Fields is one array of salesforce valid fields, example:
    $fields = array(
                  'FirstName' => eZHTTPTool::postVariable('profile_first_name'),
                  'Email' => eZHTTPTool::postVariable( 'profile_email' ),
                  'LastName' => eZHTTPTool::postVariable('profile_last_name'),
                  'Company' => eZHTTPTool::postVariable('profile_company'),
                  'Industry' => eZHTTPTool::postVariable('profile_industry'),
                  'Title' => eZHTTPTool::postVariable('profile_title'),
                  'Phone' => eZHTTPTool::postVariable('profile_phone'),
                  'Country' => eZHTTPTool::postVariable('profile_country'),
                  'City' => eZHTTPTool::postVariable('profile_city'),
              );
    */
    public static function createLead( $fields )
    {             

        try {
        
            /*--------------------------------------------------------\
            |  Assign your USER ID & PASSWORD with TOKEN 
            |  This file is included in each of the SAMPLES
            \--------------------------------------------------------*/
            $ini    = eZINI::instance( 'salesforce.ini' );

            $USERNAME = $ini->variable( 'SalesForce', 'User' );
            $PASSWORD = $ini->variable( 'SalesForce', 'Pass' );
            $mySforceConnection = new SforcePartnerClient();
            $mySoapClient = $mySforceConnection->createConnection('extension/yourextension/classes/soapclient/partner.wsdl.xml');
            $mylogin = $mySforceConnection->login($USERNAME, $PASSWORD);
            
            //Creating the Lead Object
            $lead = new stdClass;
            $lead->type = 'Lead';
            $lead->fields = $fields;
         
            //Submitting the Lead to Salesforce
            $result = $mySforceConnection->create(array($lead), 'Lead');
            eZLog::write( "New enterprise user: " . $fields['FirstName'] . " "  . $fields['LastName'] . " - " . $fields['Email'], 'sf_processor.log' );

        }
        catch (Exception $e)
        {            
            eZLog::write( "Error: " . $e->faultstring . ' - ' . $mySforceConnection->getLastRequest(), 'sf_processor.log' );
        }
    
    }


}

This is just a small example, but you can check the links below for more information about the Salesforce SOAP API:

Marketo API Example

In this example I will show how to schedule campaigns using the Marketo API. This is the code for a sample module view:

<?php

eZLog::write( implode( ', ', $_POST ), 'marketo.log' );
// Uncomment the line below for testing AND the line 75
//$_POST['pass']="YOURPASS";$_POST['program']="";$_POST['campaign']="";

// Won't schedule campaigns on saturdays or sundays
if( date("w") == 0 ||  date("w") == 6 )
{
    echo json_encode(array('status'=>'failed', 'note'=>'Will not schedule campaigns on Saturdays or Sundays'));
}
else if ( isset($_POST['pass']) && $_POST['pass']=="YOURPASS" && isset($_POST['program']) && isset($_POST['campaign']) )
{
        //INSERT FORMATTING OF RSS FEED AND PUSH TO MKTO
        $debug = true;
         
        $marketoSoapEndPoint     = "YOURMARKETOSOAPENDPOINT";  // CHANGE ME
        $marketoUserId           = "YOURMARKETOUSERID";  // CHANGE ME
        $marketoSecretKey        = "YOURMARKETOSECRETKEY";  // CHANGE ME
        $marketoNameSpace        = "http://www.marketo.com/mktows/";
         
        // Create Signature
        $dtzObj = new DateTimeZone("America/New_York"); //CHANGE ME
        $dtObj  = new DateTime('now', $dtzObj);
        $timeStamp = $dtObj->format(DATE_W3C);
        $encryptString = $timeStamp . $marketoUserId;
        $signature = hash_hmac('sha1', $encryptString, $marketoSecretKey);
         
        // Create SOAP Header - No changes needed
        $attrs = new stdClass();
        $attrs->mktowsUserId = $marketoUserId;
        $attrs->requestSignature = $signature;
        $attrs->requestTimestamp = $timeStamp;
        $authHdr = new SoapHeader($marketoNameSpace, 'AuthenticationHeader', $attrs);
        $options = array("connection_timeout" => 20, "location" => $marketoSoapEndPoint);
         
         // Create Request - Edit below
        $params = new stdClass();
        $params->programName = $_POST['program'];
        $params->campaignName = $_POST['campaign'];
        $dtObj = new DateTime('now', $dtzObj);
        $params->campaignRunAt = $dtObj->format(DATE_W3C);
        
        $tpl = eZTemplate::factory();
         
        $token = new stdClass();
        // Check your campaigns tokens, this token will be used in the marketo e-mail template
        // Usually you can create the template in marketo and use this token to put the html main content
        // In our case we prefer to leave the marketo e-mail template almost empty, leaving just this token
        // So we can generate the whole e-mail html code in eZ Publish
        $token->name = "{{my.rssContent}}";
        
        switch( $_POST['program'] )
        {
            
            case 'EXAMPLE_1':
                $tpl->setVariable('myvar',1);
                break;
            case 'EXAMPLE_2':
                $tpl->setVariable('myvar',2);           
                break;
            case 'EXAMPLE_3':
                $tpl->setVariable('myvar',3);
                break;
        }
        // Uncomment the line below line for testing
        //echo $tpl->fetch( "design:yourextension/marketo.tpl" );eZExecution::cleanExit();

        $token->value = $tpl->fetch( "design:yourextension/marketo.tpl" );

        //Assign Attributes and Push to Marketo
        $params->programTokenList = array("attrib" => $token);
        $params = array("paramsScheduleCampaign" => $params);
         
        $soapClient = new SoapClient($marketoSoapEndPoint ."?WSDL", $options);
        try
        {
            $response = $soapClient->__soapCall('scheduleCampaign', $params, $options, $authHdr);
        }
        catch(Exception $ex)
        {
            var_dump($ex);
        }
        
        eZLog::write( "RAW response:\n" .$soapClient->__getLastResponse(), 'marketo.log' );

        echo json_encode(array('status'=>'success', 'note'=>'success'));
    
}
else
{
    echo json_encode(array('status'=>'failed', 'note'=>'Invalid Request'));
}


eZExecution::cleanExit();
?>

Now, you just need to define a webhook in Marketo, specifying the URL for your site's module/view, and define the password, program and campaign parameters. Marketo will use the webhook information to call your site's module/view. Then you need to make Marketo call this webhook periodically in order to create scheduled e-mail campaigns.

See the Marketo SOAP API for more information.