简体   繁体   中英

CRM 2011 update incident when email arrives

In CRM when emails arrive and have the tracking token in them they automatically set the regarding field to be the incident (or whatever they relate to)

Unfortunately the Record wall isn't updated with this info so even if you are following the case nothing alerts you to the new activity.

I want to write a plugin on email or incident (or both) that updates the record wall and creates a task to follow up on that email with in 3 days.

I'm looking at the SDK and I can't see what the appropriate event in the pipe line would be to work out when an email is/has its regarding field set on arrival in the CRM.

The CRM email creation life-cycle is not well described in the documentation. [ shakes fist ]

Extra things that are bothering me

I can't seem to include a reference to get a strongly typed Email, Post or Case (driving me crazy)

Testing this is really hard (harder than it should be)

EDIT Here is my current code

namespace Assembly.Plugins
{
using System;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

/// <summary>
/// PostEmailDeliverIncoming Plugin.
/// </summary>    
public class PostEmailDeliverIncoming : Plugin
{
    /// <summary>
    /// Initializes a new instance of the <see cref="PostEmailDeliverIncoming"/> class.
    /// </summary>
    public PostEmailDeliverIncoming()
        : base(typeof(PostEmailDeliverIncoming))
    {
        RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>(40, "DeliverIncoming", "email", ExecutePostEmailDeliverIncoming));

        // Note : you can register for more events here if this plugin is not specific to an individual entity and message combination.
        // You may also need to update your RegisterFile.crmregister plug-in registration file to reflect any change.
    }


    protected void ExecutePostEmailDeliverIncoming(LocalPluginContext localContext)
    {
        if (localContext == null)
        {
            throw new ArgumentNullException("localContext");
        }

        //Extract the tracing service for use in debugging sandboxed plug-ins.
        ITracingService tracingService = localContext.TracingService;

        // Obtain the execution context from the service provider.
        IPluginExecutionContext context = localContext.PluginExecutionContext;

        // Obtain the organization service reference.
        var service = localContext.OrganizationService;

             // The InputParameters collection contains all the data passed in the message request.
        if (!context.InputParameters.Contains("Target") || !(context.InputParameters["Target"] is Entity)) 
            return;

        // Obtain the target entity from the input parmameters.
        var target = (Entity)context.InputParameters["Target"];

        // Verify that the target entity represents an account.
        // If not, this plug-in was not registered correctly.
        if (target.LogicalName != "email")
            return;

        if((string)target["direction"] != "Incoming")
            return;

        if (target["regardingobjectid"] == null)
            return;

        try
        {
            // if its not a case I don't care
            var incident = service.Retrieve("incident", (Guid)target["regardingobjectid"], new ColumnSet(true));
            if (incident == null) 
                return;

            var post = new Entity("post");

            post["regardingobjectid"] = target["regardingobjectid"];

            post["source"]=new OptionSetValue(0);
            post["text"] = String.Format("a new email has arrived.");

            // Create the task in Microsoft Dynamics CRM.
            tracingService.Trace("FollowupPlugin: Creating the post.");
            service.Create(post);


            // Create a task activity to follow up with the account customer in 7 days. 
            var followup = new Entity("task");

            followup["subject"] = "Follow up incoming email.";
            followup["description"] = "An email arrived that was assigned to a case please follow it up.";
            followup["scheduledstart"] = DateTime.Now.AddDays(3);
            followup["scheduledend"] = DateTime.Now.AddDays(3);
            followup["category"] = context.PrimaryEntityName;

            // Refer to the email in the task activity.
            if (context.OutputParameters.Contains("id"))
            {
                var regardingobjectid = new Guid(context.OutputParameters["id"].ToString());
                followup["regardingobjectid"] = new EntityReference("email", regardingobjectid);
            }

            // Create the task in Microsoft Dynamics CRM.
            tracingService.Trace("FollowupPlugin: Creating the task activity.");
            service.Create(followup);
        }
        catch (FaultException<OrganizationServiceFault> ex)
        {
            throw new InvalidPluginExecutionException("An error occurred in the FollupupPlugin plug-in.", ex);
        }
        catch (Exception ex)
        {
            tracingService.Trace("FollowupPlugin: {0}", ex.ToString());
            throw;
        }
    }
}
}

I've just been fighting with this exact same issue and came across this post. I thought I'd post the solution for you (if you still need it) and anyone else who comes across the issue in the future.

Here's the solution I arrived at: - Using the Plugin Registration Tool register a New Image on the appropriate step( Stage = "40", MessageName = "DeliverIncoming") - Set the New Image to be a Post Image - In your plugin fetch the Post Image's entity ID:

Guid emailID = context.PostEntityImages["PostImage"].Id;
Entity emailFromRetrieve = localContext.OrganizationService.Retrieve(
    "email",
    emailID,
    new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
Email email = emailFromRetrieve.ToEntity<Email>();

if (email.RegardingObjectId == null)
{
    return;
}

var regardingObject = email.RegardingObjectId;

Hope this helps!

I'm actually working on a very similar plugin at the moment. Mine creates a custom entity upon arrival of an email addressed to a certain email address. It also associates the incoming email with that new record via the Regarding field. I've added a Pre-Operation step on Create of Email and it works great, including incoming email from the router.

What I'm not sure of is when CRM fills in the Regarding field. You might look at Post-Operation and see if it is set there?

One interesting caveat regarding the Regarding field (haha!): Unlike single lookup fields, the Regarding object's name is actually stored in the ActivityPointer table, so when you update the Regarding field, be sure to set the Name on the EntityReference. If you don't, the Regarding lookup will still have a clickable icon but there won't be any text. I do it like this:

        email.RegardingObjectId = [yourentity].ToEntityReference();
        email.RegardingObjectId.Name = email.Subject;

Hope that helps!

I ended up doing this in a workflow on the email entity

Steps

  1. Create new workflow, I called it 'incoming email workflow'
  2. Scope is Organisation
  3. Choose Email as the entity and check 'Record field changes'
  4. Add a step that checks Regarding (Case):Case Contains Data

if true:

  1. Add a step that creates a Post
  2. Edit the properties in the Post

    • Text : This case has had {Direction(E-mail)} email activity from {From(E-mail)}
    • Source : Auto Post
    • Regarding : {Regarding(E-mail)}
  3. Add a step that creates a Task

  4. Edit the properties in the Task
    • Subject : Follow up {Subject(E-mail)}
    • Regarding : {Regarding(E-mail)}

Try to use the following code:

if ((bool)entity["directioncode"] == false)

Instead of your code:

if((string)target["direction"] != "Incoming")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM