mkto-manager v0.1.8
BETA - Use at your own risk
I am still working out the final method corrections and improved error handling, I do not consider this ready for production use. However, PRs are welcome if you would like to help develop this package or have opinions on how to improve the infrastructure.
TODOs
- Implement Database, Lead, & Activities Handler classes
- Implement User Management classes
- Implement IoC Container
- Improve
BaseAsset
validation with Yup - Improve
MktoResponse
validation with Yup - Review
MktoRequest
retry method requirement - Implement Event Emitter on
MktoBase.find()
(for database hooks) - Develop Event Emitting
MktoBase.stream()
method to replace BulkProcess Implement Event Emitter on- DeprecatedMktoRequest
(for database hooks)Implement Event Emitter on BulkProcess instead of synchronous callback system- DeprecatedCleanup BulkProcess logging- Deprecated- Develop tests and stubs for API
MktoManager
Dedicated Node library for scripting automated changes and reports for Marketo instances. Emphasis on Asset (Email, Landing Page, Form, File, Folder, etc) interactions, as well as Lead record and User record management. Attempts to standardize and compensate for Marketo's inconsistent API structures.
Read more on the Marketo REST API Here: Marketo REST Api Docs
Usage
Installation
$ npm i --save mkto-manager
Create your Manager Object
// Retrieve the mkto-manager factory
const makeManager = require("mkto-manager");
// Define your REST API Credentials
const marketoRestCredentials = {
mktoBaseUrl: "https://<Marketo Instance ID>.mktorest.com",
mktoClientId: "marketo-client-id-guid-here",
mktoClientSecret: "marketoClientSecretHashHere",
};
// Instantiate your MktoManager instance
const mktoManager = new makeManager(marketoRestCredentails);
Assets
The primary focus of this library is for Asset management. Some Asset handlers are still in progress.
mktoManager.assets.Channel
mktoManager.assets.Email
mktoManager.assets.EmailTemplate
mktoManager.assets.File
mktoManager.assets.Folder
mktoManager.assets.Form
mktoManager.assets.LandingPage
mktoManager.assets.LandingPageRedirect
mktoManager.assets.LandingPageTemplate
mktoManager.assets.Program
mktoManager.assets.Segment
mktoManager.assets.SmartCampaign
mktoManager.assets.SmartList
mktoManager.assets.Tag
Querying the API for an Asset record using .find()
Each Asset Handler class contains a static async find()
method for retrieving records from the Marketo API.
The .find()
method will define and amend the Endpoint URI as needed depending on the Asset Handler class and the search parameters you pass to it.
Examples:
// Find Landing Page by ID
mktoManager.assets.LandingPage.find({ id: 1234 });
// Find Landing Page by Name
mktoManager.assets.LandingPage.find({ name: "My Cool Landing Page" });
// Find Landing Pages by Parent Folder
mktoManager.assets.LandingPage.find({
folder: {
id: 123, // Folder ID
type: "Folder", // ["Program", "Folder"]
},
});
// Get multiple Programs
mktoManager.assets.Program.find({
offset: 0, // Offset value, like a paging token (sort of)
maxReturn: 200, // Defaults to 20 per the API Docs, maximum 200
});
Query Responses
All .find()
method responses will return an instance of MktoResponse. MktoResponse
acts as a wrapper around the real Marketo Response.
The MktoResponse
will have a single property for determining the success of the request, as well as helper methods for accessing the results.
mktoManager.assets.LandingPage
// Retrieve Landing Page by ID
.find({ id: 1234 })
// Utilize the Marketo Response
.then(function (mktoResponse) {
// Check if the API Response was successful
if (mktoResponse.success === true) {
// Get the first result - still needed if you only expect 1 result
const firstLandingPageResult = mktoResponse.getFirst();
// firstLandingPageResult is an instantiated instance of the LandingPage Handler
// Get all results as an array of instantiated instances of the Handler
const allLandingPageResults = mktoResponse.getAll();
} else {
// Capture Mkto API Warnings or Errors
const mktoWarnings = mktoResponse.warnings;
const mktoErrors = mktoResponse.errors;
}
});
Find Request Events
You can attach listeners for various steps within the .find()
request.
Pre-Request - Emitted just before the HTTP Request
mktoManager.assets.LandingPage.on("find_request", requestConfig => {
// requestConfig = {
// url: <URI String>,
// method: 'get',
// params: <Search Params Object>,
// }
});
Find Response - Emitted upon successful response
mktoManager.assets.LandingPage.on("find_response", mktoResponse => {
// Returns the instance of mktoResponse that is also returned by the method.
});
Find Error - Emitted upon a failed HTTP Response
mktoManager.assets.LandingPage.on("find_error", AxiosError => {
// Returns the AxiosError object from Axios
});
Note: Attaching listeners to mktoManager.assets.LandingPage
using the on()
method will trigger the event listener for all subsequent find methods. Use once()
or off()
to manage your event listeners on Asset Handlers.
Read more on the component/emitter
package here.
Streaming Asset Records using stream()
Due to Marketo's constraint of a maximum of 200 Asset records returned per find()
request, we also have included a static method for creating an API Record stream to easily iterate over all API records that are qualified by your find()
search parameters passed the 200 return limit.
NOTE: The stream method offered on all Asset Handler classes is intended to replace the original
BulkProcess
helper class, which will be deprecated.
stream()
is used similar to find()
, but must be synchronously composed, and then asynchronously run.
stream()
will return a single array of all retrieved records instantiated as instances of the Asset Handler class.
// Retrieve ALL Landing Pages that fit our search criteria without the maxReturn bounds
// Construct our stream handler that we can attach event listeners to and execute on-demand
const streamHandler = mktoManager.assets.LandingPage.stream({
// Search Conditions
status: "approved",
// Return modifiers
offset: 0, // Defaults to 0 to start, and is auto-incremented within the stream method()
// Use a custom offset if you prefer to skip the initial records
maxReturn: 200, // Defaults to the maximum 200.
// Reduce this maxReturn to reduce the number of results returned in the emitted "request_success" event
// This can be used to manage the size of your looping logic per "request_success" event
});
// Stream will bubble the internal `find()` requests "find_request" event carrying the request config object
streamHandler.on("find_request", requestConfig => {
// requestConfig = {
// url: <URI String>,
// method: 'get',
// params: <Search Params Object>,
// }
});
// Each iterative `find()` request will emit a "request_success" event that carries the mktoResponse from `find()`
streamHandler.on("success", mktoResponse => {
// We can safely assume this event was triggered when this
// `mktoResponse` instance was successful - `mktoResponse.success === true`
// Iterate over the results and do whatever you need
mktoResponse.getAll().forEach(landingPageAsset => {
// Your code here...
});
});
// We also have emitted events for issues with the HTTP Request
streamHandler.on("request_http_error", mktoResponse => {
// mktoResponse.status !== 200
});
// And issues with the Marketo Request
streamHandler.on("request_mkto_error", mktoResponse => {
// mktoResponse.success === false
});
// Finally, we have an emitted event when the stream is finished
streamHandler.on("finished", streamHandlerInstance => {
// Returns the copy of the streamHandler.
// All retrieved data can be accessed via streamHandlerInstance.data
// streamHandlerInstance.data = [
// <LandingPage>,
// <LandingPage>,
// <LandingPage>,
// <LandingPage>,
// <LandingPage>,
// <LandingPage>,
// <LandingPage>
// ]
});
// After attaching all of your event listeners, you can execute the async stream
streamHandler.run().then(streamHandlerData => {
// The async `run()` method will also return the streamHandlerInstance.data property
// so you can use it from the resulting `finished` event or await the results here.
// However - it is recommended you operate on the emitted `success` event and individual mktoResponse record collections
});
Asset Management
Each Asset instance shares many properties and methods.
Data Management
Access the Record ID value using the computed .id
property. This is mapped to retrieve the ID from the property where it is stored.
Manage the Asset data using the .set()
and .get()
methods.
const landingPageName = myLandingPageAsset.get("name");
// landingPageName = "My Cool Landing Page"
// Set a new Landing Page Name
myLandingPageAsset.set("name", "My Cooler Landing Page");
This updates the local data property, but has not triggered the update to the API.
Check if data has been changed
By using a data caching system, we preserve a non-mutated copy of the data.
.isChanged
is a computed boolean that will define if the data has been changed.
This allows us to quickly check if the data has been mutated, and if we need to send the updated data to the Marketo API.
You can also review what data has been mutated by using the changedData
computed property.
This will return an object of just the properties that have been altered.
Advanced
Library
All Marketo API logic is contained within lib/
.
lib/index.js
will read the lib/assets/
directory and load all Asset Handlers into the module export. This include BaseAsset
, which all other Asset Handlers are based on. Usage, User, and ~Lead~ Handler library information is also consumed here.
:warning: All HTTP request methods are asynchronous and return Promises.
Core Functions
MktoRequest
The MktoRequest
class is a Marketo specific Axios/RateLimit/ApiConsumer wrapper that instantiates our Axios HTTP instance with necessary details to communicate with our Marketo API. MktoRequest
accepts the necessary API credentials as parameters, and returns an object with initial methods.
Uses axios-rate-limit
to set a default Rate Per Second to try and remain compliant with Marketo's 100 calls per 20 seconds and Maximum of 10 concurrent API calls.
Default Rate Limit: {maxRPS: 4}
.
This default rate limit is set to meet the exact rate limit criteria that Marketo defines:
Daily Quota: Subscriptions are allocated 50,000 API calls per day (which resets daily at 12:00AM CST). You can increase your daily quota through your account manager.
Rate Limit: API access per instance limited to 100 calls per 20 seconds.
Concurrency Limit: Maximum of 10 concurrent API calls.
However, Marketo still complains if you run updates at the maximum Rate/Concurrency Limit :)
You will not need to use
MktoRequest
directly.
MktoResponse
MktoResponse
wraps API responses in an interactive Collection-type object. MktoResponse
validates HTTP and API responses and offers result-array getter methods that return instantiated instances of each Asset's corresponding Handler.
// Get all Landing Page's in a specific Folder
mktoManager.assets.LandingPage.find({
folder: {
id: 123, // Folder or Program ID
type: "Folder", // ["Program", "Folder"]
},
}).then(function (mktoResponse) {
// Check if the API Response was successful
if (mktoResponse.success === true) {
// Get the first result - still needed if you only expect 1 result
const firstLandingPageResult = mktoResponse.getFirst();
// firstLandingPageResult is an instantiated instance of the LandingPage Handler
// Get all results as an array of instantiated instances of the Handler
const allLandingPageResults = mktoResponse.getAll();
} else {
// Capture Mkto API Warnings or Errors
const mktoWarnings = mktoResponse.warnings;
const mktoErrors = mktoResponse.errors;
}
});
MktoResponse Properties
Property | Description |
---|---|
_res | Full Axios Response Object - minus the Axios data property. |
_resultClass | Stores the Handler instance if one was passed. |
_data | Raw Axios data property. |
--- | --- |
status | HTTP Status Code as returned by Axios. |
success | Handler specific logic for True/False success. Successful responses can still return Zero results. |
result | Raw Marketo 'result' data, usually an array of records. |
warnings | Array of Marketo Warnings - will return empty array if no warnings. |
errors | Array of Marketo Errors - will return empty array if no errors. |
data | Handler specific - either an Array of results Instantiated as Handler instances, or a single Instantiated Handler object. |
A summary
prop is also available that offers a quick summary of Axios Request and Response / Mkto API Response information - great for quickly visualizing a summary of the response when developing.
mktoResponse.summary = {
// Request
header: this._res.request._header,
requestURL: this._res.config.url,
method: this._res.config.method,
params: this._res.config.params,
// Response
status: this._res.status,
success: this.success,
result: this.result,
errors: this.errors,
warnings: this.warnings,
};
Full mktoResponse
Example Print
/*
mktoResponse = {
status: 200, // HTTP Status Code
success: true, // API Response Success
// Array of raw results
result: [
{ id: 1, name: 'My Landing Page' ....}
....
],
// `result` Array as Instantiated Handler instances
data: [
<Instantiated Handler Result>,
<Instantiated Handler Result>,
....
],
// Response Warnings and Errors
warnings: [
// Array of Marketo Warnings, if they were sent
// Defaults to empty array
],
errors: [
// Array of Marketo Errors, if they were sent
// Defaults to empty array
],
summary: {
// Request
header: this._res.request._header,
requestURL: this._res.config.url,
method: this._res.config.method,
params: this._res.config.params,
// Response
status: this._res.status,
success: this.success,
result: this.result,
errors: this.errors,
warnings: this.warnings,
}
// Original Marketo Response Data
_data: {
success: true,
requestId: '#asdasdasd',
result: [
{ id: 1, name: 'Toaster' ....} <Raw Asset Results>
....
],
}
// Reference to the Handler Instance
_resultClass: <Asset Class reference>,
// Raw Axios Response
_res: <Raw Axios Response>
}
*/
NOTE: MktoResponse is extended for some of the "special" Marketo endpoints, like User Management. More details below in the User section.
BaseAsset
BaseAsset is a factory function that creates a starting point for all Asset API "Handlers", including the instantiation of our shared instance of MktoRequest
. API Credentials are passed to the exported factory function. Each Asset Handler Instance shares this MktoRequest instance for REST API communication.
Create Asset
To create a net-new Asset, you can instantiate an instance of the Asset Handler, and then call the create()
method.
const myNewLandingPageData = {
name: "My First Landing Page", // Page Name, required
description: "", // Page Description, optional
template: 9, // Template ID, required
folder: {
// Folder Object, required
type: "Folder",
id: 11,
},
};
const myNewLandingPage = new mktoManager.assets.LandingPage(myNewLandingPageData);
// Send the Create request for our new Landing Page
const createMktoResponse = await myNewLandingPage.create();
if (createMktoResponse.success === true) {
// The Response Object should now contain a newly instantiated Landing Page with the data from the API, including the new ID
// Get the first (and only) result
const myLandingPage = createMktoResponse.getFirst();
}
You can now use this instantiated instance to set your Landing Page content!
Update Asset
Each extended Class defines an Active Record type approach to API record management.
For example: A retrieved Landing Page record will store it's record data (only metadata per the API) in the data
property.
Record properties are retrieved and set via the corresponding methods:
Method/Property | Description |
---|---|
Asset.data | Object with all Asset or User record data. |
Asset._data | Object with all Asset or User record data - we store this object to compare changes to the data property. |
Asset.get(propertyName) | Retrieves the given Property from the Asset.data object. |
Asset.set(propertyName, newValue) | Sets the given Property in the Asset.data object to newValue . |
Asset.isChanged | Computed boolean for depicting if any data property has been altered from it's original API data. |
Asset.changedData | Computed object that will always list the data properties that have been altered from what was last retrieved from the API (the _data property). |
Here is an example of retrieving a record from the API, and updating one of it's properties:
// Find Landing Page by ID
const specialPageSearchResponse = await mktoManager.assets.LandingPage.find({
id: 1234,
});
// Local reference to our first (and only) Landing Page Result
const mySpecialLandingPage = specialPageSearchResponse.getFirst();
// Check the Landing Page Name property
if (mySpecialLandingPage.get("name") === "My Special LandingPage") {
// Update the Landing Page Name property
mySpecialLandingPage.set("name", "My Super Special Landing Page");
}
At this point, the instance of mySpecialLandingPage
has one of it's properties changed, but the update()
call has not been made to the API.
You can check if a record instance has pending updated property data with the computed properties:
// Check if the record has pending local changes (Not submitted to the API)
if (mySpecialLandingPage.isChanged) {
// Is true because we changed the `name` property
// Get the properties that have been changed locally
console.log(mySpecialLandingPage.changedData);
// Prints:
// {
// name: "My Special Updated Landing Page"
// }
}
Now that we have updated the local instance of the API Record, we can make the update()
call to POST the updated data back to Marketo:
const updateMktoResponse = await mySpecialLandingPage.update();
// This returns a new instance of `MktoResponse` - you check for API success the same way as we did before.
if (updateMktoResponse.success === true) {
// Successful update of the Landing Page name property!
// If the `update()` response was successful,
// the record self updates the `_data` property,
// so it no longer is "changed"
// mySpecialLandingPage.isChanged === false
}
The original record self updates its property tracking to acknowledge the update()
success, meaning isChanged
will now be false
.
I recommend you use the original
mySpecialLandingPage
instance -updateMktoResponse.getFirst()
may not be a fully instantiated instance of LandingPage Asset because Marketo only returns minimal information from theupdate()
call.
Mixins
To standardize and consolidate certain record type logic, shared functionality (props and methods) are written in Mixin objects and assigned to Class definitions where required.
Examples: Clone, Delete, Content, and Variables methods and property handlers.
Variables
// Retrieve the current Asset's approved Node variables
Asset.getVariables({
status: 'approved' // Optional, ['approved', 'draft']
}).then(getVariablesMktoResponse => ...)
Asset.updateVariables(variableId, newValue).then(updateVariableMktoResponse => ...)
Content
// Retrieve the current Asset's approved Node content items
Asset.getContent({
status: 'approved' // Optional, ['approved', 'draft']
}).then(getContentMktoResponse => ...)
// Content Response structure is unique to each Asset. See Asset details below.
Asset.updateContent(contentId, newContent).then(updateContentMktoResponse => ...)
// newContent is encoded as a Query String using the qs package.
Clone
// Traditionally, only a Folder target is needed for cloning an Asset
Asset.clone({
folder: {
type: "Folder", // ["Folder", "Program"]
id: 0 // Folder ID
}
}).then(cloneAssetMktoResponse => ...)
Delete
// Not all Assets can be deleted - some Assets must be "Unapproved" prior to deletion
Asset.delete().then(deleteAssetMktoResponse => ...)
// Traditionally returns { id: <ID of deleted asset> }
Drafts
// Approve a Draft Node, if one exists
Asset.approveDraft().then(approveAssetMktoResponse => ...)
// Traditionally returns { id: <ID of asset> }
// Discard a Draft Node, if one exists
Asset.discardDraft().then(discardAssetDraftMktoResponse => ...)
// Traditionally returns { id: <ID of asset> }
// Unapprove an Approved Node, if one exists
Asset.unapprove().then(unapproveAssetMktoResponse => ...)
// Traditionally returns { id: <ID of asset> }
All Asset method instructions:
All Assets extend BaseAsset, so the above mentions of data
property management and create()
and update()
methods remains the same unless otherwise noted.
Additional Asset specific methods mentioned below.
Channel
Marketo API does not allow for Channel Creation or Updating.
Methods create()
and update()
are voided. This is primarily offered for the static find()
method.
Update
Due to Marketo's interesting choice of splitting Email "Metadata" updates to two separate endpoints, this method will need to check changedData for certain props and fire TWO Post requests.
The first POST is for the Email Metadata:
- 'name',
- 'description',
- 'operational',
- 'published',
- 'textOnly',
- 'webView'
The second POST is for the Email "Content" - but not email body content.
- 'fromEmail',
- 'fromName',
- 'replyEmail',
- 'subject'
This returns a custom response object to compensate for sending two POST requests.
// ./lib/assets/Email.js - Line: 46
// Return the boolean response of both
let returnData = {
status: metaDataResponse.status === 200 && contentResponse.status === 200 ? 200 : 666,
success: metaDataResponse.success && contentResponse.success ? true : false,
errors: [...(metaDataResponse.errors ? metaDataResponse.errors : []), ...(contentResponse.errors ? contentResponse.errors : [])],
warnings: [
...(metaDataResponse.warnings ? metaDataResponse.warnings : []),
...(contentResponse.warnings ? contentResponse.warnings : []),
],
metaDataResponse: metaDataResponse,
contentResponse: contentResponse,
};
Send Sample Email
Send a Sample Email by supplying a single Email Address, and optional LeadID for token/personalization processing.
const sendEmailResponse = await myEmail.sendSample({
emailAddress: "text-inbox@example.com", // Required, will return false if not provided
leadId: 1234, // Optional, allows you to sample email token/personalization processing by Lead Record
textOnly: false, // Optional
});
Get Variables
Returns Array of Variable Data such as Strings, Colors, Booleans, Numbers, Lists.
const variablesEmailResponse = await myEmail.getVariables({
status: "approved", // Optional, Status string, ['approved', 'draft']
});
// Data will be an array of EmailVariableResponse objects
variablesEmailResponse.data = [
//<EmailVariableResponse>,
//<EmailVariableResponse>,
];
/*
EmailVariableResponse {
"name": "twoArticlesSpacer6", // Treat this like the ID
"value": "15", // Value - String,
"moduleScope": false
}
*/
Get Content
Returns Array of Content Sections such as Modules, Rich Text areas, Images, etc. Does not return Variables.
const contentEmailResponse = await myEmail.getContent({
status: "approved", // Optional, Status string, ['approved', 'draft']
});
// Data will be an array of EmailContentResponse objects
contentEmailResponse.data = [
//<EmailContentResponse>,
//<EmailContentResponse>,
];
/*
EmailContentResponse {
contentType (string): Type of content to set for the section. ,
htmlId (string): HTML id of the content section ,
index (integer, optional),
isLocked (boolean, optional),
parentHtmlId (string, optional),
value (object): Contents of the section
}
*/
Get Full Content
Returns the Full HTML Content of an Email Record for Version 2 Emails.
A shim is in place to return the JSON string content from getContent()
method for Version 1 emails.
const fullContentEmailResponse = await myEmail.getFullContent({
status: "approved", // Optional, Status string, ['approved', 'draft']
leadId: "", // Optional, process HTML by lead record
type: "HTML", // Optional, render as HTML or plain text
});
Approve Draft
See Drafts Mixin
Unapprove Email
See Drafts Mixin
Discard Draft
See Drafts Mixin
Delete Email
See Delete Mixin
Landing Page
Get Content
Returns Array of Content Sections such as Modules, Rich Text areas, Images, etc. Does not return Variables.
const contentLandingPageResponse = await myLandingPage.getContent({
status: "approved", // Optional, Status string, ['approved', 'draft']
});
// Data will be an array of LandingPageContentResponse objects
contentLandingPageResponse.data = [
//<LandingPageContentResponse>,
//<LandingPageContentResponse>,
];
/*
LandingPageContentResponse {
content (object, optional): Content of the section. Expected values vary based on type. Image: An image URL. RichText: HTML Content. HTML: HTML Content. Form: A form id. Rectangle: Empty. Snippet: A snippet id. ,
type (string): Type of content section = ['Image', 'SocialButton', 'Form', 'DynamicContent', 'Rectangle', 'Snippet', 'RichText', 'HTML', 'Video', 'Poll', 'ReferralOffer', 'Sweepstakes']
followupType (string, optional): Follow-up behavior of a form. Only available for form-type content sections. Defaults to form defined behavior. = ['url', 'lp', 'formDefined'],
followupValue (string, optional): Where to follow-up on form submission. When followupType is lp, accepts the integer id of a landing page. For url, it accepts a url string. ,
formattingOptions (JsonNode, optional),
id (object): Id of the content section, may be a string or an int ,
index (integer, optional): Index of the content section. Index orients the elements from lowest to highest ,
}
*/
Get Full Content
Returns the Full HTML Content of an Approved Landing Page Record. This utilizes it's own Axios instance for a simple
HTTP Get request to the Page URL. Returns false
if the Landing Page is not approved.
const fullContentEmailResponse = await myLandingPage.getFullContent();
if (fullContentEmailResponse.success === true) {
fullContentEmailResponse.data === "<doctype>...";
} else {
fullContentEmailResponse.data === { axiosError };
}
Approve Draft
See Drafts Mixin
Unapprove Email
See Drafts Mixin
Discard Draft
See Drafts Mixin
Delete Email
See Delete Mixin
Marketo REST API Inconsistencies
Likely due to the evolution of Marketo and its REST API over time, there are some serious inconsistencies with how the API responds, Asset to Asset.
I have tried to standardize the API interaction within this library as much as possible. However, some issues are unavoidable and should be taken into consideration.
I have documented these inconsistencies over at my personal blog: Coming Soon
BulkProcess
Do Not Use - Deprecated as of 1.0.0. Leaving the docs here for anyone still using pre v1.0.0.
:warning: Work in progress
Due to Marketo's API return limit of 200, BulkProcess
acts as an event-emitting auto-paging processor for large scale content reviews/updates.
// Note - this instantiation is for pre 1.0.0 releases. See docs above for current setup.
const { mktoManager, bulkProcess } = new MktoManagerInit(marketoRestCredentails);
Pass BulkProcess
a config param detailing the Asset Handler, search criteria, and asynchronous success & error callbacks to handle large scale reviews/updates.
Example BulkProcess Config
{
handler: null, // <BaseAsset> Asset Specific instance
searchParams: {}, // getAsset Search Params
// Depicts if we should wait for the successCallback to finish before continuing to next iteration
awaitSuccess: false,
awaitError: false,
successCallback: async function ( /*MktoResponse*/ response) {
// Accepts the getAsset method response MktoResponse instance
if (response.success) {
}
},
errorCallback: async function ( /*MktoResponse*/ response) {
// Accepts the getAsset method response MktoResponse instance
if (response.success) {
}
}
}
Config Property | Description |
---|---|
handler | MktoManager Asset Class, such as mktoManager.assets.LandingPage . |
searchParams | Object passed to the find() method for narrowing the API Get results. |
offset | Starting offset value for the API request. |
cycleMaxReturn | Set an integer for the maxReturn value of records from Marketo. Determines the number of results that will be offered to your successCallback() method or success event. Defaults to 5, max 200. |
cycleMaxIteration | Set an integer for the maximum iterations of the while loop. Offered as a safety feature to help limit the total number of API calls per BulkProcess usage, and to mitigate run-away looping if there is a break in the logic. |
--- | --- |
awaitSuccess | Boolean if you want the while loop to await the finished Promise for your successCallback() |
awaitError | Boolean if you want the while loop to await the finished Promise for your errorCallback() |
successCallback() | Async method to be used on every successful retrieval from the API. Optional, event listener can be used instead. |
errorCallback() | Async method to be used on every failed retrieval from the API. Optional, event listener can be used instead. |
:warning: NOTE: To process the returned API results once they are returned, you can either define an asynchronous successCallback()
method within the BulkProcess config, OR attach a listener to the success
BulkProcess event.
Personally, I prefer the event listener usage.
successCallback()
Usage Example
// Set BulkProcess config
const myBulkProcessConfig = {
handler: mktoManager.assets.LandingPage, // Define which Asset type we are retrieving and processing
searchParams: {
status: "approved", // Will only retrieve and process Approved records
},
awaitSuccess: true, // Will Await your successCallback before continuing
successCallback: async function (/*MktoResponse*/ response) {
// Accepts the getAsset method response MktoResponse instance
if (response.success) {
// Save all results into my fake db
response.getAll().forEach(landingPage => {
db.insert("landingpages", landingPage.data);
});
}
},
};
// Instantiate the BulkProcess
const processor = new this.bulkProcess(myBulkProcessConfig);
// Run the BulkProcess
processor.run();
success
Event Listener Usage Example
// Set BulkProcess config
const myBulkProcessConfig = {
handler: mktoManager.assets.LandingPage, // Define which Asset type we are retrieving and processing
searchParams: {
status: "approved", // Will only retrieve and process Approved records
},
// No successCalback() definition required
};
// Instantiate the BulkProcess
const processor = new this.bulkProcess(myBulkProcessConfig);
// Add Event Listeners
processor.on("success", response => {
if (response.success) {
// Save all results into my fake db
response.getAll().forEach(landingPage => {
db.insert("landingpages", landingPage.data);
});
}
});
// Run the BulkProcess
processor.run();
BulkProcess Events
Event | Description |
---|---|
logger | Fired every time a BulkProcess log is recorded. Receives data object from Tracer Logger. Easily log or print data.output to view the BulkProcess log. |
request_http_error | Fired when the Axios status !== 200. Recevies MktoResponse instance response object. |
request_mkto_error | Fired when the MktoResponse.success === false. Recevies MktoResponse instance response object |
request_success | Fired when the MktoResponse.success === true. Recevies MktoResponse instance response object. |
success | Fired when the MktoResponse.success === true AND we have some Mkto Results. Recevies MktoResponse instance response object. Also the event when we would fire the successCallback within the BulkProcess config, if one was passed. |
finished | Fired when the BulkProcess while loop is completed. Receives the entire BulkProcess instance. |
Under continuous improvement.