Export Siebel Communication Templates using eScript
“Communication templates” - so boring a name for such an exciting thing that enables sending emails.
Siebel had communication templates as long as I can remember. Their function was simple and straight forward - enable user/system to send emails ad-hoc or using a pre-defined template.
Did I just hear you ask how and where to use those functions? You just go to a view, select the record (let’s assume a Contact - it should have email functionality enabled).
Next, go to File menu > Send Email. Alternatively, click F9.
You can now select from email templates configured for the entity (in our case Contact). See the goodness of data getting auto populated from the Siebel record into the email draft.
Finalize the draft, and hit Send button to send the email on its way.
All this email magic starts from the email templates that you can configure in Siebel. You can create simple (or advanced) plain text, rich text, or HTML email templates in multiple languages.
The email template capability is all good. But, for some strange reason, Siebel does not provide an easy way to export/migrate these assets. Before Release 8, even ADM did not support the migration OOB. You would have to start creating ‘Content Object’ and what not to get the migration to work.
For some reason if you are simply stuck in a pre-8 version, or if you are simply interested in exporting all the email templates, I can show you how.
We will use Siebel eScript to get this done.
Before we start though - take note of the quickest way to create/debug/test eScript. No, not by any fancy eScript framework - but using the plain, simple Client Business Service. Just create a new client service, start adding the code below, and within no time you can start testing every part of this script. To make things easier, you can create a custom function, and call that function from PreInvokeMethod thusly.
function Service_PreInvokeMethod (MethodName, Inputs, Outputs)
{
try {
var iReturn = CancelOperation;
switch (MethodName) {
case "ExportCommTemplate":
ExportCommTemplate(Inputs, Outputs);
break;
default:
iReturn = ContinueOperation;
break;
}
return(iReturn);
}
catch(e) {
throw(e);
}
finally { //nothing to do here, for now!
}
}
That aside, let’s focus on what needs to be done. All the logic that needs to be written will be in two functions.
The first one is ExportCommTemplate. This function will accept the following inputs:
- SearchExpr - standard Siebel SearchExpr used to query for templates
- Directory - Directory in which the template subdirectory should be created. Will default to c:\temp - note that this may be on the server
An output will be nice to ensure we are on track. So, we will have some -
- Status - message indicating status
- # Comm Templates - no. of comm templates processed
- # Comm Template Items - no. of comm template items processed
- # Errors - no. of files that errored out!
First, declare variables and prepare for the fun.
var iComExists, iComItemExists;
var sId, sName, sDisplayText, sFileStatus, sFile, sSiebelFileName, sSiebelFileExtn, sSeq;
var bcComItem;
var iComCount = 0, iComItemCount = 0, iErrCount = 0;
var sFileDelim = "^";
var oToday = new Date();
var sSearchExpr = Inputs.GetProperty("SearchExpr");
if (sSearchExpr == "") sSearchExpr = "[Id] = '1-ABC'"; //testing
var sDir = Inputs.GetProperty("Directory");
if (sDir == "") sDir = "c:\\temp";
sDir = sDir + "\\CommTemplates_" + oToday.getFullYear() + (oToday.getMonth() + 1) + oToday.getDate() + oToday.getHours();
Clib.mkdir(sDir);
We want to export all templates and store that in a directory that has a current date suffix.
The search expression helps to filter out templates that we need. If you are in doubt about how this whole thing works - introduce a blank search expression and provide the expression within the script itself. Replace the “1-ABC” with a specific row id of the template that can be tested.
Now, we just initiate the BO/BC and start the search.
var boCom = TheApplication().GetBusObject("Comm Package");
var bcCom = boCom.GetBusComp("Comm Package");
with (bcCom) {
ClearToQuery();
SetViewMode(AllView);
SetSearchExpr(sSearchExpr);
ActivateField("Name");
ActivateField("Display Template Text");
ExecuteQuery(ForwardOnly);
iComExists = FirstRecord();
}
We have the email template, and its time to get the details.
while (iComExists){
iComCount++;
sName = bcCom.GetFieldValue("Name");
sDisplayText = bcCom.GetFieldValue("Display Template Text");
sId = bcCom.GetFieldValue("Id");
if (sDisplayText != "") {
CreateFile(sDir + "\\" + sName + sFileDelim + "DisplayText.html", sDisplayText);
}
Simple email templates just have the field “Display Template Text” populated and that’s about it. But advanced templates are not that simple, they have elements in a child BC. So, if the current template is not a simple one we start collecting the details from the child BC.
else {
bcComItem = boCom.GetBusComp("Comm Package Item");
with (bcComItem){
ClearToQuery();
SetViewMode(AllView);
ActivateField("Sequence Number");
ActivateField("CommFileName");
ActivateField("CommFileExt");
ExecuteQuery(ForwardOnly);
iComItemExists = FirstRecord();
} //with (bcComItem)
while(iComItemExists){
iComItemCount++;
sSiebelFileName = bcComItem.GetFieldValue("CommFileName");
sSiebelFileExtn = bcComItem.GetFieldValue("CommFileExt");
sSeq = bcComItem.GetFieldValue("Sequence Number");
try {
sFileStatus = bcComItem.InvokeMethod("GetFile", "CommFileName");
}
catch(e) {
sFileStatus = "SevereError";
}
if (sFileStatus == "Error" || sFileStatus == "OutOfDate" || sFileStatus == "SevereError") {
iErrCount++;
CreateFile(sDir + "\\" + sName + sFileDelim + sSeq + sFileDelim + sSiebelFileName + "." + sSiebelFileExtn + sFileDelim + sFileStatus + ".txt", "[" + sFileStatus + "] Error in processing file.");
}
else {
sFile = sFileStatus.substring(sFileStatus.indexOf(",") + 1);
Clib.rename(sFile, sDir + "\\" + sName + sFileDelim + sSeq + sFileDelim + sSiebelFileName + "." + sSiebelFileExtn);
}
iComItemExists = bcComItem.NextRecord();
} //while(iComItemExists)
‘CreateFile’ function uses CLIB function to create files with the specified name and content .
Since we may want to potentially reproduce the template in another environment, we are collecting all the details that we need to recreate the email template in its pristine condition. We will output all the details needed to the file name, and if there is an import later we can just extract all that is needed for the import.
Finally, we have to close the outer loop to navigate through all the templates found for the filter criteria. Also, don’t forget to set the output parameter values to the aggregate numbers that we found here.
iComExists = bcCom.NextRecord();
} //while (iComExists)
Outputs.SetProperty("Status", "Templates exported satisfying search criteria '" + sSearchExpr + "'");
Outputs.SetProperty("# Comm Templates", iComCount);
Outputs.SetProperty("# Comm Template Items", iComItemCount);
Outputs.SetProperty("# Errors", iErrCount);
The script does look complex but is fairly simple in its doings.