Using templates to do auto-signatures in client side javascript

WARNING — unsupported CRM hacking below!

A client wanted signatures to be inserted automatically in emails sent from CRM. I wanted to use the built-in template-feature, but the button on the email form launches a modal dialog which makes it hard to script. I was just about to give up and do a callout, when my manager suggested eavesdropping on the dialog to see what it did to merge the template. Wireshark showing web service call

Wireshark revealed that no postback is involved, the dialog merely calls an undocumented web service called /AppWebServices/EmailTemplateService.asmx. The service has an operation called GetInstantiatedEmailTemplate (see pic) which returns a bunch of XML. Not wanting to deal with this myself, I poked around in the email-form source and found that Microsoft has been kind enough to provide a function that’ll insert the result of the template instantiation for you. It’s called InsertValue() and resides on the crmForm.all.description element.

GetInstantiatedEmailTemplate web service

While this method is obviously unsupported, I’m reliably informed that the web services in /AppWebServices are also to be found in Titan.

Here’s the code in all it’s glory, note that JavaScript SOAP Client is used for the web service call.

var template_url = 'http://foo/AppWebServices/EmailTemplateService.asmx';
var soap_js = IncludeJsByDom('http://foo/js/soapclient.js');
soap_js.attachEvent("onreadystatechange", check_load);
function Get_Text()
{
    var params = new SOAPClientParameters();
    params.add("templateId", '{5623E3DE-1175-DC11-A465-001B78E16CCE}');
    params.add("objectId", crmForm.all.to.DataValue[0].id);
    params.add("objectTypeCode", 2);
    SOAPClient.invoke(
        template_url,
        "GetInstantiatedEmailTemplate",
        params,
        true,
        Template_Callback);
}
function Template_Callback(vol){
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.loadXML(vol);
var body = xmlDoc.getElementsByTagName("body");
crmForm.all.description.InsertValue(body.item(0).text);
}
var check_load = function()
{
    if (event.srcElement.readyState == 'loaded'
    || event.srcElement.readyState == 'complete')
    {
        Get_Text();
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *