Direct mail
- 9 minutes to read
Some products may require the personalization of every printed copy, for example, when you are preparing letters and pre-addressed envelopes for mass mailings (a so-called mail merge, direct mail marketing), creating wedding invitations, or printing business cards in a corporate style.
For example, you are building a marketing campaign, where you have a catalog of such products as postcards, letters, and invitations. For this campaign, you select one or more products and one or more mailing lists. Then, you select templates for the products and may want to customize these templates with static design elements and variable fields, like text, images, or barcodes. You may want to generate preview images on a small sample of addresses.
This article provides an overview of how this scenario can be implemented with Customer's Canvas.
General idea
To implement direct mail marketing, a customer creates a campaign and adds templates to this campaign. Customer's Canvas allows you to arrange the templates into folders by categories, as well as create product variants based on these templates. Then, the user selects a template, personalizes the template if needed, provides a data set to be applied, previews the design with a data sample, and if they find the preview good, they proceed to checkout.
Let's split this process into steps.
Roadmap for direct mail
1. Creating templates
A template is a basic public design file for rendering. When users start working with the template, they can change the location of the default design elements and add new design elements and variable fields. As a result, they get a personalized private design.
You may wonder how exactly to create the templates. Customer's Canvas supports templates created in Adobe Photoshop, Adobe InDesign, and the Customer's Canvas Template Editor.
To learn how you can add variable fields to templates, let's first list elements that can become variable and be personalized:
- In-string (
[#]
), interpolation{{}}
, and text placeholders<TPH>
- Image placeholders
<PH>
- Barcode placeholders
<BPH>
To allow the BackOffice API to recognize a field as variable, you need to set its isVariable
property to true
. You can do this in the Template Editor by switching the Variable field toggle, or in Adobe editors by adding the <VAR>
marker.
You may want to add special buttons to the editor's toolbox, so that your users create variable fields of the text, image, or barcode type in personalized designs. To do so, you need to change the configuration of the editor as described below.
2. Organizing a catalog
Upload your templates to your Customer's Canvas tenant and organize them into folders in the Assets > Designs section to make it easy to navigate them. For example, you may create the following hierarchy:
- Products (e.g. postcards, letters, invitations, ...)
- Options (e.g. size, material, ...)
- Variants (combinations of all option values with assigned SKUs)
- Options (e.g. size, material, ...)
This hierarchy fits the PIM products. Using this approach, you can easier manage designs, enable the price support, and link product variants in Customer's Canvas with products in your application using SKUs.
When creating products, select valuable options to define product variants, and a template will represent a product variant design in this case. For more details, refer to the Products and variants topic.
3. Personalizing templates
After a user has selected a template, open an editor so that the user could personalize it. For example, you can use the Design Editor. In your tenant, an instance of this editor is installed by default.
To open a template, you need:
- A link to the Design Editor instance
- A template ID
- A user ID
- An editor configuration
The Design Editor link
To get a URL that linking to Design Editor through the user interface, navigate to Settings > Applications > Design Editor. However, it's not recommended to hardcode this link, it's better to request it using the Tenant API.
Using this link, load the IframeApi.js script on the page.
<script type="text/javascript" id="CcIframeApiScript"
src="<design-editor-link>/Resources/Generated/IframeApi.js"></script>
A template ID
When you are managing templates on your own, you can find the ID in the template properties: navigate to the template in the Assets > Designs section, right-click its thumbnail, click Properties, and copy the ID. For more details, refer to the Cloud Design Editor topic.
When you are using Customer's Canvas products, get the ID of a product variant design through the Storefront API - Products. In this case, you need to find a product by ID or by reference, get product variants, and get the product variant design. For more details, refer to the description of working with PIM products.
A user ID
First, decide how you can grant access to designs and other assets in your application.
Since every user has isolated private storage, different users cannot open each other's designs. However, if you create campaigns, you can use a campaign ID as the user ID. This will allow you to share the campaign data, without linking to the company or a single user.
A Design Editor configuration
The editor configuration can be obtained from a workflow. If you implement a custom design processing in your application, you can create a workflow of the Design Editor
type. If you use the PIM module, your product will contain a specific workflow, which can define not only the configuration of the Design Editor, but also completely determine the personalization process.
In the Opening products for editing topic, you can find an example of getting a workflow.
For variable data printing, you may want to add buttons to the editor's toolbox, so that your users create variable fields when personalizing their designs. To do so, in the configuration, find the buttons
array and add a button definition with the itemConfig.isVariable
property to true
.
{
"buttons": [
{
"action": "Text",
"iconClass": "cc-icon-add-text",
"itemConfig": {
"name": "CustomerName",
"isVariable": true,
"text": "Customer",
...
}
},
...
]
}
Pay attention to the type of variables, since text and images have different fields. For more details about the button types, refer to the topic describing the Toolbox configuration.
Initializing the editor
To open the Design Editor, use the CustomersCanvas.IframeApi.loadEditor
method. It's initialized with the following arguments:
- a container with an HTML element
iframe
- a template ID
- editor's parameters
config = {
"userId": userId,
"widgets": {
"Toolbox": {
"buttons": [{
"action": "Text",
"iconClass": "cc-icon-add-text",
"itemConfig": {
"name": "CustomerName",
"isVariable": true,
"text": "Customer"
}
}]
}
}
};
// ...
await CustomersCanvas.IframeApi.loadEditor(document.getElementById("editorFrame"), templateId, config);
In the Editor config reference, you can find all the parameters to configure the Design Editor.
4. Preview design with data
When the user finishes the personalization, you can display a design preview with applied data sets on the approval page. Here, you can use different strategies for data substitution, for example, you may want to display the first and the last records of the data set, or some corner cases such as the longest field values, or implement another logic.
Validating variables
You may want to check that the design contains all the required variable fields. The endpoint DesignAtomsService_GetVariables allows you to retrieve the variables. The response will contain an array of items.
"items": [
{
"name": "string", // for example, "job title"
"value": "string", // for example, "junior copywriter"
"type": "string" // one of "Text", "InString", "ImagePlaceholder", "Image"
}
]
Defining variable data
After you have selected a data set and obtained the list of variables, use the endpoint DesignAtomsService_RenderDesignProof to get a design preview. In the request body, you can pass the data for variable fields in the following format.
{
"designId": "string", // for example, "64f97dd555334834ede11817"
"ownerId": "string", // for example, "6527afc635b52bfadd355226"
"renderingConfig": {
"surfaceIndex": 0,
"width": 800,
"height": 500,
"fileFormat": "Jpeg"
},
"variableData": [
{
"name": "string", // for example, "job title"
"value": "string", // for example, "junior copywriter"
"type": "string" // for example, "Text", "Image"
}
]
}
In the variableData
pass key-value pairs defining values for substitution. When renderingConfig.surfaceIndex
is undefined, the response will contain all design pages.
To learn about defining images, refer to the Adding variable images topic.
5. Saving a private design
When the user finishes editing a template and clicks Save, the personalization results are saved to the private user's storage as a private state file. This private design is ready for further processing.
A state file not only defines design elements but also may contain a data sample that will be applied to this design. The endpoint DesignAtomsService_SaveVdpData puts the samples to state files, while the endpoint DesignAtomsService_LoadVdpData reads them.
A data set can define only the field values or the fields with parameters describing the rendering procedure. For mode details, refer to the Saving VDP data topic.
Note that you need to clean up the data saved in state files as well as private assets and designs, as described in Cleaning up private assets. You can delete the entire state file or only the saved data by using the endpoint DesignAtomsService_DeleteVdpData.
6. Rendering designs
For rendering, create a pipeline with a render-vdp-hires task and create a project based on this pipeline through the endpoint Projects_CreateBySpecificPipelineScenario.
However, you can go by the usual way and create a project through Projects_CreateWithSingleItem, which transfers the design ID and VDP data through the Storefront API. Once the project is created, the rendering job begins immediately.
Customer's Canvas allows you to manage the resulting artifacts. When rendering a data sample, every data set in that sample is applied to the design and creates a single print file. Depending on your task, select how you can get the resulting artifacts:
- A single archive with many zipped files
- A multipage PDF file
- Many single print files
You can pull the rendered files one by one or in a combined file. For PDF output file, the sample may represent pages of a multipage file. For a set of single-page file, you can create a ZIP archive with these files. When the rendering task provides a link to the print files, you can pull files using this link.
However, a push strategy is also available. You can add to your pipeline such tasks as upload-to-ftp or export-to-ecommerce.
7. Cleaning up private assets
Since this task involves a large flow of data and assets, it is necessary to provide the cleanup procedure for your users in your storage. You can either rely on the retention policy implemented in BackOffice or perform the cleanup by your own.
According to the default retention policy in BackOffice, once a day, a background task that finds and deletes outdated assets for all tenants with EnableAssetsRetention
set to true
is performed on the backend. Assets are considered outdated if they meet two the following conditions:
RetentionPolicy
is set toDefault
.LastAccessTime
is earlier than theAssetsRetentionPeriodInDays
defined in the tenant settings.
To run this task through the API, use the endpoint Tenants_CleanUp. You can also clean up the assets manually or write scripts for that.