Self Service flow steps (SSFS) are a powerful way to integrate with third party applications and to build custom workflows that can't be achieved in Marketo alone. This blog post will give you a Replit repository that you can clone to get started and it will walk you through the code in the repository so that you can make it your own and bring SSFS into your Marketo instance.
Ok so we all know what a SSFS looks like inside of Marketo but what happens when the SSFS is executed in a smart campaign flow and the data is sent outside of Marketo? There is a server set up to catch all this information, process it, and then send the information back to Marketo to update the lead record.
Don't be intimidated by the word "server", this is just somewhere we have hosted our SSFS code so that it is constantly listening out for information sent from Marketo, ready to process it and send it back. This hosted code for the SSFS can be referred to as a "service".
I have seen a lot of documentation and posts about what a SSFS looks like inside of Marketo but I haven't yet seen anyone show what this looks like on a server. That's why I'm here to show you what's under the hood so that once I'm finished you can take the wheel and drive your Lambo off into the sunset!
I recommend checking out the YouTube video below where I can go into much more detail than here in the blog. The aim of this blog and the associated walkthrough video is to:
Josh Arrington does a great job at highlighting the advantages of using SSFS over Webhooks. Since the purpose of my blog is to walk through the technical build out of self service flow steps I will just summarize the advantages that Josh mentions:
I really like using Replit to host my code because it is relatively cheap and it makes it easy to deploy your code to production and handle scaling your capacity to handle increased volume from Marketo. To see how easy it is to work in Replit and deploy your service check out the video above.
At the moment the Replit Core package that allows you to deploy your service and make your service private costs $20 per month. Then all the computation your service uses when your code executes is billed monthly.
To give you an idea of how much usage will cost, it cost my company less than $1 to run 2 SSFS for 2 weeks so Replit is a cost effective solution for hosting your SSFS service.
When I first opened up the self service flow step Github repo provided by Marketo and started scrolling through the ReadMe file, I didn't have the slightest clue about where to begin. I figured that I would need to host code externally which Marketo could interact with but after this I was lost.
In stepped my buddy ChatGPT. I used the O3 reasoning model and pasted in the link to the Github repo and explained that I wanted to build a service in Replit to host a Marketo SSFS. Then after much back and forth with ChatGPT and lots of experimenting and testing in my Marketo instance I finally was able to build a Replit repository to support multiple SSFS.
Now I want to save you all the blood, sweat, and tears that I had to endure by sharing a Replit template that you should be able to clone as a starting point.
I personally found the ReadMe file to be hard to navigate easily since it is missing hierarchy so I copied all this information to a Google doc to make it easier to navigate. So if you feel the same way then feel free to use this doc.
The Replit template contains code for the 3 self service flow steps described below.
This self service flow step allows a user to call the OpenAI chat endpoint. All that is needed to get this SSFS working for your instance is to put your OpenAI API key into the secrets in Replit. You can follow this link to get an API key.
SSFS to create a GPT chat
This self service flow step using the Telnyx SMS API to send an SMS message.
SSFS to send an SMS
This self service flow step allows you to compute Excel formulas using the formulas Python library. If you want to see all the functions that are available then you can check out the docs here.
SSFS to calculate an Excel formula
Josh Arrington and I have collected our notes on the bugs we have noticed with SSFS and Josh has also put together a wishlist of features he would like to see. So when you are testing out the SSFS provided in the template and things are not working as expected give this document a look first because these could be bugs of SSFS overall and have nothing to do with the code in Replit.
Replit code repository
The structure of the Replit template consists of:
Admin > Service Providers
section or in the flow of a smart campaign when configuring the SSFS.
Since this blog post will be long enough already I will show in a future post how to get the "inbound-footing" file and how to set up the Google API in the Google Admin console. If you want to figure this out now then you can ask ChatGPT, this is how I found out 😉
Before diving into the /submitAsyncAction
endpoint below I wanted to share an example of the information Marketo sends to your code.
/submitAsyncAction
code to send information back to Marketo.
The request below is what it looks like when a single lead is sent by Marketo. If you want to see what the payloads look like for multiple leads and for each of the 3 SSFS in the template then you can check out this sheet.
{
"token": "xxx",
"apiCallBackKey": "123abc",
"campaignId": 42504,
"callbackUrl": "https://mkto-cfa.adobe.io/customflowaction/submitCustomFlowAction",
"context": {"admin": {}},
"objectData": [
{
"objectType": "lead",
"objectContext": {"email": "tyron@theworkflowpro.com", "sms_subscription": "true", "id": 7315607},
"flowStepContext": {"to_phone": "+17126258027", "from_phone": "+18005713186", "message": "Hello World"}
}
]
}
/serviceIcon
endpoint is where you reference the image you want to appear in the Admin console and in smart campaigns for this SSFS./brandIcon
endpoint is where you set the brand icon for the SSFS which will only be visible in the "Admin > Service Provider" section./status
endpoint is pinged by Marketo daily to check that the service is still active./install
endpoint points Marketo to the "swagger.json" file when you are installing the service in the Admin section in Marketo./getPicklist
endpoint is optional and only needed if your SSFS will have picklist values offered (see the calcFormula
"routes.py" file for an example). This endpoint:
Brand and Service icons in the Admin section
This is the where the magic happens in your SSFS service. Whenever a SSFS is called from within Marketo, Marketo will send the lead and flow step information to this endpoint where code will then:
The callback object consists of two parts:
leadData
part which is where you include all the fields that you want the SSFS to update (the "id" field is always included so Marketo knows which lead to update).activityData
part which contains all the attributes you want to be listed in the activity detail for the SSFS when viewed in a person's activity log.
callback_objects.append({
"leadData": {
"id": lead_id,
"quality_score": q_score,
"quality_score_detail": q_detail
},
"activityData": {
"company_employee_number": emp_num,
"company_industry": industry,
"person_job_title": job_title
"quality_score": q_score,
"quality_score_detail": q_detail,
"success": True
}
})
This endpoint contains all the information Marketo needs to know to configure the SSFS upon install.
This section defines the:
Within the Invocation Payload Definition there are 3 things that need to be defined:
flowAttributes
parameter.fields
parameter.userDrivenMapping
parameter which can either be True or False. I will explain the implications of this setting in more detail below.
As mentioned in the docs it is possible to send program, my token, subscription, trigger, campaign, and programMember token context along with Global attributes in the Invocation payload.
If userDrivenMapping
is set to False then when you install the flow step the "Map Outgoing Fields" section will be populated with all the fields you listed in the fields
parameter and then the admin must activate the fields they wish to send and match these fields to the corresponding Marketo fields.
Then in your code when you want to retrieve these field values from the objectContext
you will use the "External Field" names shown in the screenshot below (versus the Marketo field API names when userDrivenMapping
is set to True).
title = context.get("person_job_title", "")
If userDrivenMapping
is set to False and your fields
parameter is empty then the "Map Outgoing Fields" section will be skipped during install.
userDrivenMapping set to False
If userDrivenMapping
is set to True then even if you have populated the fields
parameter it will be ignored. Instead during install the admin will get to choose all the fields that will be sent every time the SSFS is called.
Then in your code when you want to retrieve these field values from the objectContext
you will use the Marketo field API names.
phone = context.get("Form_Phone__c", "")
userDrivenMapping set to True
Within the Callback Payload Definition there are 3 things that need to be defined:
fields
parameter.attributes
parameter. Note that if you specify the fields in the callback object as shown above but you don't define them here then they won't show up in activity detail.userDrivenMapping
parameter which can either be True or False. I will explain the implications of this setting in more detail below.
Note that you do not need to (and won't be able to) declare the Primary attribute in the attributes
parameter in order for it to show up in the activity log.
If userDrivenMapping
is set to False then when you install the flow step the "Map Incoming Fields" section will be populated with all the fields you listed in the fields
parameter and then the admin must activate and map the fields that they want the SSFS to be able to update.
Then in order to actually update these fields with the SSFS you must include them in the leadData
section of the callback object and use the "External Field" names shown in the screenshot below.
callback_objects.append({
"leadData": {
"id": lead_id,
"quality_score": q_score,
"quality_score_detail": q_detail
},
userDrivenMapping set to False
If userDrivenMapping
is set to True then even if you have populated the fields
parameter it will be ignored. Instead during install the admin will get to choose all the fields that they the SSFS to be able to update.
Then in order to actually update these fields with the SSFS you must include them in the leadData
section of the callback object and use the Marketo API field names.
callback_objects.append({
"leadData": {
"id": lead_id,
"AE_SDR_Notes__c": ai_summary
},
userDrivenMapping set to True
If you are already comfortable with programming and APIs then you should check out these 2 blogs which show you how to get started with the Marketo API and link out to other blogs showing plenty of useful use cases for revenue operations.
Here are some answers to frequently asked questions. If you have any more then please get in touch!
Trigger Campaigns, Batch Campaigns, and Executable Campaigns are all able to call self service flow steps.
Yes, SSFS behave similar to Executable campaigns in this sense that the flow of the smart campaign will wait for the SSFS to complete before continuing on to carry out the subsequent flow step actions.
If the SSFS is used in the flow of a trigger campaign then it will only send the single lead that triggered the campaign to your service. If the SSFS is used in the flow of a batch campaign then it will send multiple leads in the batches it sends to your service.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.