1

I am trying to set up a Journey where the DE is populated when someone replies to a SMS with specific keyword. I want the journey to be triggered each time someone is added to the data extension. I'm not sure how I would set up the entry source for this. Any ideas? Thank you!

  • The journey will be already running, perhaps what you want is to have the contact enter the journey as soon as it is added to the DE which is in the entry criteria of the journey. Please have a look at the recurring entry criteria here with processing only new records option help.salesforce.com/… – manjit5190 Jul 28 at 14:50
  • Hey @manjit5190, I understand it is already running but isn't the 3 options just run once, schedule and automation? I don't want it to be running on any schedule as I want them to enter as soon as the data extension is updated - which is whenever the contact responds to the SMS. – chrissyj13 Jul 28 at 14:53
  • there is not a feature of any JB entry source, you can evaluate using an API entry, a smart capture, of a salesforce entry event to inject when an action occurs – EazyE Jul 28 at 17:38
2

I have build exactly that scenario and I am happy to share how it has been accomplished.


Prerequisites

  • A journey as an API entry event. Copy the API key
  • An SMS response message expecting the reply
  • SFMC API server-to-server implementation

Flow

  1. Sending out the SMS and waiting for a response
  2. Retrieve a SMS response and validate the keyword
  3. If keyword match, fire the journey entry via API

SMS response setup

In your SMS response message you would need to look for the keyword/reply and fire of the journey. Let's assume we are having two possible replies such as YES or NO. When YES is replied, we want to fire the journey which will create a CRM case.

Notice:

SMS response messages allow the usage of AMP and SSJS. For the ease of maintaining your code, it is a good idea to use ContentBlocks to manage the code and load the code inside the SMS response message. If you are doing so, keep in mind that the SMS response message will fail if there is any form of output outside the message itself. Output() or Write() inside the ContentBlock will fail the message


Code for the SMS response message:

%%[
    /* The valid replies */
    SET @validReplies = 'YES|NO'

    /* the keyword you used for the response */
    SET @keyword = 'MYKEYWORD'

    /* Load the content */
    ContentBlockByKey('ContentBlockExternalKey')
]%%    
%%=v(@msg)=%%

Code of the ContentBlock for the SMS response:

%%[ 
    /* Fetch the user reply */
    SET @reply = [MSG(0).NOUN(0)]

    /* Check if reply is allowed (set in the message itself) */
    IF IndexOf(@validReplies,@reply) > 0 THEN

        /* ======================== REPLY ======================== */
        IF @reply == 'YES' THEN
            /* Load the journey fire event from an external content block */
            Output(ContentBlockByKey('ExternalKeyForYourJourneyFireCode'))
            SET @msg = 'Thank you, a customer service agent will contact you shortly.'
            
        ELSEIF @reply == 'NO' THEN
            SET @msg = 'Thank you!'

        ENDIF

    /* The given reply is not allowed */
    ELSE 
        /* Build the response such as "Please reply only with MYKEYWORD YES or MYKEYWORD NO" */
        SET @validReply = BuildRowsetFromString(@validReplies,'|')
        SET @msg = 'Please reply only with '
        FOR @i = 1 to RowCount(@validReply) DO
            SET @msg = Concat(@msg, UpperCase(@keyword),' ',Field(Row(@validReply, @i),1))
            IF @i < RowCount(@validReply) THEN
                SET @msg = Concat(@msg, ' or ')
            ELSE 
                SET @msg = Concat(@msg, '.')
            ENDIF
        NEXT @i
    ENDIF
]%%

Code for the Journey ContentBlock:

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

    // API credentials
    var setup = {
                authBaseURI         : "https://xxxxxxxxxxxxxxxxxx.auth.marketingcloudapis.com/",
                restBaseURI         : "https://xxxxxxxxxxxxxxxxxx.rest.marketingcloudapis.com/",
                soapBaseURI         : "https://xxxxxxxxxxxxxxxxxx.soap.marketingcloudapis.com/",
                clientId            : "xxxxxxxxxxxxxxxxxx",
                clientSecret        : "xxxxxxxxxxxxxxxxxx"
            };

    // YOUR API EVENT KEY
    var apiKey = 'APIEvent-xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx';

    // DATA YOU WANT TO PASS TO THE JOURNEY
    var data = {
        'Reply ': Variable.GetValue("@reply"),
        'SubscriberKey': Variable.GetValue("@SubscriberKey")
    };

    // TRIGGER THE JOURNEY
    triggerJourneyEvent(data.SubscriberKey,apiKey,data);


// *********************** FUNCTIONS *********************** //

    // FUNCTION TO GET A TOKEN
    function getToken() {

        // set data for the API call
        var config = {
            url : setup.authBaseURI + "v2/token",
            contentType : "application/json",
            payload : {
                "client_id": setup.clientId,
                "client_secret": setup.clientSecret,
                "grant_type": "client_credentials"
            }
        };
        
        // generate new token
        var req = httpRequest('POST', config.url, config.contentType, config.payload);

        if (req.status == 200) {
            return token;
        } else {
            return null;
        }
    }

    // FIRE OF AN HTTP REQUEST
    function httpRequest(method,url,contentType,payload,header) {
        var req = new Script.Util.HttpRequest(url);
        req.emptyContentHandling = 0;
        req.retries = 2;
        req.continueOnError = true;
        req.method = method;
        for( var k in header ) {
            req.setHeader(k, header[k]);
        }
        if(typeof contentType !== 'undefined' && contentType !== null) { req.contentType = contentType; }
        if(typeof payload !== 'undefined' && payload !== null) { req.postData = Stringify(payload); }

        try {
            var res = req.send();
            return {
                status: Platform.Function.ParseJSON(String(res.statusCode)),
                content: Platform.Function.ParseJSON(String(res.content))
            };

        } catch(e) {
            return {
                status: '500',
                content: e
            };
        }
    }


    // FIRE THE JOURNEY
    function triggerJourneyEvent(contactKey,eventDefinitionKey,data) {
        var token = getToken(),
            config = {
                url: setup.restBaseURI + "interaction/v1/events",
                contentType: "application/json",
                header: {
                    Authorization: "Bearer " + token
                },
                payload : {
                    ContactKey: contactKey,
                    EventDefinitionKey: eventDefinitionKey,
                    Data: data
                }
            };

        var req = httpRequest('POST',config.url, config.contentType, config.payload, config.header);

        if (req.status == 201) {
            if (req.content.eventInstanceId != null && req.content.eventInstanceId != "") {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

</script>

This will allow you to fire of a Journey form a SMS response.

Keep in mind, the best practice is to re-use the API token for its duration and not generate a new one every time. I have achieved that by saving the token in a DataExtension but removed it from this example.

These code snippets are part of my library I have written which also has the token logic to save it in a DataExtension. You can find the library here.

| improve this answer | |
  • This is great! Thanks so much, very keen to try this. – chrissyj13 Jul 29 at 6:48

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.