Thursday, August 28, 2008

Invoking MS CRM from other applications

The Active Directory security model of MS CRM is amazingly flexible and allows  powerful control inside of CRM, but when integrating with systems outside of CRM, AD security really shines.

One of the great things about AD security is that your users do not have to log into CRM after they are logged into a domain on their computers. This means that third party programs can just call into CRM with web services to get information as they need it. Reporting services written against the filtered views only show CRM users what they are allowed to see and CRM forms can be pulled up whenever it is convenient.

CRM from Links
Since CRM is a web application ANY entity form can be opened directly from Internet Explorer. Below is an example link to a specific contact.

http://crmserver1:5555/MicrosoftCRM/sfa/conts/edit.aspx?id={DE1F590A-37D0-DC11-AA32-0003FF33509E}#

Application: Directly accessing a CRM entity can be really handy for email messages generated from CRM, as you can send an email to the appropriate person with a link to an an entity requiring attention and even send instructions telling them what to do with it once they click on the link. In this way users require less training and have faster access to the information they need.

Implementation Details: Just create one mail group in exchange for each of the applicable types of mail they you need ( ie. CRMerrors, CRMmaint, CRMreports, etc... ). This way IT can administrate who gets the email without touching the CRM servers. Mail relaying from the CRM server to the Exchange Server will need to be set up first. Scheduled status emails with links for additional information could be routed to CRMreports, all your exceptions could be sent to CRMerrors, and anything that a business rule picks up on during the running of a plugin can email CRMmaint with a link to the entity in question with an explanation of what needs to be addressed. This can be useful with marginal data that is imported from another system and needs some massaging, or anything else that is flagged by internal business rules requiring decisions.

Hint: If you need a link for an specific entity, but that part of explorer is hidden, type <CTRL>N and a new fully functional browser will show up that you can cut a URL from or use other tools like the Web Accessibility Toolbar to examine the markup.

CRM from the command line
From the command line you can also open that page which could be useful for batch files.

C:\ @start "" /b "iexplore.exe"http://crmserver1:5555/MicrosoftCRM/sfa/conts/edit.aspx?id={DE1F590A-37D0-DC11-AA32-0003FF33509E}#

CRM from another application
Another application can automatically pop an entity up on the screen whenever some trigger occurs.

// Get contactID from information passed to auto dialer client
string contactId = "{DE1F590A-37D0-DC11-AA32-0003FF33509E}";

var proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName="iexplore";
proc.StartInfo.Arguments = String.Format("http://crmserver1:5555/MicrosoftCRM/sfa/conts/edit.aspx?id={0}#", contactId);
proc.Start();
Application: Most auto dialers have a client that is customizable to do "screen pops" or to open a specific application when a call is connected to their phone. Ideally CRM has the marketing list stored and is generating the auto dialer lists that include some unique information like a Lead or Contact Guid, or at a bare minimum some unique information that can be queried against in CRM. Now your call center person can immediate do things related to that contact without having to look that contact up or even log into CRM, or by using CRM web services a related entity like an opportunity or a campaign could be popped instead.

Implementation details: If CRM is generating your auto dialer lists then make sure to include the appropriate guid of the entity that you want to pop with the data sent to the client. If your auto dialer is fed from another source, you might want to re-examine that. CRM imports leads from many sources very easily and creating auto dialer data from a Campaign associated with a given marketing list works very well. Then you want to make sure that your auto dialer client also tracks the results from a call so that you can use web services to create a Campaign Response record in CRM to track how successful your Campaign was.

Sunday, August 24, 2008

Mashups in CRM (Part 2)

For part 2 we are going to create an iframe with a web application in it that gives your user a visual representation of where their package is using a Google Gadget called packagetrackr . There is also another gadget called CPS Parcel Locator that will pop up an external screen similar to what was generated in part 1.

Normally I recommend that all custom web applications run from a web site separate from the CRM web site. However for this example I will just create a folder CustomWebPages off of the main CRM web site \Program Files\Microsoft Dynamics CRM Server\CRMWeb.

1. Visit the packagetrackr website, customize to taste and copy their generated script to embed their gadget in your web page. You should end up with something like the following in your copy buffer.

<script src="http://www.gmodules.com/ig/ifr?url=http://www.packagetrackr.com/gadgets/google/packagetrackr.xml&amp;synd=open&amp;w=320&amp;h=350&amp;title=Track+Packages+in+CRM&amp;border=%23ffffff%7C3px%2C1px+solid+%23999999&amp;output=js"></script>

2. Create a web page PageTracker.html in the CustomWebPages folder that calls the script that the packagetrackr generates as shown below.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>PackageTracker</title>
</head>
<body>
<script src="http://www.gmodules.com/ig/ifr?url=http://www.packagetrackr.com/gadgets/google/packagetrackr.xml&amp;synd=open&amp;w=320&amp;h=350&amp;title=Track+Packages+in+CRM&amp;border=%23ffffff%7C3px%2C1px+solid+%23999999&amp;output=js" type="text/javascript"></script>
</body>
</html>

3. Create a new section and iframe that points to the new web page /CustomWebPages/PackageTracker.html, and set the formatting to automatically expand to use available space. You should end up with something like the following.

mashupIframe

This is not completely integrated and still requires user interaction. It would be nice if we could set the Tracking ID automatically which was my original intent. I tried with both packagetrackr and the following CPS Parcel Locator gadget, unfortunately they have blocked access to the inner iframe where their text input for the tracking number goes. What I can demonstrate is how to reference values on your CRM form from the web page running in an iframe. If your web page is running from another website you will need to enable cross site scripting on your iframe to make this work. Add the code below to your web page. This code will run in an iframe and then reference the parent document for your entity's form. From there it retrieves the Tracking Number attribute's value and pops up an alert. This example invokes with the onclick of the body, so you can just click in the iframe and it will show you the current tracking number on the form.

<script type="text/javascript"> 
 function GetNumber()
 {
    var trackingnumber = parent.document.getElementById("new_trackingnumber");    
    
    alert("tracking number " + trackingnumber.value);
 }
</script>

<body onclick="javascript:GetNumber();">
What you should see is something like this. I did cut and past the tracking number into the gadget to generate the map below.

map

Wednesday, August 20, 2008

Mashups in CRM (Part 1)

Mashups in CRM are powerful and can be very easy to implement. There is so much data in a typical CRM system that can offer more user value when mashed up with other web sites and web applications. In this post I'll show how to create a simple mashup taking some data in CRM and adding it into a URL to provide your end users with some functionality and time savings. In (Part 2) I will show something a little more advanced using a Google Gadget in an iframe.

If you are storing Shippers and Tracking numbers in CRM you have everything you need to give your users a tracking link. Below is an example that will generate tracking links to UPS, FEDEX and DHL.

  1. Create a text field with a Tracking Number in it new_trackingnumber.
  2. Create a picklist telling you which type of shipping is being used new_shippedby. Add UPS, FEDEX and DHL to the picklist
  3. Create a link field for the user to click on new_trackinglink.
  4. Add JavaScript (below) to the OnLoad event for your Form to builds the links for your new_trackinglink below:
var Shipper = crmForm.all.new_shippedby.value;
var trackingNumber = crmForm.all.new_trackingnumber.value;

switch( Shipper )
{
   case "1": /*UPS*/ crmForm.all.new_trackinglink.DataValue='http://wwwapps.ups.com/WebTracking/processRequest?HTMLVersion=5.0&Requester=NES&AgreeToTermsAndConditions=yes&loc=en_US&tracknum=' + trackingNumber ;  
             break;

   case "2": /*FEDEX*/ crmForm.all.new_trackinglink.value =  'http://www.fedex.com/Tracking?tracknumbers=' + trackingNumber + '&cntry_code=us&language=english&clienttype=ivother&' 
             break;

   case "3": /*DHL*/ crmForm.all.new_trackinglink.value =  'http://track.dhl-usa.com/TrackByNbr.asp?shipmentNumber=' + trackingNumber ;
             break;
}
Hint: You really don't want lots of copies of the same code. You can reference an existing OnLoad, OnSave event from the same form as follows: crmForm_onload0(); crmForm_onsave0(); So in this case you would add "crmForm_onload0();" to the OnChange event for both shippedby and trackingnumber so that the trackinglink would regenerate whenever you changed either of those fields. Here is your final result, a populated link specific to the shipper: mashup1

Sunday, August 17, 2008

MS CRM and WF books

I've been working on a non-CRM application that will use WF for complex scheduled activities with lots of dependencies and notifications. Basically there are a lot of sequential workflow's with external method handlers and decision trees that run after external events occur. The end user will be able to configure their workflow's through the application's UI and generate XML that the workflow runtime can consume.  This is basically how MS CRM 4.0 and SharePoint 2007 use WF.  If you are just starting on WF, Kenn Scribner's book "Windows Workflow Foundation, Step by Step" is pretty good. It comes with a PDF version of the book on a CD with code samples from all of the chapters. It covers a lot, but not everything and sometimes a Google search will find a better explanation about how some things work. I like the way Kenn described WF in terms of being kind of like an application level Biztalk.

I've also been reading through Dave Yank's new book, CRM as a Rapid Development Platform which just became available electronically on August 11th. What is interesting is that there are things that I haven't explored yet with workflow's in CRM, like creating custom activities in VS2008 to use in CRM.  Dave wrote this book with a developer in mind and provides some very interesting and useful source code that I believe most people who are already familiar with developing in CRM would benefit from. There really isn't a lot of overlap with Mike Snyder and Jim Steger's, Working with Dyanamics CRM 4.0 which tries to cover everything from basic concepts and system administration to development basics. BTW one of the perks of going to TechEd or Convergence is a copy of this book. To earn this book you need to go to a Sonoma Partner's presentation or spend some time talking with the right person about CRM in exhibition hall.

Wednesday, August 6, 2008

MS CRM 3.0 and 4.0 JavaScript Report Tool

The ability to put JavaScript into a CRM form is a powerful tool. Unfortunately it can be hard to manage the all of the JavaScript code which is embedded in the customization.xml file, so I created a program that applies an XSLT against the customization.xml file to create an html report page with all of the JavaScript extracted and presented entity by entity and by event and field.

jsReport.zip

After downloading this zip file simply copy the jsReport.exe and jsReport.xslt files into a directory and run jsReport.exe.

javascripttool2.jpg

You need to browse to a CRM customizations.xml file that you want it to translate. By default it will use the XSLT that is provided, but you can pick another if you want to customize the XSLT to better fit your needs.

The Header of the current generated html report is the following:

javascripttoolreport2.jpg

Note: MS has a lot of JavaScript in the customizations.xml file besides what you have written. Their code has a LOT of leading whitespace which unfortunately makes this report very wide. You may also notice that events that are not supported in the CRM Entity Forms Editor are also included.