GoDaddy Doesn’t Like HTML

Recently I’ve had problems sending e-mail messages to some recipients. Turns out most of these (all?) use GoDaddy. Today I entered a new Lead into my CRM. My workflow automatically sent the Lead my follow up e-mail. It bounced! The Undeliverable message included this information:


smtp.secureserver.net #<smtp.secureserver.net #5.0.0 SMTP; 554 The message was rejected because it contains prohibited virus or spam content> #SMTP#


My CRM template includes links to my logos so I deleted them and tried again. Once again the message bounced with the same reason. So I tried turning the message into plain text. This time it went right through! After removing the logo links, I still had some formatting in the message, fonts and such. Going to plain text removed the formatting, resulting in an ugly message. But a message that was accepted none the less.

CRM 4.0 Accelerators and isv.config

Recently I decided it was about time that I checked out the accelerators for CRM 4.0 that have been released in the past months. You can find the accelerators at http://www.codeplex.com/crmaccelerators. There several of these. I chose the Notifications accelerator to start off with. I’ll not cover what it does, you can see that on the accelerators site. But I’ll tell you about the challenges I had installing them and how I resolved them.


The Notifications accelerator comes with an installation program. Unfortunately it hung on me and never completed. So I went to the manual method. The first parts were pretty easy, copy some files to the proper spots. The last, edit the isv.config, is where my challenge appeared.


isv.config is a file in CRM that can be modified to allow independent software vendors to create buttons and menus in CRM and plug their code in. The accelerators use this method. To access your existing isv.config, you must export it. Do so by going to Settings –> Customizations –> Export Customizations. From the list select ISV Config. Save it somewhere easy to access, like your desktop. The exported file will be in .xml format but will be packaged inside a compressed, .zip, envelope. You’ll have to extract the .xml to work on it. Make a copy of the .zip as you might want to reinstall it if you mess up the original. You can use Notepad to edit it or something more sophisticated like Visual Studio. I chose the later.


Normally the isv.config comes with some sample configurations. You can activate these in System Settings. Go to Settings –> Administration –> System Settings and go to the Customizations tab. Go to ‘Custom menus and toolbars’ and select the client (Web Application, Outlook, and/or Outlook Offline) you want. After you restart CRM, you’ll notice some new stuff, if the sample stuff is in your isv.config. In my case, the isv.config was blank. Here is what my original file looked like:


- <ImportExportXml version=”4.0.0.0” languagecode=”1033” generatedBy=”OnPremise“>


<Entities />


<Roles />


<Workflows />


<EntityMaps />


<EntityRelationships />


- <Languages>


<Language>1033</Language>


<Language>3082</Language>


</Languages>


</ImportExportXml>


 


This file is missing some very important stuff, like ISV stuff. My job was to add the isv.config info that comes with the Notifications accelerator into this isv.config so that it will load into CRM. Here is the info that comes with Notifications:


<Menu>
  <!– RSS Accelerator Menu–>
<Titles>
<Title LCID=”1033″ Text=”RSS” />
</Titles>
<MenuItem JavaScript=”var sFolder = ‘{#subfolder#}';
if (top.stage.crmGrid == null)
{
window.showModalDialog(‘/’ + ORG_UNIQUE_NAME + ‘/isv/’ + sFolder + ‘/rss.aspx’,”,’dialogHeight:150px;dialogWidth:400px;status:no;resizable:yes’);
}
else
{
var sViewId = top.stage.crmGrid.GetParameter(‘viewid’);
var sViewType = top.stage.crmGrid.GetParameter(‘viewtype’);
var sOtc = top.stage.crmGrid.GetParameter(‘otc’);
var sUrl;
if(sOtc == ‘4200’ || sOtc == ‘9100’ || sOtc == ‘4406’ || sOtc == ‘4703’ || sOtc == ‘4700’ || sOtc == ‘4410’ || sOtc == ‘2029’ || sOtc == ‘127’)
{
window.showModalDialog(‘/’ + ORG_UNIQUE_NAME + ‘/isv/’ + sFolder + ‘/rss.aspx’,”,’dialogHeight:150px;dialogWidth:400px;status:no;resizable:yes’);
}
else
{
switch(sViewType)
{
case ‘1039’:
sUrl = ‘/’ + ORG_UNIQUE_NAME + ‘/isv/’ + sFolder + ‘/rssdata.aspx?q=’+sViewId;
break;
case ‘4230’:
sUrl = ‘/’ + ORG_UNIQUE_NAME + ‘/isv/’ + sFolder + ‘/rssdata.aspx?u=’+sViewId;
break;
}
window.open(sUrl);
}
}”>
<Titles>
<Title LCID=”1033″ Text=”Subscribe to Current View” />
</Titles>
</MenuItem>
<MenuItem JavaScript=”var sFolder='{#subfolder#}'; window.showModalDialog(‘/’ + ORG_UNIQUE_NAME + ‘/isv/’ + sFolder + ‘/rss.aspx’,”,’dialogHeight:150px;dialogWidth:400px;status:no;resizable:yes’);”>
<Titles>
<Title LCID=”1033″ Text=”Choose Subscription…” />
</Titles>
</MenuItem>
</Menu>


In order to plug this into our isv.config file, we have to add some other stuff. Took me awhile to figure all that out as I haven’t done much ISV configuring. First we have to add an <IsvConfig> header with opposing </IsvConfig> and some other sections. To make a long story short, here is what I came up with as my final isv.config file:


<ImportExportXml version=”4.0.0.0″ languagecode=”1033″ generatedBy=”OnPremise”>
  <Entities>
  </Entities>
  <Roles>
  </Roles>
  <Workflows>
  </Workflows>
  <IsvConfig>
    <configuration version=”3.0.0000.0″>
      <Root>
        <MenuBar>
          <CustomMenus>
            <Menu>
        <!– RSS Accelerator Menu–>
          <Titles>
            <Title LCID=”1033″ Text=”RSS” />
          </Titles>
          <MenuItem JavaScript=”var sFolder = ‘RSS';
            if (top.stage.crmGrid == null)
            {
            window.showModalDialog(‘/’ + ORG_UNIQUE_NAME + ‘/isv/’ + sFolder + ‘/rss.aspx’,”,’dialogHeight:150px;dialogWidth:400px;status:no;resizable:yes’);
            }
            else
            {
            var sViewId = top.stage.crmGrid.GetParameter(‘viewid’);
            var sViewType = top.stage.crmGrid.GetParameter(‘viewtype’);
            var sOtc = top.stage.crmGrid.GetParameter(‘otc’);
            var sUrl;
            if(sOtc == ‘4200’ || sOtc == ‘9100’ || sOtc == ‘4406’ || sOtc == ‘4703’ || sOtc == ‘4700’ || sOtc == ‘4410’ || sOtc == ‘2029’ || sOtc == ‘127’)
            {
            window.showModalDialog(‘/’ + ORG_UNIQUE_NAME + ‘/isv/’ + sFolder + ‘/rss.aspx’,”,’dialogHeight:150px;dialogWidth:400px;status:no;resizable:yes’);
            }
            else
            {
            switch(sViewType)
            {
            case ‘1039’:
            sUrl = ‘/’ + ORG_UNIQUE_NAME + ‘/isv/’ + sFolder + ‘/rssdata.aspx?q=’+sViewId;
            break;
            case ‘4230’:
            sUrl = ‘/’ + ORG_UNIQUE_NAME + ‘/isv/’ + sFolder + ‘/rssdata.aspx?u=’+sViewId;
            break;
            }
            window.open(sUrl);
            }
            }”>
            <Titles>
              <Title LCID=”1033″ Text=”Subscribe to Current View” />
            </Titles>
          </MenuItem>
          <MenuItem JavaScript=”var sFolder=’RSS'; window.showModalDialog(‘/’ + ORG_UNIQUE_NAME + ‘/isv/’ + sFolder + ‘/rss.aspx’,”,’dialogHeight:150px;dialogWidth:400px;status:no;resizable:yes’);”>
            <Titles>
              <Title LCID=”1033″ Text=”Choose Subscription…” />
            </Titles>
          </MenuItem>
        </Menu> 
          </CustomMenus>
        </MenuBar>
      </Root>
    </configuration>
  </IsvConfig>
  <EntityMaps />
  <EntityRelationships />
  <Languages>
    <Language>1033</Language>
    <Language>3082</Language>
  </Languages>
</ImportExportXml>


Other sections that needed to be added were <Configuration version=3.0.0000.0>, <Root>, <MenuBar>, and <CustomMenus> before the Notifications code. Then the closing items for each in reverse order.


Once the file is complete, put the .xml back into a .zip file and use the Import Customizations to import it back into CRM. You will have to restart CRM, or press F5, for it to take effect.


One other thing. When I tried to run the RSS menu item in my newly config’d CRM, I got a 404 error. I tracked that down to an error in the code. Note in the original code the line:


<MenuItem JavaScript=”var sFolder = ‘{#subfolder#}‘;


Note the #subfolders# item. This is not defined anywhere so replace it with the appropriate value, which in this case is ‘RSS’. This item appears twice in the Notifications code. This cured my 404 error and the Notifications accelerator now works as advertised on my CRM system.


Have fun!