CRM 2011: Removing Email from queue

Last year I blogged about this on CRM 4.0 but since last few months lots of users queried about similar solution for CRM 2011. This blog entry hopefully will provide solution for this.

Well solution logic is same as CRM 4.0, we will create custom workflow which will take email id and source queue id as input parameter and then custom will removed this email from relevant queue.

I have done following are steps to achieve this in CRM 2011.

Step 1:
Create new VS studio project and add necessary reference (i.e. Microsoft.Xrm.Sdk , Microsoft.Xrm.Sdk.Workflow etc.). for more information on how to create custom workflow activity for 2011 refer following article
http://technet.microsoft.com/en-us/library/gg328515.aspx

Step 2 :
Add new class called RemoveEmail.cs and I have provided full source code for this class at end of this article. (or it can be downloaded from http://snipt.org/xoGi)

Step 3 :
Register custom workflow assembly on 2011 dynamics server using Plug in Registration Tool.
for more information on how to register custom workflow activity for 2011 refer following article http://technet.microsoft.com/en-us/library/gg328515.aspx

Step 4:
following screen print of on demand workflow I have created for this in CRM 2011 for testing purpose.

That’s it, Done. if you need more information or got any more queries regarding this please drop comment below.
Hope this helps..

Cheers,
MayankP:)

Source Code


using System;
using System.Activities;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Discovery;
using Microsoft.Xrm.Sdk.Client;

namespace CRM2011WorkflowUtilities
{
public class RemoveEmail : CodeActivity
{
protected override void Execute(CodeActivityContext executionContext)
{
try
{
//Create the context and tracing service
IExecutionContext context = executionContext.GetExtension();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
ITracingService tracer = executionContext.GetExtension();

EntityReference incomingEmail = activityId.Get(executionContext);
string emailID = incomingEmail.Id.ToString();

EntityReference incomingQueue = queueId.Get(executionContext);
string queueID = incomingQueue.Id.ToString();

//Get the QueueItemID
Guid queueItemId = GetQueueItem(service,emailID,queueID);

//delete relevant queue item record and it will remmoved email from queue
if (queueItemId != Guid.Empty)
{
service.Delete("queueitem", queueItemId);
}
}
catch (Exception ex)
{
Helpers.Throw(String.Format("An error occurred in the {0} plug-in.",
this.GetType().ToString()),
ex);
}

return;
}

///

/// Retrieve Queue Item for this email and queue
///

///
///
///
///
private Guid GetQueueItem(IOrganizationService service,string emailGUID,string QueueGUID)
{
Guid queueItemId = Guid.Empty;

// Share the same access rights as the user, so we must retrieve the user's access rights to the record
QueryExpression qe = new QueryExpression();
qe.EntityName = "queueitem";
qe.ColumnSet = new ColumnSet();
qe.ColumnSet.AllColumns = true;

FilterExpression filter = new FilterExpression();

ConditionExpression hasEmailId = new ConditionExpression();
hasEmailId.AttributeName = "objectid";
hasEmailId.Operator = ConditionOperator.Equal;
hasEmailId.Values.Add(emailGUID) ;

ConditionExpression hasQueueId = new ConditionExpression();
hasQueueId.AttributeName = "queueid";
hasQueueId.Operator = ConditionOperator.Equal;
hasQueueId.Values.Add(QueueGUID);

filter.Conditions.Add(hasEmailId);
filter.Conditions.Add(hasQueueId);

qe.Criteria = filter;

EntityCollection ec = service.RetrieveMultiple(qe);

if (ec != null && ec.Entities.Count > 0)
{
queueItemId = ec.Entities[0].Id;
}

return queueItemId;

}

#region Input Parameters

[RequiredArgument]
[Input("Source Email Id")]
[ReferenceTarget("email")]
public InArgument activityId { get; set; }

[Input("queue Id")]
[ReferenceTarget("queue")]
public InArgument queueId { get; set; }

#endregion

#region Output Parameters

#endregion
}
}

Advertisements

23 thoughts on “CRM 2011: Removing Email from queue

  1. Silla Mulandi

    Greetings, thanks for all your work. i am having issues with registering the plug-in. i keep getting no plugins selected dialogue box. am i not building the project correctly? kindly advise.

    Reply
      1. Silla Mulandi

        greetings. thanks for the response. am using an on-premise version. the code builds successfully. the issue is when i load the assembly into the registration tool. it loads but when i click on register selected plugin, the dialog box appears saying “no plugins have been selected….”

      2. mayankp Post author

        when you load the assembly , make sure you select the relevant class..
        see below link for this

        if your class is selected then try none option isolation mode and also try to register using disk option.

        hope this helps..

    1. mayankp Post author

      can you please confirm passed Queue and Email Id is correct? I guess you are getting while retrieve queue item becuase either queue id or emailid is not passed correctly..

      Reply
  2. jfletchster

    I have tried following your guide, however i have got stuck at the build stage.
    using System.Runtime.Serialization; needed to be added to remove 1 error.
    Microsoft Visual Studio is reporting 6 errors, that will prevent the build from happening:
    3 x The type arguments for method ‘System.Activites.ActivityContext.Get.Extension()’ cannot be inferred from the usage. Try Specifiying the type arguments explicity.
    Line 20,21,23
    2 x Cannot implicitly convert type ‘object’ to ‘Microsoft.Xrm.Sdk.EntityReference’. An Explict conversion exists (are you missing a cast?)
    1 x The name ‘Helpers’ does not exist in the current context

    I copied the code from the website direclty yo visual studio and added the one line mentioned above. I followed your guide and read in full the microsoft info from Technet and I am sure something is missing.
    Due to these errors when i press debugg it comes up saying it cant debugg as there is no .dll file in the bin\debug folder.

    Your help with this would be greatly apreciated.

    Reply
    1. mayankp Post author

      you can comment out helper line..that is onlu used to display exception..

      for other error you just need to add relevant assemblies from CRM 2011 SDK and it should complile ok after these changes…
      if still error please let me know..

      Reply
      1. jfletchster

        Thanks for taking the time to reply.
        I have downloaded and added all the references as shown in the Microsoft guide, when you add them all the other errors in the script are removed. So it must be something in the code that VS is identifying. I have SP1 installed of VS2010.
        All the errors lie in the var = executionContext.GetExtension() lines. The other errors on the page are due to these 3 lines.
        Thanks again

  3. RB

    Hi, in our situation, we will convert some emails in the queue to cases and others not. Does this remove all emails from a queue or only those that have a case as ‘set regarding’?

    Reply
  4. mayankp Post author

    Hi RB,
    you can do this as per your requirement, personally I guess it is better to remove only emails which are converted in to case, so in your workflow which converts email to case when case is created successfully , use this module to remove email otherwise not..

    hope this helps..

    Reply
  5. Marcelle Jacobs

    “I have tried following your guide, however i have got stuck at the build stage.
    using System.Runtime.Serialization; needed to be added to remove 1 error.
    Microsoft Visual Studio is reporting 6 errors, that will prevent the build from happening:
    3 x The type arguments for method ‘System.Activites.ActivityContext.Get.Extension()’ cannot be inferred from the usage. Try Specifiying the type arguments explicity.
    Line 20,21,23
    2 x Cannot implicitly convert type ‘object’ to ‘Microsoft.Xrm.Sdk.EntityReference’. An Explict conversion exists (are you missing a cast?)
    1 x The name ‘Helpers’ does not exist in the current context

    I copied the code from the website direclty yo visual studio and added the one line mentioned above. I followed your guide and read in full the microsoft info from Technet and I am sure something is missing.
    Due to these errors when i press debugg it comes up saying it cant debugg as there is no .dll file in the bin\debug folder.

    Your help with this would be greatly apreciated.”

    I got the same errors what reference did you add to fix this?

    Reply
  6. Marcelle Jacobs

    Thanks for the quick reply. I did add them, I get the following error “The type arguments for method ‘System.Activities.ActivityContext.GetExtension()’ cannot be inferred from the usage. Try specifying the type arguments explicitly.” on all the …..execution.Context.GetExtension();

    😦

    Reply
  7. mayankp Post author

    can you please check project target framework? and confirm it’s set to .net framework 4.0?

    you can check this by right clicking on project name -> properties and then check application tab..

    see if this resolves the issue..

    Reply
  8. Rayan

    Thanks for the code. Just to let everyone know that you must add a reference to the “System.Runtime.Serialization”.

    On my computer the file is located here:

    C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Runtime.Serialization.dll

    Reply
  9. Marcelle Jacobs

    Yes it is set to .Net Framework 4.0, and I do have System.Runtime.Serilization. I know I’m missing something small but can’t pin point it. I went over the blog 100 times. Did step by step from Microsoft site on how to create Custom Workflow, still stuck.

    Reply
  10. Ido Deutch

    To fix error: “The type arguments for method ‘System.Activities.ActivityContext.GetExtension()’ cannot be inferred from the usage. Try specifying the type arguments explicitly.” on all the …..execution.Context.GetExtension();

    Change :

    IExecutionContext context = executionContext.GetExtension();
    IOrganizationServiceFactory serviceFactory = executionContext.GetExtension();
    IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
    ITracingService tracer = executionContext.GetExtension();

    Into:

    IExecutionContext context = executionContext.GetExtension();
    IOrganizationServiceFactory serviceFactory = executionContext.GetExtension();
    IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
    ITracingService tracer = executionContext.GetExtension();

    Reply
    1. Ido Deutch

      Sorry , Change the above code into:

      IExecutionContext context = executionContext.GetExtension();

      IOrganizationServiceFactory serviceFactory = executionContext.GetExtension();

      IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

      ITracingService tracer = executionContext.GetExtension();

      Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s