[SalesForce] Exact Target SOAP API: Using ‘SimpleFilterPart’ for Retrieve

I am facing a problem when triying to use the filter of the method 'retrieve' for the SOAP API of Exact Target. I dont know how to set an attribute to a node of the xml generated when using WebServiceCallout.

I need a generated xml like this (see xsi:type in Filter):

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <env:Header>
  <n1:fueloauth xmlns="http://exacttarget.com/wsdl/partnerAPI" xmlns:n1="http://exacttarget.com">
   <fueloauth>MyAuthToken</fueloauth>
  </n1:fueloauth>
 </env:Header>
 <env:Body>
  <RetrieveRequestMsg xmlns="http://exacttarget.com/wsdl/partnerAPI">
   <RetrieveRequest>
    <ObjectType>DataExtensionObject[XXXXXXXXXXXXXX]</ObjectType>
    <Properties>Email Address</Properties>
    <Properties>Date Added</Properties>
    <Filter xsi:type="SimpleFilterPart">
     <Property>Email Address</Property>
     <SimpleOperator>equals</SimpleOperator>
     <Value>testMail@gmail.com</Value>
    </Filter>
   </RetrieveRequest>
  </RetrieveRequestMsg>
 </env:Body>
</env:Envelope>

But I'am getting one without the attribute in Filter:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <env:Header>
  <n1:fueloauth xmlns="http://exacttarget.com/wsdl/partnerAPI" xmlns:n1="http://exacttarget.com">
   <fueloauth>MyAuthToken</fueloauth>
  </n1:fueloauth>
 </env:Header>
 <env:Body>
  <RetrieveRequestMsg xmlns="http://exacttarget.com/wsdl/partnerAPI">
   <RetrieveRequest>
    <ObjectType>DataExtensionObject[XXXXXXXXXXXXXXXXXXXXXX]</ObjectType>
    <Properties>Email Address</Properties>
    <Properties>Date Added</Properties>
    <Filter>
     <Property>Email Address</Property>
     <SimpleOperator>equals</SimpleOperator>
     <Value>testMail@gmail.com</Value>
    </Filter>
   </RetrieveRequest>
  </RetrieveRequestMsg>
 </env:Body>
</env:Envelope>

The code I'm using to fill the request (consider ET_WSDL the autogenerated class from the exactTarget WSDL from salesforce):

    ET_WSDL.Soap soapRequest = new ET_WSDL.Soap();
    ET_WSDL.fueloauth header = new ET_WSDL.fueloauth();

    header.fueloauth = 'MyAuthtoken';
    soapRequest.HeaderFOAuth = header;

    ET_WSDL.RetrieveRequest retrieveRequest = new ET_WSDL.RetrieveRequest();
    ET_WSDL.SimpleFilterPart filterPart = new ET_WSDL.SimpleFilterPart();

    retrieveRequest.ObjectType = 'DataExtensionObject[XXXXXXXXXX]';
    retrieveRequest.Properties = new String[]{'Email Address', 'Date Added'};

    filterPart.Property = 'Email Address';
    filterPart.SimpleOperator = 'equals';
    filterPart.Value = new String[]{'emailtest@test.com'};

    retrieveRequest.Filter = filterPart;

    ET_WSDL.RetrieveResponseMsg_element response = soapRequest.Retrieve_x(retrieveRequest);
    system.debug('SOAP: '+response);

I've changed the code of the class RetrieveRequest FilterPart–> SimpleFilterPart:

public class RetrieveRequest {
        public ET_WSDL.ClientID[] ClientIDs;
        public String ObjectType;
        public String[] Properties;
        //OLD public ET_WSDL.FilterPart Filter;
        public ET_WSDL.SimpleFilterPart Filter;//NEW
        [...]

But it doesn't add the attribute.

Anyone else facing the same issue?

Thanks in advance

Best Answer

I had the same problem using directly the apex class generated from ExactTarget WSDL in SalesForce.

I solved in this way.

First in the wsdl generated class we have to declare "virtual" the public class FilterPart. After this, we have to make the SimpleFilterPart to extend the FilerPart.

       public virtual class FilterPart {
            private String[] apex_schema_type_info = new String[]{'http://exacttarget.com/wsdl/partnerAPI','true','false'};
            private String[] field_order_type_info = new String[]{};
        }

 public class SimpleFilterPart extends FilterPart{ 
...

With this changes, you can assign a SimpleFilerPart in a request that is using a FilterPart in your apex code:

  ET_WSDL.RetrieveRequest retrieveRequest = new ET_WSDL.RetrieveRequest();
  ET_WSDL.SimpleFilterPart filterPart = new ET_WSDL.SimpleFilterPart();

  retrieveRequest.ObjectType = 'DataExtensionObject[Example]';
  retrieveRequest.Properties = new String[]{'Email Address', 'Date Added'};
  filterPart.Property = 'Email Address';
  filterPart.SimpleOperator = 'equals';
  filterPart.Value = new String[]{'example@example.com'};

  retrieveRequest.Filter = filterPart;

Ok, you have now your request using a SimpleFilterPart in a FilterPart, but the XML generated is like this:

<env:Body>
    <RetrieveRequestMsg xmlns="http://exacttarget.com/wsdl/partnerAPI">
        <RetrieveRequest>
            <ObjectType>DataExtensionObject[Example]</ObjectType>
            <Properties>Email Address</Properties>
            <Properties>Date Added</Properties>
            <Filter>
                <Property>Email Address</Property>
                <SimpleOperator>equals</SimpleOperator>
                <Value>example@example.com</Value>
            </Filter>
        </RetrieveRequest>
    </RetrieveRequestMsg>
</env:Body>

But, as we can see in ExactTarget documentation, we need to obtain an attribute in the Filter tag indicating the filter type. You can do this changing the api class generated from WSDL again:

public class SimpleFilterPart extends FilterPart{
    private String attribute = 'SimpleFilterPart';
    public String Property;
    public String SimpleOperator;
    public String[] Value;
    public DateTime[] DateValue;
    private String[] attribute_att_info = new String[] {'xsi:type'};
    private String[] Property_type_info = new String[]{'Property','http://exacttarget.com/wsdl/partnerAPI',null,'1','1','false'};
    private String[] SimpleOperator_type_info = new String[]{'SimpleOperator','http://exacttarget.com/wsdl/partnerAPI',null,'1','1','false'};
    private String[] Value_type_info = new String[]{'Value','http://exacttarget.com/wsdl/partnerAPI',null,'0','-1','false'};
    private String[] DateValue_type_info = new String[]{'DateValue','http://exacttarget.com/wsdl/partnerAPI',null,'0','-1','false'};
    private String[] apex_schema_type_info = new String[]{'http://exacttarget.com/wsdl/partnerAPI','true','false'};
    private String[] field_order_type_info = new String[]{'Property','SimpleOperator','Value','DateValue'};
}

As you can see, I have added an attribute to the SimpleFilterPart, indicating the type and the value, and then, you can see the XML now generated:

<env:Body>
    <RetrieveRequestMsg xmlns="http://exacttarget.com/wsdl/partnerAPI">
        <RetrieveRequest>
            <ObjectType>DataExtensionObject[Example]</ObjectType>
            <Properties>Email Address</Properties>
            <Properties>Date Added</Properties>
            <Filter xsi:type="SimpleFilterPart">
                <Property>Email Address</Property>
                <SimpleOperator>equals</SimpleOperator>
                <Value>example@example.com</Value>
            </Filter>
        </RetrieveRequest>
    </RetrieveRequestMsg>
</env:Body>

You can apply this solution to all classes inside your Apex class generated form the WSDL that extend from other classes.

This works for me and I hope for you too.

Bye !

Related Topic