Recipients Selected On Demand By API Calls
Normally, messages sent via LISTSERV Maestro select their recipients actively from some sort of pre-existing repository, either in Maestro's subscriber warehouse or in some imported form. Maestro On-Demand Recipients go beyond this methodology by allowing you to not only trigger a prepared mail job's delivery based on an external event (and then having Maestro perform the necessary steps to gain access to the recipient data) but to also supply the actual recipient data directly with the API call.
A typical usage scenario is this: Assume you run an online shop system that allows customers to purchase merchandise. Typically, upon completion of a purchase, customers expect some form of email confirmation. While shop systems certainly support such completion messages, you may want to employ Maestro's sophisticated tracking and reporting capabilities to measure if and how your customers interacted with the completion message, for example to follow-up on the completion message with additional discount offers or other marketing messages.
Basic Workflow
- Prepare a Mail Job: Since you will be sending email messages via Maestro,
you first need to create a mail job or edit an existing one.
- Edit the recipients of this mail job and choose the recipients type Send to Subscriber List. On the "Source" page of the recipients wizard, select the desired subscriber list, segment or group and choose the Advanced subscriber selection option. On the Source Details page, choose Recipients Selected On Demand By API Calls.
- Define the remaining parts of the mail job workflow and proceed to the authorize delivery screen. Due to the job's special recipients definition, the "Authorize" workflow step activates the capability to accept external API calls for this mail job.
-
Determine the base URL: You will have to configure your shop system to access a special URL in response to the event of a completed purchase. Similar to other actions that are triggerable externally, on-demand recipient API calls go via an external trigger URL, as described here.
Note: Even if processing the provided data supplied with the call fails with an error information as described further below, the associated URL call still succeeds with the HTTP status "200-OK", which means that your system also has to inspect the data provided in the response body if this "OK"-type HTTP response code is returned.
- Acquire the security token for the API URL: Open the summary of your prepared mail job. On this screen you find a link to show the security token.
-
Configure your system to provide recipient data with the triggering URL: With the preparation steps performed so far, you have a base URL for your API calls similar to the following:
http://SERVER_NAME/lui/externalAction.do?token=SECURITY_TOKEN
(The value for SECURITY_TOKEN is the security token acquired from your prepared mail job.)
You now have to configure your external system to supply the value for at least one additional URL parameter to finally yield a triggering URL in this form:
http://SERVER_NAME/lui/externalAction.do?token=SECURITY_TOKEN&recip=DATA
The value for "DATA" above is supplied in JSON format that has additionally been URL-encoded (in order to be valid as an URL parameter). The full format is described below. A simple example, in URL-encoded form, looks like this:
http://SERVER_NAME/lui/externalAction.do?token=SECURITY_TOKEN&recip=%7B%22email%22%3A%22test%40example.com%22%2C%22ifNotExistsAddAndSend%22%3Atrue%7D
In human-readable form, the value for the "recip" parameter in the example above was:
{"email":"test@example.com","ifNotExistsAddAndSend":true}
If your external system accesses this URL after a customer with the email address "test@example.com" has purchased merchandise from your shop, the following happens in Maestro:
- If the address "test@example.com" does not yet exist in the subscriber list (or list group) selected in the recipients definition of your prepared mail job, then this address is registered as a list subscriber (or group subscriber, depending on your selection in the recipients wizard). Since the URL call did not provide additional recipient profile data, this action only succeeds if your list or group does not have boolean or mandatory fields (more below).
- The associated subscriber record is registered as recipient of your prepared mail job and the message of the prepared mail job is sent to the given address.
(Note that the data in the example above included "ifNotExistsAddAndSend" with the value "true". This makes sure that new addresses are also added to the list or group.)
- Configure your system to act properly on the HTTP response provided when accessing the URL:
If all data supplied with the URL was processed successfully and Maestro successfully delivered the
associated email message, then the HTTP response consists of the following text:
{"result":"SENT"}
If you receive anything other than the text above, then this means that the message was not delivered. The actual text normally provides details on what happened, so the easiest way to act on the response would be to program your system to handle the delivery as failed and log the response for later troubleshooting.
Even if the example used in the description above is rather simple, it illustrates the basic mechanism and the minimum requirements that an external system must provide in order to properly provide on-demand recipients via URL calls: The ability to access HTTP URLs with dynamic parameters in URL-encoded format and to dynamically act on the associated HTTP response.
Personalizing the message with profile fields
The URL in the basic example above only allows you to send a message with very generic content, i.e not much more than "thank you for your purchase". To employ Maestro's sophisticated mail-merging capabilities, you may want to provide additional information with the email address, for example values for additional recipient profile fields such as the first name or the last name. (These values may in fact be mandatory fields of your list or group, which means that the URL call would actually fail if your system did not provide these values with the call.)
To provide profile values in addition to the email address, you augment the (non-encoded) value for the "recip" parameter with the additional "profile" JSON property, e.g.:
With this additional information supplied in the URL call, Maestro also checks if your list or group actually contains fields with names "FIRST_NAME" and "LAST_NAME". If they don't exist and have not been configured in the mail job's recipients wizard as "On-Demand Merge Fields" (more on this later), the URL call fails with an appropriate error message. If this validation succeeds, then the values provided with the URL are also used for mail-merging in the message of the associated mail job.
Personalizing the message with additional on-demand merge fields
The profile fields you have configured in your list or group are only used for the purpose of sending personalized email messages and do not necessarily contain one-time only information which however may be vital in the context of for example a purchase confirmation or a shipping notice, which typically would include the specific shipping address that was chosen while performing the checkout in your shop system.
If you plan to send messages which contain one-time only information that you do not want to add as profile field to your list, you prepare the mail job in Maestro with additional on-demand merge fields: When preparing your mail job following the procedure described above, you additionally need to open the "Recipients Details" page of the recipients wizard. On this page you see a section Additional On-Demand Merge Fields. Continuing the example of a shipping address that you do not want to appear in the list or group profile, you can supply on-demand merge fields here that would constitute a shipping address, for example with several address lines:
With the mail job prepared in Maestro in such a manner, the following value for the "recip" parameter would also be accepted, even if your list or group only knows the fields EMAIL, FIRST_NAME and LAST_NAME:
Now that these values are available for mail-merging, you are able to write a generic shipping notice using the variables &FIRST_NAME;, &LAST_NAME;, &SHIPPING_ADDRESS_LINE1;, &SHIPPING_ADDRESS_LINE2; and &SHIPPING_ADDRESS_LINE3;, which appear under "Merge Fields" on Maestro's "Define Email Content" screen.
Customizing drop-in content in the message
While using merge fields in your content is a good option to personalize certain small areas with short, recipient-specific values, you may want your shop system to supply a larger portion of content (be it HTML or plain text) that for example describes the purchased item in a manner that is completely different from other items (in the sense that the intended result can not be achieved through simple mail-merging). Again, this is illustrated best with the following simple example:
Assume that the content of your prepared mail job contains the drop-ins {{header}}, {{body}} and {{footer}}. While you are fine with the values provided by {{header}} and {{footer}} (you use these drop-ins in all your messages to include boilerplate header/footer text for your messages), the value of the {{body}} drop-in shall now be set to a custom value that is provided in the value of an additional parameter "content":
With this information supplied in the URL call (in addition to the other parameters described up until here), Maestro also checks if the drop-in with the name "body" exists among the drop-ins of your account or group. Additionally, to avoid undesired errors, the content of your mail job is also verified to contain an occurrence of the drop-in token for "body" (i.e. usually the token {{body}}. With these checks passed, the message for the job is sent and the usual drop-in replacement also happens, but an exception is made for the "body" drop-in:
Instead of using the currently defined value for this drop-in (which is not suitable for this specific on-demand URL API call), the given text "Latest technology knife sharpening kit" is used instead for delivery. (Note: The current value of the given drop-in element remains unaffected, other mail jobs that use the same drop-in normally will not be affected by your API call.)
Warning: If your shop system uses API calls like this for very many different drop-in replacements given in the JSON for "dropInValues", consider employing mail-merging in the text given for ""dropInValue"", i.e. instead of already replacing something like &CUSTOMER_ID; with the specific id in the text for ""dropInValue"", you should instead use the mail-merge token &CUSTOMER_ID; in the value and supply the value for &CUSTOMER_ID; with the "profile" given for the "recip" parameter described above.
The reason for this is that drop-in content with changing values (as is the case here) prompts Maestro to create and manage content variants, similar to how this is done for auto-repeated delivery. By mentioning the purchasing customer's ID specifically inside the text for ""dropInValue"", you create a new content variant for every single customer purchase of the same shop item. By employing mail-merging, you avoid this: Only one content variant is created which can be associated more or less directly with your shop item. And since individual recipient mail-merging is performed after creating the variant, your recipients still receive the message with their ID replaced.
More information about content variants can be found here.
To define a meaningful title for the content variant that is created through this API call, you can optionally add this
to the value given for the "content" parameter, so that the result looks like this:
Augmented like this, the content variant associated with this API call is easier to identify later when you log in to Maestro to run reports on the variants.
Note: Since this feature works in a manner completely analogous to drop-in content (you only "override" the drop-in's value while the rest of the technology is the same), you are welcome to use links in the text that you supply for "dropInValue". Contrary to the values you supply for conventional mail-merge tokens, drop-in content value undergoes tracking link replacement (if so configured in the job's settings), which means that you can view tracking reports specifically for the links that your shop system may supply during the API call.
Sending Messages to Existing Subscribers
"ifNotExistsAddAndSend":true
Setting this flag allows you to send email also to addresses that previously did not exist on the list or list group (by first also adding the address with the supplied profile to the list or group). If you instead supply the value "false" (or leave out the flag completely), then Maestro instead validates that the given email address already exists, which protects you for example from spelling errors.
By default, when sending messages to existing subscribers, additional profile information you supply with the URL call is ignored, the profile values that exist in Maestro's database take precedence. To override this behavior and to actually also update the data in Maestro with the values you have included with URL, use:
"ifExistsDoUpdate":true
With this, the given profile fields are updated with the values you supply in the URL, the rest of the subscription profile in Maestro remains unchanged.
Overriding Delivery Constraints
Maestro respects certain constraints before sending email messages to subscribers of a subscriber list. A subscriber may for example have chosen to temporarily suspend email delivery for a given list, or a list group subscriber may not be subscribed to any of the subscriber lists in the group. Or the list group may be configured so that only up to a certain limited number of emails is sent to a given subscriber in a certain period of time.
Normally, delivery to such subscribers does not happen. Forcing the delivery regardless of such constraints or limitations requires careful consideration because this effectively ignores the subscriber's explicit intention to not receive mail. Examples were such a behavior is not considered problematic are purchase confirmations or shipping notices which legally belong to a business transaction between you and your customer. To enable forced delivery, use:
"ifExistsForceSending":true
Description of the format for the "recip" parameter
- "email":"test@example.com"
Defines the address to which Maestro shall send the email message. Must not be empty and is checked to be a valid Internet email address.
- "profile":{FIELD1,FIELD2,FIELD3,...}
Defines the profile associated with the given address. Used to add/update the subscriber profile or for on-demand mail-merging. Each of "FIELD1", "FIELD2", ... in the pseudo notation above is a JSON property which can be any of the following:
- "FIELD_NAME":"text"
A text field with its textual value in double quotes.
- "FIELD_NAME":12345
A number field with its integer value (without quotes).
- "FIELD_NAME":"selected value"
Syntactically equivalent to a text field, only that "selected value" is the display text of one of the entries of a lookup table that is assigned to a single-select field.
- "FIELD_NAME":["selected value 1","selected value 2",...]
Similar to above, only that the associated list field allows multiple selection.
- "FIELD_NAME":true
A boolean field with its boolean value (without quotes).
In all cases, FIELD_NAME is the name a known merge field. Merge fields either exist as fields of the underlying subscriber list or group or they have been configured in the recipients wizard of the associated mail job as "Additional On-Demand Merge Fields".
- "FIELD_NAME":"text"
Description of the format for the "content" parameter
- "dropInValues":JSON_HERE
Top-level property of the "content" parameter JSON value. Describes, in JSON format, the customized drop-in values (one or multiple, see below) for this API call.
- "dropInName":"body"
JSON property inside of "dropInValues". Defines the name of a user-defined drop-in element whose value shall be overridden during this API call.
- "dropInValue":"value goes here"
JSON property inside of "dropInValues". Defines the value to use instead of the current drop-in element value. This custom value is only used during the API call, the actual drop-in element value is unchanged.
- "variantTitle":"title goes here"
Top-level property of the "content" parameter JSON value. Contains the desired title of the content variant that will be associated with this API call (either a new one or an existing one, in which case the existing variant's title is overwritten).
Send Result: Success
{"result":"SENT"}
This text is returned in the body of the HTTP response if Maestro has successfully performed the delivery of the email message for a recipient supplied as value for the "recip" parameter.
Send Result: Error
In order for the delivery to succeed, various validation, compatibility and internal checks are performed. If any of these checks fail, then a suitable "result" property other than the above is returned. Possible errors are:
{"result":"PARSE_ERROR", "error":"Parse error in JSON data"}
{"result":"NO_RECIPIENTS", "error":"No recipients specified"}
{"result":"MAIL_JOB_NOT_FOUND", "error":"Mail job not found"}
{"result":"ILLEGAL_JOB_STATE", "error":"Illegal mail job state"}
{"result":"TRIGGER_CLOSED", "error":"Trigger closed"}
{"result":"DATASET_NOT_FOUND", "error":"Dataset not found"}
{"result":"HOSTED_LIST_NOT_FOUND", "error":"Subscriber list not found"}
{"result":"PROFILE_VALIDATION_ERROR", "error":"Profile validation error"}
{"result":"ADDRESS_NOT_FOUND", "error":"No subscriber with specified address found and property ifNotExistsAddAndSend not set"}
{"result":"ADDRESS_REJECTED_BY_SUPPRESSION_LIST", "error":"Address on suppression list"}
{"result":"ADDRESS_REJECTED_BY_LIST_PROTECTION", "error":"List protection is enabled and address was previously unsubscribed or bounced too often"}
{"result":"SEND_ERROR", "error":"Sending failed"}
{"result":"INTERNAL_ERROR", "error":"Internal execution error"}
{"result":"INVALID_EMAIL", "error":"Invalid email address"}
{"result":"MISSING_EMAIL", "error":"Missing email address"}
{"result":"INVALID_DO_UPDATE_FLAG", "error":"Invalid ifExistsDoUpdate property"}
{"result":"INVALID_FORCE_ADD_FLAG", "error":"Invalid ifNotExistsAddAndSend property"}
{"result":"INVALID_FORCE_DELIVERY_FLAG", "error":"Invalid ifExistsForceSending property"}
{"result":"INVALID_PROFILE", "error":"Invalid profile property"}
{"result":"MISSING_DROP_IN_NAME", "error":"Missing drop-in name"}
{"result":"MISSING_DROP_IN_VALUE", "error":"Missing drop-in value"}
{"result":"UNKNOWN_DROP_IN", "error":"Unknown drop-in"}
{"result":"DROP_IN_NOT_IN_MESSAGE", "error":"Drop-in not appearing in content"}
{"result":"MISSING_CUSTOM_DROP_IN_VALUES", "error":"Missing custom drop-in values"}
The properties result and error in the JSON objects listed above are always present in the case of a non-successful send result. Depending on the actual error that occurred, the additional message property provides further details about the error, such as for example input validation error messages in the case of a profile field with custom input validation defined.
Supplying Multiple Addresses
The examples above all trigger the delivery of an email message to one recipient only. If your system needs to trigger delivery for several recipients, then, for convenience, it is possible to supply multiple values for the recip parameter in JSON array format.
This is how you supply one recipient:
{ "email":"test@example.com", "ifNotExistsAddAndSend":true }
To supply multiple recipients, you supply for example:
[{ "email":"test@example.com", "ifNotExistsAddAndSend":true }, { "email":"test2@example.com", "ifNotExistsAddAndSend":true }]
Note the array brackets in the example above. With this syntax, Maestro processes each of the supplied recipients one by one exactly in the same way single recipients are processed. The result provided in the HTTP response body is also a JSON array, whose sequence follows the sequence in which the recipients were supplied. If delivery to all provided recipients succeeds, then the response body looks like this:
[{"result":"SENT"},{"result":"SENT"}]
Supplying Multiple Drop-In Values
The examples above only show how to supply one drop-in value only. If you need to supply multiple values, then it is possible to supply multiple values for the dropInValues property of the content parameter in JSON array format, similar to how you do this for multiple recipients:
This is how you supply one drop-in value:
{ "dropInValues" { "dropInName":"body", "dropInValue":"body value here" } }
To supply multiple drop-in values, you supply for example:
{ "dropInValues": [ { "dropInName":"body", "dropInValue":"body value here" }, { "dropInName":"footer", "dropInValue":"custom footer value here" } ] }
Note the array brackets in the example above. With this syntax, Maestro processes each of the supplied drop-ins exactly in the same way single drop-ins are processed. The logic that applies to standard drop-in replacement (outside of API calls) also applies here: The whole set of drop-in replacement values that are present during a job delivery determines if a new content variant is created or not, regardless of whether these values were supplied with an API call like this one here with multiple drop-in values, a call with a single drop-in value, or from standard drop-in replacement values that were retrieved from the Maestro Drop-In elements of your account or group.