Go Back   Mike Simonds > Salesforce > Salesforce PHP Tutorials

This is a discussion on Using Salesforce Outbound SOAP Messages with PHP within the Salesforce PHP Tutorials forums, part of the Salesforce category; Recently I have been using the Salesforce outbound SOAP messages while I

Reply
 
LinkBack Thread Tools Rate Thread
  #1  
Old 05-13-2008, 09:19 AM
Administrator
 
Join Date: May 2007
Posts: 214
Send a message via AIM to mike Send a message via MSN to mike Send a message via Yahoo to mike Send a message via Skype™ to mike
Using Salesforce Outbound SOAP Messages with PHP

Recently I have been using the Salesforce outbound SOAP messages while I was working on some workflow's. Honestly I had no idea that this could be implemented and I am in awe right now.

My organization needed to find a way to change the Owner Id on a custom object when a certain field changed. We implemented a workflow, which in turn would thin trigger an outbound message from Salesforce via the API. An outbound message looks like and is formatted in XML. Here is an example:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
   <OrganizationId>00DR......</OrganizationId>
   <ActionId>04kR00000004CCXIA2</ActionId>
   <SessionId xsi:nil="true"/>
   <EnterpriseUrl>https://cs2-api.salesforce.com/services/Soap/c/8.0/4e1300DR00000000XcD</EnterpriseUrl>
   <PartnerUrl>https://cs2-api.salesforce.com/services/Soap/u/8.0/4e1300DR00000000XcD</PartnerUrl>
   <Notification>
    <Id>04lR0000000CcIFIA0</Id>
    <sObject xsi:type="sf:Design_Registration__c" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
     <sf:Id>a06R00000009QZaIAM</sf:Id>
     <sf:BU_Reviewer_Lookup__c>00540000000lnc2AAA</sf:BU_Reviewer_Lookup__c>
     <sf:DP_cust_eng_email__c>me@email.com</sf:DP_cust_eng_email__c>
     <sf:DP_reg_id__c>JXD08-7CLLB7</sf:DP_reg_id__c>
     <sf:DR_Number__c>R080500453</sf:DR_Number__c>
     <sf:Field_reviewer_lookup__c>00540000000yHbGAAU</sf:Field_reviewer_lookup__c>
     <sf:Name>URT</sf:Name>
     <sf:OwnerId>00540000000mBqsAAE</sf:OwnerId>
    </sObject>
   </Notification>
  </notifications>
 </soapenv:Body>
</soapenv:Envelope>
The key to this is that you are allowed to include almost any field in the outbound message. You can set these values when you are creating the trigger in Salesforce.

Once you set the fields, they are sent in the sObject portion of the SOAP message:

Code:
<sObject xsi:type="sf:Design_Registration__c" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
     <sf:Id>a06R00000009QZaIAM</sf:Id>
     <sf:BU_Reviewer_Lookup__c>00540000000lnc2AAA</sf:BU_Reviewer_Lookup__c>
     <sf:DP_cust_eng_email__c>me@email.com</sf:DP_cust_eng_email__c>
     <sf:DP_reg_id__c>JXD08-7CLLB7</sf:DP_reg_id__c>
     <sf:DR_Number__c>R080500453</sf:DR_Number__c>
     <sf:Field_reviewer_lookup__c>00540000000yHbGAAU</sf:Field_reviewer_lookup__c>
     <sf:Name>URT</sf:Name>
     <sf:OwnerId>00540000000mBqsAAE</sf:OwnerId>
    </sObject>
The great thing is that you can then kick off almost any application with this with a SOAP Server that is setup locally (we have one running on our server).

The key is that you have to send a response back to your instance of Salesforce.

So once the SOAP Server is setup on your server, you can respond to an incoming message like this:

PHP Code:
//Reads SOAP incoming message from Salesforce/MAPS
$data fopen('php://input','rb');
$content fread($data,5000); 
This code reads the raw data coming in from Salesforce and then sticks it in a variable called $content.

You can then respond to the message like this:

PHP Code:
if ($content)
{
    respond('true');
}
else
{
    respond('false');
}

function respond($tf)
{

    print '<?xml version "1.0" encoding "utf-8"?>
   <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <soapenv:Body>
           <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
               <Ack>' . $tf . '</Ack>
              </notifications>
          </soapenv:Body>
      </soapenv:Envelope>';
}
So $tf is set to true and responds to the outbound message and Salesforce knows that the message has been accepted and is removed from the queue.


So what can you really do with this? We are using this workflow to change the OwnerId on a custom object when a certain field is changed

I will continue to update this thread with different topics and ideas on what I have been able to accomplish with this on demand feature

~Mike
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote

  #2  
Old 05-13-2008, 11:50 AM
Junior Member
 
Join Date: May 2008
Posts: 5

What does it take to get a SOAP server setup? What's needed architecturally to configure the end point? Just any PHP server that is ready and able to connect to Salesforce using the PHP toolkit?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3  
Old 05-13-2008, 02:12 PM
Administrator
 
Join Date: May 2007
Posts: 214
Send a message via AIM to mike Send a message via MSN to mike Send a message via Yahoo to mike Send a message via Skype™ to mike

Hey Scott !!

listen the setup (still totally new at this) was rather quite easy

First off, do you know how to setup the outbound workflow in Salesforce?

I am sure you do, you are a lot more knowledgeable than I am, LOL!

Listen there is no special setup for the SOAP server setup.

I just have that code that I posted in the first post of this thread and a parser to read XML (the incoming SOAP message)

for testing purposes, I wrote it out to a file and then used that to parse the XML until I felt comfortable with the data I was seeing using print_r.

You can use PHP's built in XML DOM. I found this example at the salesforce forums:

PHP Code:
<?php
/* Handles SFDC Outbound Message notification.*/
require_once ('../includes/salesforce_login.php');


// Get raw post data
$data fopen('php://input','rb');
$content fread($data,5000);

// Parse values from soap string
$dom = new DOMDocument();
$dom->loadXML($content);
$resultArray parseNotification($dom);
$sObject $resultArray["sObject"];

// Output field names and values to file
$fields_string "";

foreach (
$sObject->fieldnames as $field)
{
    
$fields_string .= $field " => " $sObject->fields->$field "\n";
}


// Write message and values to a file
$fh fopen('soap.xml','a');
fwrite($fh,$content);
$ret fclose($fh);


// Sends SOAP response to SFDC
if ($ret)
{
    
respond('true');
}
else
{
    
respond('false');
}
//functions

/* Parse a Salesforce.com Outbound Message notification SOAP packet
* into an array of notification parms and an sObject.   */
function parseNotification($domDoc)
{
    
// Parse Notification parameters into result array
    
$result = array("OrganizationId" => "","ActionId" => "","SessionId" => "","EnterpriseUrl" => "","PartnerUrl" => "","sObject" => null);

    
$result["OrganizationId"] = $domDoc->getElementsByTagName("OrganizationId")->item(0)->textContent;
    
$result["ActionId"] = $domDoc->getElementsByTagName("ActionId")->item(0)->textContent;
    
$result["SessionId"] = $domDoc->getElementsByTagName("SessionId")->item(0)->textContent;
    
$result["EnterpriseUrl"] = $domDoc->getElementsByTagName("EnterpriseUrl")->item(0)->textContent;
    
$result["PartnerUrl"] = $domDoc->getElementsByTagName("PartnerUrl")->item(0)->textContent;

    
// Create sObject and fill fields provided in notification
    
$sObjectNode $domDoc->getElementsByTagName("sObject")->item(0);
    
$sObjType $sObjectNode->getAttribute("type");
    if (
substr_count($sObjType,"sf:"))
        
$sObjType substr($sObjType,3);
    
$result["sObject"] = new SObject($sObjType);
    
$result["sObject"]->type $sObjType;

    
$sObjectNodes $domDoc->getElementsByTagNameNS('urn:sobject.enterprise.soap.sforce.com','*');
    
$result["sObject"]->fieldnames = array();
    foreach (
$sObjectNodes as $node)
    {
        if (
$node->localName == "Id")
        { 
// Id goes under sObject->Id
            
$result["sObject"]->Id $node->textContent;
        }
        else
        { 
// ... the rest go under sObject->fields
            
$fieldname $node->localName;
            
$result["sObject"]->fields->$fieldname $node->nodeValue;
            
array_push($result["sObject"]->fieldnames,$fieldname);
        }
    }

    return 
$result;
// end parseNotification


function respond($tf)
{

    print 
'<?xml version = "1.0" encoding = "utf-8"?>
   <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <soapenv:Body>
           <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
               <Ack>' 
$tf '</Ack>
              </notifications>
          </soapenv:Body>
      </soapenv:Envelope>'
;
}
?>
to get me started. I had some small troubles and also purchased a off the shelf XML parser that reads the SOAP message better than the DOM XML built in class.

So basically it is easy to setup and get working, I can take this offline sometime if you want

~Mike

PS: good to see you here, I need to add a link to your site on my main page, I forgot to do that
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4  
Old 05-13-2008, 04:46 PM
Junior Member
 
Join Date: May 2008
Posts: 5

Awesome. Got it working! Now I need to figure out what to implement, but this is a really nice option to have.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5  
Old 05-13-2008, 05:03 PM
Administrator
 
Join Date: May 2007
Posts: 214
Send a message via AIM to mike Send a message via MSN to mike Send a message via Yahoo to mike Send a message via Skype™ to mike

Outstanding man!! Glad that helped.

Listen if you come up with Ideas, fixes or things that work and you post them on your site, would you be willing to post a link here or the code and let me know what you did or found?

FYI > I added a link from my main menu to your site


~Mike
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6  
Old 06-26-2008, 01:26 PM
Administrator
 
Join Date: May 2007
Posts: 214
Send a message via AIM to mike Send a message via MSN to mike Send a message via Yahoo to mike Send a message via Skype™ to mike

Scott we have taken this service and added a whole new object via the outbound messaging. It is really like combining a whole bunch of queries using the data coming in from the salesforce outbound messaging and querying multiple tables

Then we take that data and create a whole new data flow for a new Object in Salesforce. It works like a charm

So if they change a status on the custom object, it kicks off a SOAP outbound message that you could really do anything with!!

Stick it into a custom reporting application, A database, or back into Salesforce

I am thinking this is like the new trigger function in APEX, but keeping your process outside of Salesforce and not having to learn APEX coding (even though I need too)

Have you had a chance to mess around with this at all

~Mike
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump



Powered by vBulletin


SEO by vBSEO 3.2.0 RC8 ©2008, Crawlability, Inc.

1 2 3 4 5