1

I need to trigger a Double Opt-In Journey process instantly after a Marketing Cloud Landingpage form submit (Smart Capture cannot be used).

I'm aware that I could save data in a DE an run an automation on it, but we need to send the Double Opt-In E-Mail right after submit. It would be perfect if I could fire the API Entry Source from AMPscript or SJSS, have anyone done that before?

  • 1
    You can add them to a DE that acts as an entry source for journey via SSJS/Ampscript. Alternative, you can make an API call from the landing page and definite the entry source as an API – Samuel Dare Jun 18 '17 at 11:19
  • "You can add them to a DE that acts as an entry source for journey via SSJS/Ampscript." How to start the journey with a DE? This seems to be possible just with the "contact data" entry source which will be disabled soon, or am I wrong? "Alternative, you can make an API call from the landing page and definite the entry source as an API" Do you have a code snippet for it? I cannot find any information in the documentation – Michael H Jun 18 '17 at 11:22
8

You can fire the event using a REST-API call to the "POST /interaction/v1/events" endpoint.

An example request looks like this:

{
    "ContactKey": "YOUR_CONTACTS_KEY",
    "EventDefinitionKey":"EVENT_DEFINITION_KEY_OF_API_EVENT",
    "EstablishContactKey": true,
    "Data": {
        "dataForEvent1":"John",
        "dataForEvent2":"Doe"
    }
}

Prerequisites:

Before initiating this request, you need to obtain an access token, that needs to be sent in the header of the request to the /interaction/v1/events endpoint. Requesting this token can be done using the /v1/requestToken endpoint and the following payload:

{
    "clientId": "YOUR_CLIENT_ID_FROM_APP_CENTER",
    "clientSecret": "YOUR_CLIENT_SECRET_FROM_APP_CENTER"
}

AMPscript example:

%%[
    Var @body, @callstatus, @response, @accessToken, @resultOfParsing
    Set @body = '{"clientId": "xxxxx", "clientSecret": "yyyyyyy"}'

    HTTPPost2("https://auth.exacttargetapis.com/v1/requestToken", "application/json", @body, True, @callstatus, @response)

    Set @body = '{"ContactKey": "YOUR_CONTACTS_KEY", "EventDefinitionKey":"EVENT_DEFINITION_KEY_OF_API_EVENT", "EstablishContactKey": true, "Data": { "dataForEvent1":"John", "dataForEvent2":"Doe"}}'

    Set @regex = '^{"accessToken":"(.*)",.*$'
    Set @accessToken = REGEXMATCH(@response, @regex, 1)
    Set @accessToken = CONCAT('Bearer ', @accessToken)

    HTTPPost2("https://auth.exacttargetapis.com/interaction/v1/events", "application/json", @body, True, @callstatus, @response, 'Authorization', @accessToken)
]%%

Further reading:

  • Ok. Do you have a code example how to fire that from AMPscript/SSJS? – Michael H Jun 18 '17 at 13:05
  • 1
    I updated my answer with a more or less complete example snippet. The only thing you need to do is extract the value of the accessToken property of the response JSON. However Salesforce StackExchange isn't meant to be a code writing service. Please read the documentation and try to write code yourself and ask here on StackExchange if you are stuck somewhere. Check out the help center on Asking. – Markus Slabina Jun 18 '17 at 13:17
  • Thanks for that super helpful information! Even this solution doesn't seem to be clean, It seems to the best one for my case at the moment. Or do you have additional ideas? – Michael H Jun 18 '17 at 13:26
  • If you like to trigger a journey and definitely want to use an API event this will be the way to go using AMPscript. You could however implement your DOI email using a triggered send and initiate this send using SSJS triggeredSend.Send – Markus Slabina Jun 18 '17 at 13:34
  • I updated my answer to include the accessToken parsing. – Markus Slabina Feb 27 at 9:44
7

Below is a similar solution using SSJS in a CloudPage to retrieve Installed Package details from a Data Extension called 'Client_Auth_Details' to perform a v2 Auth token request. This is followed by a rest call to inject a record into a Journey and then returns the EventInstanceID as confirmation. Comments are included for context.

Requirements:

-V2 Server to Server Installed Package with scope to read/write to Data Extensions as well as read/write/execute for Journeys.
-Journey configured with API Entry Event
-Substitute details for your configuration within all {{}} labels.
-Data Extension named 'Client_Auth_Details' with fields 'ClientID', 'PackageName', and 'ClientSecret'. Each field should contain corresponding values for the Installed Package.

    %%[ var @clientid,@clientsecret,@packagename 
Set @clientid = Lookup('Client_Auth_Details','ClientID','PackageName','{{Installed Package Name}}') 
Set @clientsecret = Lookup('Client_Auth_Details','ClientSecret','PackageName','{{Installed Package Name}}') ]%%


<script runat="server">
 Platform.Load("Core", "1.1.1");

    //Get client id and secret from ampscript variables
    // Static API authentication properties
    var clientId = Variable.GetValue("@clientid");
    var clientSecret = Variable.GetValue("@clientsecret");
    var grantType = "client_credentials";

    var eventDefinitionKey = "{{Event Definition Key}}"; // unique key for the API Event used as the entry source for the journey
    var subscriberKey = "Test123";
    var emailAddress = "test123@gmail.com";

    try 
    {
      var success = false;
      var accessToken = GetAccessTokenForAPI(clientId, clientSecret, grantType);
      if (accessToken != null) 
      {
        success = InjectSubscriberIntoAPIEventForJourney(subscriberKey, emailAddress, accessToken,eventDefinitionKey);
      }
      if (success) {
        Write("Subscriber injected into Journey");
      } else {
        Write("Failed to inject subscriber.");
      }
    } 
    catch (ex) 
    {
     Write("Exception Error: " + Stringify(ex));
 }

    function GetAccessTokenForAPI(clientId, clientSecret, grantType) 
    {
     var url = 'https://{{Tenant Specific Domain}}.auth.marketingcloudapis.com/v2/token';
        var contentType = 'application/json';
        var payload = 
        {
          client_id: clientId,
          client_secret: clientSecret,
          grant_type: grantType

        };

        var accessTokenRequest = HTTP.Post(url, contentType, Stringify(payload));
        if (accessTokenRequest.StatusCode == 200) { 
           var tokenResponse = Platform.Function.ParseJSON(accessTokenRequest.Response[0]);
           return tokenResponse.access_token;
        }
  else // Call failed, return nothing
        {
          return null;
          Write("Error");
        }

    }

    function InjectSubscriberIntoAPIEventForJourney(subscriberKey, emailAddress, accessToken,eventDefinitionKey)
    {
        var url = 'https://{{Tenant Specific Domain}}.rest.marketingcloudapis.com/interaction/v1/events';
       //Write("URL OK");
        var contentType = 'application/json';
      //Write("contenttype OK");
       var headername = ["Authorization"];
       //Write("contenttype OK" + headername);
       var headervalue = ["Bearer " + accessToken];
      //Write("contenttype OK" + headervalue);
       var payload =

           '{"ContactKey":"'+subscriberKey+'","EventDefinitionKey":"'+eventDefinitionKey+'","Data": {"SubscriberKey":"'+subscriberKey+'", "EmailAddress":"'+emailAddress+'"}}';
          /* {
            ContactKey: subscriberKey,
             EventDefinitionKey: eventDefinitionKey,
            EstablishContactKey: false, // this must be provided if you want to also supply Data below
             Data:
               { // You need to create a matching Data Extension for the API Event entry source
                 SubscriberKey: subscriberKey,
                  EmailAddress: emailAddress,
                }
              }*/
   //Write("payload OK" + payload);
          var eventRequest = HTTP.Post(url, contentType, payload,headername,headervalue);
      //Write("Call Successful");
          if (eventRequest.StatusCode == 201)// 201 is Created
          { 
             var requestResponse = Platform.Function.ParseJSON(eventRequest["Response"][0]);
               Write(Stringify(requestResponse)); // uncomment to see the returned object
              if (requestResponse.eventInstanceId != null && requestResponse.eventInstanceId != "") // eventInstanceId is a GUID 
              { 
                  // TODO: maybe we should check that it is actually a GUID and not some other string
                 return true; // we got a GUID the event has been fired
              }
          }
    return false; // the injection failed
}

  </script>
-4

For anyone else looking for some sample code for a solution here;

<script runat="server">
Platform.Load("Core", "1.1.1");

// Static API authentication properties
var clientId = "id";
var clientSecret = "secret";

// Static config
var EventDefinitionKey = "apiEvenKey"; // unique key for the API Event used as the entry source for the journey

// Change this
var subscriberKey = "key";
var emailAddress = "email@email.com";

try {

    var success = false;
    var accessToken = GetAccessTokenForAPI(clientId, clientSecret);
    if (accessToken != null) {
        success = InjectSubscriberIntoAPIEventForJourney(subscriberKey, emailAddress, accessToken);
    }

    if (success) {
        Write("Subscriber injected into Journey");
    } else {
        Write("Failed to inject subscriber.");
    }

} catch (ex) {
    Write("Exception Error: " + Stringify(ex));
}

// https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-programmatic-content.meta/mc-programmatic-content/ssjs_httpPost.htm
function GetAccessTokenForAPI(clientId, clientSecret) {
    var url = 'https://auth.exacttargetapis.com/v1/requestToken';
    var contentType = 'application/json';
    var payload = {
        clientId: clientId,
        clientSecret: clientSecret
    };

    var accessTokenRequest = HTTP.Post(url, contentType, Stringify(payload));
    if (accessTokenRequest.StatusCode == 200) { // 200 is successful
        var tokenResponse = Platform.Function.ParseJSON(accessTokenRequest.Response[0]);
        return tokenResponse.accessToken;
    }

    // Call failed, return nothing
    return null;
}

// https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-apis.meta/mc-apis/postEvent.htm
function InjectSubscriberIntoAPIEventForJourney(subscriberKey, emailAddress, accessToken) {
    var url = 'https://www.exacttargetapis.com/interaction/v1/events?access_token=' + accessToken;
    var contentType = 'application/json';
    var payload = {
        ContactKey: subscriberKey,
        EventDefinitionKey: EventDefinitionKey,
        EstablishContactKey: false, // this must be provided if you want to also supply Data below
        Data: { // You need to create a matching Data Extension for the API Event entry source
            SubscriberKey: subscriberKey,
            EmailAddress: emailAddress,
            InjectedAtCST: new Date() // you must provide a value for all DE columns, even if they have a default value
        }
    }

    var eventRequest = HTTP.Post(url, contentType, Stringify(payload));
    if (eventRequest.StatusCode == 201) { // 201 is Created
        var requestResponse = Platform.Function.ParseJSON(eventRequest.Response[0]);
        // Write(Stringify(requestResponse)); // uncomment to see the returned object
        if (requestResponse.eventInstanceId != null && requestResponse.eventInstanceId != "") { // eventInstanceId is a GUID 
            // TODO: maybe we should check that it is actually a GUID and not some other string
            return true; // we got a GUID the event has been fired
        }
    }
    return false; // the injection failed
}

</script>

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.