a.k.a. “that guy” from the Marketo Community
who also blogs at https://blog.teknkl.com
and has created some Marketo apps
such as FlowBoost.
= What your software talks to instead of talking directly to the Marketo platform
How can you tell when an integration salesperson is lying?
They just said, "We have a native connector"
* “Program to the Interface, not the Implementation”
The CLIENT APIs
Munchkin API
Forms JS API
The IN-FLOW APIs
Webhook API
Velocity API
The BULK (AND BULK-ISH) APIs
Bulk Lead/Activity Extract
Bulk Lead/Activity Export
Bulk Lead Import
The MARKETING APIs
Campaign Request/Schedule
Program/List Membership
The OBJECT APIs
Lead CRUD and Push
Marketo Custom Object/Activity
Marketo Oppty/Company/Sales
The ASSET APIs
Static Files API
Email/LP Template APIs
Email/LP/Form APIs
A USER INTERFACE API
Customize menus, buttons, et al.
Branded flow options: FlowBoost It! instead of Call Webhook
A FORMS PREPROCESSOR API
Manage data between browser and database
YOUR HOPES AND DREAMS
Anything else you thought already worked
A CAMPAIGN UPDATE API
Reorder, create, delete SC steps
A REPORTING API
Execute and download UI-defined reports
A PARTNER-ONLY API
What's {{Member.Webinar URL}}???
Run at campaign execution and/or email assembly; moderate scale
Run in web browsers, designed for massive scale
Awesome if actually used in bulk; terrible if used singly
Use conservatively given business needs, bulkify madly
If flushed too often, don't scale, otherwise OK
Upsert Lead (/lead.json) and Push Lead (/push.json) are endpoints within the REST Lead API.
*or can it...?
Vastly more scalable than server APIs
Designed to respond to individual public and/or anonymous activities
<button type="button">Button</button>
<button type="submit">Button</button>
<a href="#">Button</a>
<a href="https://example.com/getMy.pdf">Button</a>
<button class="mchReDecorate" type="button">Button</button>
<script>
Array.from(document.querySelectorAll(".mchReDecorate"))
.forEach(function(decoratable){
decoratable.addEventListener("click", function(e){
Munchkin.munchkinFunction("clickLink", {
href : this.form.action ||
this.getAttribute("data-href") ||
this.href
});
});
});
);
</script>
form.onSuccess(function(vals, tyURL){
tracker.send("my ROI pixel");
document.location.href = tyURL;
});
Replaces broken integrations
the thing that gets called (remote service)?
the thing that calls (http client w/payload)?
the ACT of calling?
plus some great open-source Apache libraries
* OK, all of Java 6
#set( $inTimeZone = $date.getTimeZone().getTimeZone('America/New_York') )
#set( $outTimeZone = $date.getTimeZone().getTimeZone('America/New_York') )
#set( $locale = $date.getLocale() )
#set( $String = $context.getClass().forName("java.lang.String") )
#set( $LocaleFrom2Part = $locale.getClass().getConstructor($String,$String))
#set( $locales = {
"en_US" : $LocaleFrom2Part.newInstance("en","US"),
"fr_FR" : $LocaleFrom2Part.newInstance("fr","FR"),
"es_ES" : $LocaleFrom2Part.newInstance("es","ES"),
"pt_PT" : $LocaleFrom2Part.newInstance("pt","PT")
})
#set( $myDate = $convert.parseDate($lead.Member_Expire_Date,'yyyy-MM-dd',$locale,$inTimeZone) )
${date.format("d MMMM, yyyy",$myDate,$locales.en_US,$outTimeZone)}
${date.format("d MMMM yyyy",$myDate,$locales.fr_FR,$outTimeZone)}
${date.format("d 'de' MMMM 'de' yyyy",$myDate,$locales.es_ES,$outTimeZone)}
${date.format("d 'de' MMMM 'de' yyyy",$myDate,$locales.pt_PT,$outTimeZone)}
English output: March 31, 2018
French output: 31 mars 2018
Spanish output: 31 de marzo de 2018
Portuguese output: 31 de março de 2018
#set( $secretKeySpec = $EncryptionTool.getKeySpec.newInstance(
$PreferenceCenterAESSecret.toString().trim().getBytes("ascii"),
"AES")
)
#set( $cipher = $javax.crypto.Cipher.getInstance("AES/ECB/PKCS5Padding") )
#set( $tmp = $cipher.init( $field.in($javax.crypto.Cipher).ENCRYPT_MODE, $secretKeySpec ) )
#set( $encrypted = $cipher.doFinal($PreferenceCenterPayload.toString().getBytes("utf8")) )
#set( $Base64Encoded = $EncodingTool.Base64.encoder.encodeBuffer( $encrypted ) )
#set( $Base64EncodedURLSafe = $Base64Encoded.replace(
$EncodingTool.Base64.ENCODED_CHAR_62.STANDARD,
$EncodingTool.Base64.ENCODED_CHAR_62.URLSAFE
).replace(
$EncodingTool.Base64.ENCODED_CHAR_63.STANDARD,
$EncodingTool.Base64.ENCODED_CHAR_63.URLSAFE
)
)
<a href="${PreferenceCenterBaseURL.toString().trim()}?lead=${Base64EncodedURLSafe}">${PreferenceCenterLinkText.toString().trim()}</a>
<a href="https://xerox.my.preferencecenter.co.uk?lead=uk_H5W_tuqQymuK7Rig-s16sxLYyqdIlOA_4zW-P9q0-8GoiuHK1R-oxaQAcwNnkfM7E_2uNl...">Manage Your Preferences Ultra-Securely</a>
... what does all that make you think of?
Meter all the things!
get (stored REST API access_token)
then
check (seconds until token expires)
if (token expired)
send (REST API client_id, REST API client_secret)
to (Marketo REST Identity endpoint)
and get (new REST API access_token)
then
send (new REST API access_token, request parameters)
to (Marketo REST Get Leads endpoint)
and get (lead info)
else
send (stored REST API access_token, request parameters)
to (Marketo REST Get Leads endpoint)
and get (lead info)
get (stored REST API access_token)
then
check (seconds until token expires)
if (token expired)
send (REST API client_id, REST API client_secret)
to (Marketo REST Identity endpoint)
and get (new REST API access_token)
then
send (new REST API access_token, request parameters)
to (Marketo REST Get Leads endpoint)
and get (lead info)
else
send (stored REST API access_token, request parameters)
to (Marketo REST Get Leads endpoint)
and get (lead info)
then
if (error) with error code (601:access_token expired)
then
send (REST API client_id, REST API client_secret)
to (Marketo REST Identity endpoint)
and get (new REST API access_token)
then
send (new REST API access_token, request parameters)
to (Marketo REST Get Leads endpoint)
and get (lead info)
Theory:
Practice: