Looking for guidance on how to best import our html email headers and footers into adobe campaign as personalization blocks. We have 100+ of each and I do not want to manually copy and paste html code into Adobe Campaign.
I was hoping I could do something where I place the html in a folder on our SFTP and then have a Workflow import them as personalization blocks but open to anything really.
Solved! Go to Solution.
Views
Replies
Total Likes
I ended up making a lot of changes and then after some time I found that it was failing because I was running the workflow in the Web UI. Running it through the Desktop application everything worked as expected.
Hello @Hurston You can update the default delivery template to have the headers and footers. This way any new delivery will already have those PB populated by default
Thanks, but my question is more so how do I actually get my headers and footers into Adobe Campaign without having to manually copy and paste the html int the personalization blocks for 100+ files.
Views
Replies
Total Likes
Hello @Hurston Here is what you can do.
Write a JS code in workflow to read the HTML files from SFTP server and then add the code to dynamically create the PB.
Sample Code:
function createPB(pbContents,label,internalName){
var newPB=nms.includeView.create();
newPB.Duplicate('nms:includeView|2029'); // 2029 is the primary key of an existing shared PB
newPB.source.text=pbContents;
newPB.name=label;
newPB.name=internalName;
newPB.save();
}
var FOLDER_PATH=""; // PATH of your folder that contains HTML files
var FILE_NAME_PATTERN = "*.html"; //pick only HTML files
var objDirectory = new File(FOLDER_PATH);
var objFiles = objDirectory.list(FILE_NAME_PATTERN,false);
for each(var objFile in objFiles){
var PersonalizationBlockName=objFile.name.replace(".html",""); //Get file name and remove .html then use the as label of PB
var htmlFile=new File(FOLDER_PATH+objFile.name);
htmlFile.open();
createPB(htmlFile,PersonalizationBlockName,PersonalizationBlockName);
htmlFile.close();
htmlFile.remove(); // this is to delete the file once it is processed.
}
This code is not tested and is just for guidance. DO NOT USE IN PRODUCTION.
Thanks I tried doing the following but I get errors, assuming there must be a step where I specify to the JS that the path is the SFTP or something.
// Define the correct directory where the files are stored
var FOLDER_PATH = '/import/personalization_blocks/';
var objDirectory = new File(FOLDER_PATH);
var files = objDirectory.list();
logInfo("Starting import of *.htm files for Personalization Blocks...");
if (files != null) {
logInfo("Found " + files.length + " files in " + FOLDER_PATH);
for each (var fileName in files) {
var filePath = FOLDER_PATH + fileName;
var file = new File(filePath);
if (file.exists && file.name.indexOf('.htm') !== -1) {
logInfo("Processing file: " + file.name);
file.open('r'); // Open the file for reading
var content = file.read(); // Read the content of the file
file.close();
var personalizationBlockName = file.name.replace('.htm', '');
try {
// Check if the personalization block already exists
var query = xtk.queryDef.create(
'<queryDef schema="nms:includeView" operation="select">' +
'<select>' +
'<node expr="@name"/>' +
'</select>' +
'<where>' +
'<condition expr="@name" value="' + personalizationBlockName + '"/>' +
'</where>' +
'</queryDef>'
);
var result = query.execute();
if (result && result.@name == personalizationBlockName) {
logInfo("Personalization Block already exists. Updating...");
var block = xtk.session.write(result);
block.name = personalizationBlockName;
block.source.text = content;
xtk.session.write(block);
logInfo("Updated Personalization Block: " + personalizationBlockName);
} else {
logInfo("Creating new Personalization Block...");
var newPB = nms.includeView.create();
newPB.Duplicate('nms:includeView|2029'); // 2029 is an existing PB ID used as a template
newPB.source.text = content;
newPB.name = personalizationBlockName;
newPB.label = personalizationBlockName;
newPB.save();
logInfo("Created new Personalization Block: " + personalizationBlockName);
}
} catch (e) {
logError("Error processing Personalization Block '" + personalizationBlockName + "': " + e.message);
}
file.remove(); // Optional - Delete file after processing
} else {
logInfo("Skipped file (not .htm): " + file.name);
}
}
} else {
logInfo("No files found in " + FOLDER_PATH);
}
Views
Replies
Total Likes
Thanks, I ended up changing the JS to the below, btu it only creates the empty file for test99 and doesn't import the files in the SFTP.
// Function to create PB
function createPB(pbContents, label, internalName) {
//var newPB = xtkQueryDef.create("nms:includeView|6580"); // ID 65447 formerly nms:transactionalMessage
//newPB.copy(); // Duplicates the PB with ID 65447
//newPB.internalName = internalName; // Sets the internal name for the PB
//newPB.label = label; // Sets the label for the PB
//newPB.content = pbContents; // Sets the PB content
//newPB.save(); // Saves the new PB
var joinedContent = "";
for each(var line in pbContents) {
joinedContent += line;
}
var escapedContent = joinedContent.replace(/'/g, "\\'");
logInfo("Contents",escapedContent);
var newPB = <includeView xtkschema="nms:includeView" label="Test8" name="test8" contentType="1" _key="@name">
<source dependOnFormat="1" noEscaping="false">
<html></html>
</source>
</includeView>;
var doc = new DOMDocument("html", "http://www.w3.org/1999/xhtml"); // Assuming you have a DOMDocument object
var cdata = doc.createCDATASection(escapedContent);
newPB.source.html = cdata.data;
newPB.@label = "Test99"; // changing this to PersonalizationBlockName makes it no longer work
newPB.@name = "test99"; // changing this to PersonalizationBlockName makes it no longer work
logInfo("NEW PB",newPB.toXMLString());
xtk.session.Write(newPB);
}
//var FOLDER_PATH = "sftp://my-instance.com/incoming/import/personalization_blocks/"
var FOLDER_PATH = "sftp://my-instance.com/incoming/import/personalization_blocks/"; // SFTP path to the folder containing HTML files
var FILE_NAME_PATTERN = "*.htm*"; // Picks only .htm files (case-insensitive)
// Create an SFTP connection object and list files in the directory
var objDirectory = new File(FOLDER_PATH);
var objFiles = objDirectory.list(FILE_NAME_PATTERN,true); // List all files matching the pattern (*.htm)
// Loop through each file in the directory
for each(var objFile in objFiles) {
logInfo("new Inside Obj FIle");
var PersonalizationBlockName = objFile.name.replace(".htm", ""); // Get the file name and remove ".htm"
var htmlFile = new File(FOLDER_PATH + objFile.name); // Create a File object for the HTML file
logInfo("new HMTL File",htmlFile.fullName);
htmlFile.open(); // Open the file
createPB(htmlFile, PersonalizationBlockName, PersonalizationBlockName); // Create the PB using the file contents and name
htmlFile.close(); // Close the file
// htmlFile.remove(); // Delete the file once it is processed
}
Views
Replies
Total Likes
Hello @Hurston Can you confirm if the code to read the contents of the file is working?
Views
Replies
Total Likes
Hi @Hurston,
Were you able to resolve this query with the given solution or was this something you were able to figure out on your own or do you still need help here? Do let us know.
Thanks!
Views
Replies
Total Likes
I ended up making a lot of changes and then after some time I found that it was failing because I was running the workflow in the Web UI. Running it through the Desktop application everything worked as expected.
Thanks for sharing the update!
Views
Replies
Total Likes
Views
Likes
Replies