Using the DeliverIncomingEmail Message

On March 31, 2010, in Development, Dynamics CRM, Email, by Mitch Milam

Every now and again, you find an absolute gem within the CRM SDK.  And I’m not talking about a diamond-in-the-rough, I’m talking about a bright, shiny, put it in a ring kind.

The DeliverIncomingEmail message is one of those gems.  Let’s take a look:

 

What does it do?

First and foremost, it takes information that exists within an email message that you retrieved from somewhere and creates a CRM Email Activity. This process could be a custom application you wrote, or in my case, a Simple Email Router.  Regardless of where the email comes from, this message will do all of the heavy lifting required to create the Email Activity.

 

Usage:

DeliverIncomingEmailRequest request = new DeliverIncomingEmailRequest
{
    Subject = subject,
    From = from,
    To = to,
    Cc = cc,
    Bcc = bcc,
    MessageId = Guid.NewGuid().ToString(),
    ReceivedOn = CrmTypes.CreateCrmDateTimeFromUser(timeReceived),
    Body = body,
    SubmittedBy = to,
    Importance = "Normal",
    Attachments = new BusinessEntityCollection()
};

request.Attachments.EntityName = EntityName.activitymimeattachment.ToString();
request.Attachments.BusinessEntities.Add(new activitymimeattachment());

 

How It Works

You complete the parameters of the message with information from the inbound email; things like To, From, Subject, Body, etc. the use the CrmService.Execute method to deliver the mail.  That’s it.

 

Caveats

MessageId is a Guid that can be either the ID of the message or a new Guid you supply.

Attachments are required, even if you don’t have attachments.  In the example above, we have created a BusinessEntityCollection to hold our attachments, but never actually added any.  This will keep the Message from failing to process.

To, Cc, Bcc can contain multiple email addresses that are separated by a comma ( , ).

 

So why is this such a big deal?

Did you notice that we are only supplying the email addresses of the people involved in the conversation?  When CRM processes this message, it will perform an automatic lookup and attempt to associate people with those email addresses.

This is actually one of the few messages within the CRM SDK that doesn’t require an ID to perform a lookup or an association and saves you, the developer, a tremendous amount of time and effort.

 
 

Yes, I said Email Router.  And no, I’m mostly not crazy – I just had a very specific need to fulfill and I didn’t wish to install the standard CRM Email Router to solve a problem.

A Bit of Background

In the next few weeks, sometime before Convergence 2010, I’ll be launching a new online training service for CRM users.  This is a totally Online-based solution using the Microsoft Online stack including:

  • CRM Online
  • Business Productivity Online Suite ( BPOS )
  • Windows Azure

The only drawback to using CRM Online is you must install the CRM Email Router on a computer somewhere to move email into and out of CRM Online.  Since I wanted everything in a data center not run by me, I decided to spend a little time and effort to create a very simplistic replacement for the Email Router.

 

Email Router Architecture

At its heart, the Email Router really only does two things:

  1. Check CRM for unsent messages, sending any it finds
  2. Check a mailbox for new messages, retrieving and inserting into CRM any it finds

That didn’t seem to be too hard of a process to replicate especially since, in all reality, I only had one CRM user to monitor.

 

Software Components

To help me send and receive email, I selected the Chilkat Email .NET Component.  It’s quite affordable and has a whole host of useful features.

Everything else was written using the CRM SDK.

The code resides inside a Windows Azure Worker Role and I poll CRM and the Exchange Online mailbox a few times a minute ( again, this is not a high-production environment ).

 

Sending Email

So how do you determine what email needs to get sent?  It’s pretty simple actually:  You just query the Email entity and look for emails with a statuscode attribute for a value of 6, which is PendingSend.

Again, I don’t have complicated requirements so I’m only interested in retrieving the TO, Subject, and Description from the email.  If my needs develop, I can always add additional functionality to handle scenarios like:

  • Multiple recipients
  • Attachments
  • Multiple users ( From address )

Once I have collected all of the emails to be sent, I connect to Exchange Online, send the emails, then set the status of the email to Sent

Receiving Email

Collecting incoming email is a very similar process.  Here’s how it works:

  1. I connect to my Exchange Online mailbox using POP3 and retrieve all of the unread email.
  2. Looping through each email, I use the SDK method, DeliverIncomingEmailRequest, to actually deliver the email to CRM.
  3. After successful delivery, I delete the email from the Exchange Online mailbox.

Conclusion

Well, that’s about it.  Like I mentioned numerous times: my needs were very simplistic, but as you can see, it’s not rocket science, and the process can be enhanced and extended to suit your needs.

 

In the previous article we discussed how to use workflow to move activities between queues.

We noticed and issue last week related to how the users were actually processing the activities that would result in the workflow failing.

It turns out the users were changing the value of the picklist we use to move activities between queues and also closing the activity as completed.  This caused the workflow to fire because of the change in the picklist but since the activity was already closed, the workflow failed because it tried to update a closed record.

To prevent this occurrence from happening, we need to insert a bit of code at the beginning of the workflow to check the activity status:

image

So when we start the workflow, we check the status of the activity ( a fax in this case ) and if it is either Completed or Canceled, then we stop the workflow with a status of Completed.

This will prevent the workflow from attempting to update a closed activity.

 

The CRM E2 team has released two complementary documents, a white paper and a build guide, related to Sharing Data across Microsoft Dynamics CRM Deployments.

  • The white paper provides an overview of the levels of integration available for sharing data across multiple Dynamics CRM organizations, together with details about the techniques that are used for integration at the Application and Data levels, which include Web Services, Web Services-based solutions, Filtered Views, and SQL Server Replication.
  • The build guide explains how to configure the Microsoft Dynamics CRM 4.0 April 2009 VPC base image to enable data sharing between a Publisher organization and multiple Subscriber organizations. The configuration demonstrates how to use Microsoft Dynamics CRM to maintain referential integrity between multiple organizations by leveraging Microsoft SQL Server 2008 transactional replication.

Overview

While using a single CRM instance is probably the simplest way to accommodate the data sharing needs within an organization, using multiple instances of Dynamics CRM may be preferable in a number of scenarios. This release includes two documents, a white paper and a build guide, focused on sharing data across multiple CRM organizations.

The white paper provides an overview of the levels of integration available for sharing data across multiple Dynamics CRM organizations, together with details about the techniques that are used for integration at the Application and Data levels, which include Web Services, Web Services-based solutions, Filtered Views, and SQL Server Replication.

The build guide explains how to configure the Microsoft Dynamics CRM 4.0 April 2009 VPC base image to enable data sharing between a Publisher organization and multiple Subscriber organizations. The configuration demonstrates how to use Microsoft Dynamics CRM to maintain referential integrity between multiple organizations by leveraging Microsoft SQL Server 2008 transactional replication

Get it here.

 

Increasing CRM Developer Productivity

On March 6, 2010, in Development, Dynamics CRM, by Mitch Milam

Every now and then I find a solution to a problem that I didn’t know I had.  Yesterday was a perfect example.

I spend most of my day inside Visual Studio either writing C# or JavaScript.  I also use several tools to help me work with CRM.  Usually what happens is I open Windows Explorer, navigate to my Utilities folder and launch whatever tool I need. 

Yesterday it occurred to me that I was wasting my time.

Visual Studio has a feature on the Tools menu called External Tools:

image

It allows you to add your own tools so that you can launch them without ever leaving Visual Studio.  Simple, I know, but it just never occurred to me to use this feature until I had launched Stunnware Tools for like the one millionth time.

Here is the configuration for Stunnware Tools:

image

And my very own Export JavaScript utility:

image

Now I can launch these two tools without ever leaving Visual Studio.  A small productivity enhancement, but an enhancement nonetheless.