Extending [Logical Users] list in Workflow

Hi guys,

Here is an example about how to call an assembly from the WF manager. This example deals with a request we had from a customer about how to extended the sendmail functionnality in order not to be limited by the [Logical User] list offered out of the box.

I have to thank Clint Warriner for his help about the logical implemention :-)

Here we go:

When you want to send an email via the Workflow manager inside your rule, you have the choice to select a particular recipient for your mails, or to choose the "Logical User" list, this list depends of the type of record you refer to.

Here is the list of "Logical User" listed for a case.

 SendMail Action in Workflow Manager

 Here is the signification of the abover "Logical User" list:

[account/contact] Sends email to the account or contact associated with the case
[account] Sends email to the associated account for this case (customer field)
[contact] Sends email to the associated contact for this case (customer field)
[owner's manager] Sends email to the associated owner's manager of this case record.
[owner] Sends email to the associated Owner of the case record.

Here is bellow to which field these Logical Users refer to (in the Case Record):

Case Record

 The problem is:

What if I want to to something esle? Like:

=> Send the email to the Logical Account (customer in the TO: Line of my Email) and its Primary Contact in CC: Line ?

This is not possible in the regular workflow interface, so you need to develop you own SendMail Workflow Assembly and call it into workflow manager.

The code will:

- retrieve the customer properties (account), search for it's "PrimaryContact" property
- based on this, an EMail activity will be created with the Account (customer) in the TO Line and its primary contact in the CC Line
- then we send the email.

[note: we check the customer is an account (OTC =1) before trying to fill the CC line, we don't handle the situation where the Customer is a contact]

It's provided as is, there is no error handling at all, you will need to add the CrmSdkHelpers.Cs file provided by the CRM 3.0 SDK to do this:

using System;
using CrmSdk;
using SendMailToPrimaryContact.crmsdk;

namespace SendMailToPrimaryContact

{

/// <summary>
/// Summary description for Class1.
/// </summary>

public class MailToCustomer

{

public void CreateMailAndSendIt(Guid guidOfCustomer, int ObjectTypeCode)

{

// create CrmService instance

CrmService csvc = InitWebSvc();

// Create New EMAIL

email e =

new email();
e.ownerid = new Owner();
e.ownerid.type = EntityName.systemuser.ToString();
e.ownerid.Value = new Guid("302A6CD7-8E63-DA11-BC4B-0003FF0D54C9"); // to simplify things, we set static owner to admin...
e.subject = "A new case has been created (mail sent by custom DLL)"; // Email Subject
e.description = "Hi All, here is a new mail to notify you that a new case has been created"; // Email Body

// create an ActivityParty matching the customer guid to fill the TO line with....
activityparty ap = new activityparty();
ap.partyid = CrmSdk.CrmTypes.CreateLookup(EntityName.account.ToString(),guidOfCustomer);

// fill the TO Field with the customer....
e.to = new activityparty[]{ap};

// fill the CC Field with the primary contact of this customer....
if(ObjectTypeCode==1)
{
e.cc = new activityparty[]{RetrievePrimaryContact(guidOfCustomer)};
}

// Actually create the mail activity.
Guid emailid = csvc.Create(e);

// Send the mail.
SendMyMail(emailid);

// release resource.
csvc.Dispose();

}

public CrmService InitWebSvc()

{

CrmService csvc = new CrmService();
csvc.Credentials = System.Net.CredentialCache.DefaultCredentials;
csvc.PreAuthenticate = true;
csvc.UnsafeAuthenticatedConnectionSharing = true;
return csvc;

}

public void SendMyMail(Guid emailid)

{

// create CrmService instance
CrmService csvc = InitWebSvc();
// Send the Email based on the EmailId provided.
SendEmailRequest req = new SendEmailRequest();
req.EmailId = emailid;
req.TrackingToken = string.Empty;
req.IssueSend = true;
SendEmailResponse res = (SendEmailResponse)csvc.Execute(req);
// release ressource.
csvc.Dispose();

}

public activityparty RetrievePrimaryContact(Guid accountid)

{

// create CrmService instance
CrmService csvc = InitWebSvc();

// Creating ActivityParty matching the PrimaryContact
ColumnSet cs = new ColumnSet();
cs.Attributes = new string[]{"primarycontactid"};
activityparty ap = new activityparty();
Guid primarycontactGUID = ((account)csvc.Retrieve(EntityName.account.ToString(),accountid,cs)).primarycontactid.Value;
ap.partyid = CrmSdk.CrmTypes.CreateLookup(EntityName.contact.ToString(),primarycontactGUID);

// release ressource.
csvc.Dispose();

return ap;

}

}

}

Compile the code in Visual Studio 2003.

Now you have an Assembly DLL called: SendMailToPrimaryContact.dll
The name of your Class is: MailToCustomer()
The main method is: CreateMailAndSendIt()

Now you need to update your Workflow.Config file to handle your freshly created DLL:

Go to C:\Program Files\Microsoft CRM\Server\bin\assembly\ and Edit the Workflow.Config file

If the assembly is unsigned, you must add the allowunsignedassemblies attribute to the <workflow.config> element at the top of the Workflow.config file. Assign a value of "true" to the allowunsignedassemblies attribute. To update the Workflow.config file, use the following code sample.

<

method name="Send Mail to Customer When Case Created"
assembly="SendMailToPrimaryContact.dll"
typename="SendMailToPrimaryContact.MailToCustomer"
methodname="CreateMailAndSendIt"
group="Send Mail"
description="benlec">
<parameter name="Customer" datatype="lookup" entityname="account"/>
<parameter name="CustomerOTC" datatype="integer" default="0"/>
<result datatype="boolean"/>
</method>

Copy now SendMailToPrimaryContact.Dll into this directory too.

Now that you're done with the Config file and your DLL, create a MANUAL workflow rule which will call this assembly when a CASE is created.

 

Call Assembly

 

Now you will need to setup the rule by specifying the 2 parameters we defined in the workflow config.

 

Here is what you have:

 

Rule Configuration 1

 

Double click on each parameter, select CustomerOTC static Value = 1, and Customer dynamic value = Account.

You should have something like this:

 

Rule Configuration 2

 

Click Save and Activate your rule.

 

Now when you create a case, and fill the customer field with your Account have a primary contact, click "More Actions" menu and apply the rule we created.

 

The Email created and sent shall look like this:

 

EMail Received

 

Hope this helps, here are some usefull things around this topic:

 

922607 How to use the Logical User fields in Microsoft Dynamics CRM 3.0 workflow rules
http://support.microsoft.com/default.aspx?scid=kb;EN-US;922607

 

Sending email via workflow as different user

http://blogs.msdn.com/crm/archive/2006/11/15/sending-email-via-workflow-as-different-user.aspx

 

Kind regards

 

Benjamin LECOQ