1

I am trying to execute a trigger send email after a Case record is created/updated to meet a criterion. For this I used out of the box trigger send functionality available in SFDC through SFMC connector. However, here for the recipient lookup , I need to compulsorily add contact/lead. But, if I do this, I get the subscriber ID as contactId in SendLog. I want the subscriber Id as ID of a custom object that we are using as subscriber between SFMC and SFDC.

What is the correct way to approach and achieve this?

Probably , this could be done via REST/SOAP API calls to SFMC. It would be helpful if there is an example code explaining this. In the documentation, they have given JAVA/.Net code for making SOAP API calls.

Also, can REST API be used for the same, and if yes how?

SOAP request:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance
">
 <Header>
    <fueloauth>ACCESS_TOKEN</fueloauth>
 </Header>
 <Body>
      <CreateRequest xmlns="http://exacttarget.com/wsdl/partnerAPI">
     <Objects xsi:type="TriggeredSendDefinition">
        <PartnerKey xsi:nil="true"/>
        <ObjectID xsi:nil="true"/>
        <CustomerKey>397</CustomerKey>
        <Name>Triggered Send Email for Case when failed count is 1</Name>
        <Description>Exacttarget TriggeredSend Definition demo desc</Description>
        <SendClassification>
           <PartnerKey xsi:nil="true"/>
           <CustomerKey></CustomerKey>
           <ObjectID xsi:nil="true"/>
        </SendClassification>
        <Email>
           <PartnerKey xsi:nil="true"/>
           <ObjectID xsi:nil="true"/>
           <ID>155</ID>
           <CustomerKey>a3f44aa9-1a91-45f1-8786-6a02d5f9fc41</CustomerKey>
        </Email>
        <!-- must use the data extension created with Triggered Send Template-->
        <SendSourceDataExtension>
           <CustomerKey>021EFBC6-4092-4B5E-B377-6424D79FC94B</CustomerKey>
        </SendSourceDataExtension>
        <TriggeredSendStatus>Active</TriggeredSendStatus>
     </Objects>
  </CreateRequest>
 </Body>
</Envelope>
  • Here's a very good example of SOAP calls to interact with the SFMC salesforce.stackexchange.com/questions/174380/… – mario ruiz Feb 5 at 16:01
  • Here's another one salesforce.stackexchange.com/questions/179328/… However not sure if are helpful for You as seems your requirement is different. – mario ruiz Feb 5 at 16:03
  • @MarioRuiz : Thanks for pointing to these links. I have a very basic question. 1. What should be the password for these SOAP requests? 2. How to write Apex code for creating these requests. All sample code in documentation is .net or Java code. Appreciate your response. – Sarang Feb 5 at 16:34
  • The user and passwords are the ones used for login as normal You do through the web site. I have not experience on APEX. – mario ruiz Feb 5 at 19:03
3
+50

But, if I do this, I get the subscriber ID as contactId in SendLog. I want the subscriber Id as ID of a custom object that we are using as subscriber between SFMC and SFDC.

You should use the subscriber Id of salesforce, it will be needed if you want to take advantage of all the JourneyBuilder's activities it has.

can REST API be used for the same, and if yes how?

Yes it can be used, you should not use the user/password for SOAP request but the token retrieved in the REST API call described in: https://developer.salesforce.com/docs/atlas.en-us.mc-getting-started.meta/mc-getting-started/requestToken.htm

Then you can use the code in a SOAP API call:

        <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://exacttarget.com/wsdl/partnerAPI">
           <SOAP-ENV:Header>
       <fueloauth xmlns="http://exacttarget.com">YOUR_TOKEN</fueloauth>
      </SOAP-ENV:Header>
        [...]

Or in the any REST call as usual in the Authorization header. You can embed your rest api call in APEX like (for retrieving the token):

private final String CONTENT = 'Content-Type';
private final String AUTHORIZATION = 'Authorization';
private final String BEARER = 'Bearer ';
private final String FORM_URLENCODED = 'application/x-www-form-urlencoded';
private final Integer CODE_200_OK = 200;
private final String ACCESS_TOKEN = 'accessToken';
private final String EXPIRES_IN = 'expiresIn';
private final String METHOD_POST = 'POST';
public final static String LOGIN_URL = '<YOUR_SUBDOMAIN>.auth.marketingcloudapis.com/v1/requestToken';//OLD url is https://auth.exacttargetapis.com/v1/requestToken

public HttpResponse performRequest (String method, String url, Map<String, String> headerMap, String body){
    HttpResponse response = null;
    HttpRequest httpRequest = new HttpRequest();
    Http httpClient = new Http();

    httpRequest.setEndpoint(url);
    httpRequest.setMethod(method);
    if(headerMap != null){
        for(String headerName : headerMap.keySet()){
            httpRequest.setHeader(headerName, headerMap.get(headerName));
        }
    }
    if(String.isNotEmpty(body)) httpRequest.setBody(body);
    httpRequest.setTimeout(TIMEOUT);

    response = httpClient.send(httpRequest);

    return response;
}

@Future(callout=true)
private String doLogin(String clientID, String clientSecret){
    String body;
    String accessToken;
    Map<String, String> headers = new Map<String, String>();        
    body = 'clientId=' + clientID + '&clientSecret=' + clientSecret;

    headers.put(CONTENT, FORM_URLENCODED);

    HttpResponse response = performRequest(METHOD_POST, LOGIN_URL, headers, body);

    if(response.getStatusCode() == CODE_200_OK){
        Map<String, Object> responseBody = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
        accessToken = (String) responseBody.get(ACCESS_TOKEN);
        expiresIn = (Integer) responseBody.get(EXPIRES_IN);
    }

    return accessToken;
}

For sending Triggered emails you have do as its in the documentation: https://developer.salesforce.com/docs/atlas.en-us.mc-apis.meta/mc-apis/messageDefinitionSends.htm and the code in apex looks like:

private final String TRIGGERED_EMAIL_BODY = '{ '+
            '"To": { '+
            '"Address": "{emailAddress}",'+
            '"SubscriberKey": "{subscriberKey}", '+
                '    "ContactAttributes": { '+
                '        "SubscriberAttributes": { '+
                '            {attributes} '+
                '        }'+
                '    }'+
                '},'+
                '"OPTIONS": { '+
                '    "RequestType": "ASYNC" '+
                '}'+
            '}';
private final String ACCESS_TOKEN = 'accessToken';
private final String SEND_MAIL_URL = '/messaging/v1/messageDefinitionSends/key:{triggeredEmailKey}/send';
private final String BASE_URL = '<YOUR_SUBDOMAIN>';
private  final String APPLICATION_JSON = 'application/json';

public HttpResponse sendTriggeredEmail (String triggeredEmailKey, String emailAddress, String subscriberKey, Map<String, String> attributesMap, String token){
    String token = getAccessToken();
    String method = METHOD_POST;
    String url = BASE_URL + SEND_MAIL_URL.replace('{triggeredEmailKey}', triggeredEmailKey);
    Map<String, String> headerMap = new Map<String, String>();
    String attributes = '';
    String body ;

    if(attributesMap != null && attributesMap.size() > 0){
        for(String attr : attributesMap.keySet()){
            attributes += '"' + attr + '" : "' + attributesMap.get(attr) + '" ,';
        }
        attributes = attributes.removeEnd(' ,');
    }

    body = TRIGGERED_EMAIL_BODY.replace('{emailAddress}', emailAddress).
        replace('{subscriberKey}',subscriberKey).
        replace('{attributes}', attributes);

    headerMap.put(CONTENT, APPLICATION_JSON);
    headerMap.put(AUTHORIZATION, BEARER + token);

    HttpResponse response = performRequest(method, url,  headerMap, body);

    return response;
}
  • Thanks @SebOB. REST part I could understand and is working. But for SOAP I get error as : Requested value 'APIObject' was not found. Updated my SOAP request in question. – Sarang Feb 8 at 9:37
  • Also from documentation I came to know that SOAP is the better approach for triggered send emails while for SMS REST is recommended. Could you please clarify on which approach to use. – Sarang Feb 10 at 7:46
  • 1
    I would use REST API for both, its much easier to integrate with APEX or any other third party system. You can use POSTMAN to test it, there is a collection you can import in github.com/salesforce-marketingcloud/postman – SebOB Feb 11 at 8:07
  • Yes, I did test it with postman. The only concern here is recommendation by salesforce to SOAP for email sends and lack of documentation for REST API call in SF standard documents. However, I am going forward with REST for now. – Sarang Feb 12 at 12:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.