Thursday 1 December 2016

How to send email notification to all members of a team in Dynamics CRM

How to send email notification to all members of a team in Dynamics CRM


Recently this requirement came where we have to notify all the team members of a team, which [team] was the owner of a queue.

I checked and found that there isn't any straight forward OOB feature provided by Microsoft to do the same.

So i decided to implement this using some code and action process.

Here is what was the scenario:-

There is a team named "Sales Team" and a queue named  "Sales Team Queue".

"Sales Tea Queue" is the default queue of  "Sales Team" and  "Sales Team" was the owner of the "Sales Team Queue".


Sales team queue as the default queue of sales team:

Sales team as the owner of sales team queue:


So what does it means?

It means that the emails which are sent on the email address of the Sales Team Queue, Sales Team  will be the owner of all those emails.


So how does it matter?

It does and it does a lot.

What it does is that it give us the capability of managing Just Sales Team members and by adding and removing the members in Sales Team you can change who got the notification email and who not.


So how does we design it?

Now we also want to give the administrator freedom of changing the from email address and the notification text  without changing any code.

What we did to achieve the above requirement is:

1. We write a plugin on create of email and check whether the owner is some team.

2. If it is a team then fetch all the Members of the team.

3. We create an action process in Dynamics crm as shown below:



Create an email(don't send) and return the reference of created email in output parameter:



Below is how we have created the email to send:

Here is how we returned the reference of created email to the output parameters:



Now the steps is : Register the plugin on create event of email in asynchronous mode.

Why in asynchronous mode?

Just to be on safe side. I have observed that if we write some synchronous logic on create even of email and in any case the logic/code breaks in any condition, it might affect the creation of email.i.e. may be the incoming email might stop.

So it's better to make this step asynchronous.

Below is the code snippet of the plugin:

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public void Execute(IServiceProvider serviceProvider)
        {
            List<Entity> _toList = new List<Entity>();
        #region Setup
        IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationService service = ((IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory))).CreateOrganizationService(new Guid?(context.UserId));
            ITracingService tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            #endregion
            tracing.Trace("0.0");
            if ((context.InputParameters.Contains("Target")) && (context.InputParameters["Target"] is Entity) & context.Depth < 3 )
            {
                #region codearea
                try
                {
                    NotificationtoUsers obj = new NotificationtoUsers(); //NotificationtoUsers  is my Class name
                    tracing.Trace("0.1");
                    Entity Activity = service.Retrieve(context.PrimaryEntityName, context.PrimaryEntityId, new ColumnSet(true));
                    tracing.Trace("1");
                    EntityReference Owner = Activity.GetAttributeValue<EntityReference>("ownerid");
                    if (Owner.LogicalName == "team")
                    {
                        EntityCollection toPartyColl = new EntityCollection();
                        EntityCollection TeamMembers = obj.GetAllTeamUsers(service, Owner.Id);
                        Console.WriteLine("TeamMembers Count" + TeamMembers.Entities.Count);
                        foreach (Entity User in TeamMembers.Entities)
                        {

                            Entity entityUser = new Entity("activityparty");
                            entityUser.Attributes["partyid"] = (object)new EntityReference("systemuser", (Guid)User.GetAttributeValue<Guid>("systemuserid"));
                            if (!Enumerable.Any<Entity>((IEnumerable<Entity>)_toList, (Func<Entity, bool>)(t => ((EntityReference)t.GetAttributeValue<EntityReference>("partyid")).Id == (Guid)User.GetAttributeValue<Guid>("systemuserid"))))
                            {
                                _toList.Add(entityUser);

                            }
                        }


                        StringBuilder std = new StringBuilder();
                        std.Append("https://statictrial6.crm.dynamics.com"); //Write your own crm url here
                        std.Append("/main.aspx?etn=");
                        std.Append(Activity.LogicalName);
                        std.Append("&pagetype=entityrecord&id=%7B");
                        std.Append(Activity.Id.ToString());
                        std.Append("%7D");
                        String ClickHere = "Click Here to Open the Email";
                        String url = std.ToString();
                        String EmailLink = " <a href= '" + url + "'>'" + ClickHere + "'</a>";

//Make a request to get the action
                        OrganizationRequest orgRequest = new OrganizationRequest("new_emailtousers");
                        //Passing the dynamic link of email crated as a parameter to action
orgRequest["link"] = EmailLink;
                        OrganizationResponse orgResponse = (OrganizationResponse)service.Execute(orgRequest);
                        if (orgResponse.Results != null)
                        {
                            //Get the email reference from action which is returned from action
                            EntityReference emailRef = (EntityReference)orgResponse.Results["email"];
                            if (emailRef.Id != Guid.Empty)
                            {
                                Entity email = service.Retrieve(emailRef.LogicalName, emailRef.Id, new ColumnSet("to", "from"));
                                if (email.Id != Guid.Empty)
                                {
                                    obj.SendEmailAction(email, service, _toList);
                                }
                            }
                        }


                    }
                }
                catch (Exception ex)
                {
                    throw new Exception("Error occured" + ex.Message);
                }
                #endregion
            }
        }

        private void SendEmailAction(Entity email, IOrganizationService service, List<Entity> toList)
        {

            try
            {
                email["to"] = toList.ToArray();
                service.Update(email);
                SendEmailRequest sendEmailreq = new SendEmailRequest
                {
                    EmailId = email.Id,
                    TrackingToken = "",
                    IssueSend = true
                };
                SendEmailResponse sendEmailresp = (SendEmailResponse)service.Execute(sendEmailreq);
            }
            catch (Exception ex)
            {
                Console.WriteLine("" + ex.Message);
            }
       }
        private  EntityCollection GetAllTeamUsers(IOrganizationService _CrmService, Guid TeamID)
        {
            //Create query expression
            QueryExpression _Query = new QueryExpression();
            _Query.EntityName = "systemuser";
            _Query.ColumnSet = new ColumnSet(true);
            //_Query.ColumnSet.AddColumn("systemuserid");
            _Query.LinkEntities.Add(new LinkEntity
            {
                LinkFromEntityName = "systemuser",
                LinkToEntityName = "teammembership",
                LinkFromAttributeName = "systemuserid",
                LinkToAttributeName = "systemuserid",
                LinkCriteria =
                        new FilterExpression
                        {
                            Conditions ={
                            new ConditionExpression("teamid",ConditionOperator.Equal,TeamID)
                                        }
                        }
            });
            return _CrmService.RetrieveMultiple(_Query);
        }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Below is the email all Team Member received:



Hope this was helpful.

You can utilize the above implementation as per your requirement.

Happy Learning..!!!


2 comments:

  1. Its a custom code activity (class should inherit CustomActivity Interface) , not the plugin. Your code has missed out some classes eg. NotificationtoUsers, SendEmailRequest,SendEmailResponse. Please update your code so that people can take benefits of your knowledge you shared here. Thanks

    ReplyDelete
  2. Could you provide this as a github repository?

    ReplyDelete