There was a requirement in project to send email to all Team members of a certain Queue, whenever a new item is added to that Queue.
To achieve this requirement, I have developed custom workflow so that configuration can be done from the Dynamics Workflow interface / window.
Below is Dynamics Workflow screen
For Beginners: Solution -> Processes -> Create New Process as workflow
This is code:
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Workflow;
using System;
using System.Activities;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MT.Workflow.SendEmailTeam
{
public class SendEmailTeam : CodeActivity
{
[Input("Email Template")]
[RequiredArgument]
[ReferenceTarget("template")]
public InArgument<EntityReference> EmailTemplate { get; set; }
[Input("From User")]
[RequiredArgument]
[ReferenceTarget("systemuser")]
public InArgument<EntityReference> EmailSender { get; set; }
[Input("To Team")]
[RequiredArgument]
[ReferenceTarget("team")]
public InArgument<EntityReference> ToTeam { get; set; }
[Input("Case")]
[RequiredArgument]
[ReferenceTarget("incident")]
public InArgument<EntityReference> Case { get; set; }
protected override void Execute(CodeActivityContext executionContext)
{
string DebugDesc = " Started...";
// Create the tracing service
ITracingService tracingService = executionContext.GetExtension<ITracingService>();
if (tracingService == null)
{
throw new InvalidPluginExecutionException("Failed to retrieve tracing service.");
}
// Create the context
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
if (context == null)
{
throw new InvalidPluginExecutionException("Failed to retrieve workflow context.");
}
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
IOrganizationService privService = serviceFactory.CreateOrganizationService(null);
EntityReference _EmailTemplate = EmailTemplate.Get(executionContext);
EntityReference _EmailSender = EmailSender.Get(executionContext);
EntityReference _ToTeam = ToTeam.Get(executionContext);
EntityReference _Case = Case.Get(executionContext);
var TeamMembers = new List<Guid>();
var IsTeam = true;
if (IsTeam) {
TeamMembers = GetTeamMembers(service, _ToTeam.Id.ToString());
Entity email = new Entity("email");
email.Attributes["directioncode"] = true;
Entity FromActivityParty = new Entity("activityparty");
FromActivityParty.Attributes["partyid"] = _EmailSender;
email["from"] = FromActivityParty;
foreach (Guid userid in TeamMembers) {
Entity ToActivityParty = new Entity("activityparty");
ToActivityParty["partyid"] = new EntityReference("systemuser", userid);
EntityCollection EntCol = new EntityCollection();
EntCol.Entities.Add(ToActivityParty);
EntCol.EntityName = ToActivityParty.LogicalName;
email["to"] = EntCol;
}
SendEmailFromTemplateRequest EmailTemplateReq = new SendEmailFromTemplateRequest
{
Target = email,
TemplateId = _EmailTemplate.Id,
RegardingId = _Case.Id,
RegardingType = "incident"
};
service.Execute(EmailTemplateReq);
}
}
public List<Guid> GetTeamMembers(IOrganizationService service, string TeamId)
{
var UserIds = new List<Guid>();
// Id of the specific Team
Guid teamId = new Guid(TeamId);
// main query returing users
QueryExpression userQuery = new QueryExpression("systemuser");
// take all columns
userQuery.ColumnSet = new ColumnSet(true);
// this is the intersect condition
LinkEntity teamLink = new LinkEntity("systemuser", "teammembership", "systemuserid", "systemuserid", JoinOperator.Inner);
// this is the condition to use the specific Team
ConditionExpression teamCondition = new ConditionExpression("teamid", ConditionOperator.Equal, teamId);
// add the condition to the intersect
teamLink.LinkCriteria.AddCondition(teamCondition);
// add the intersect to the query
userQuery.LinkEntities.Add(teamLink);
//get the results
EntityCollection retrievedUsers = service.RetrieveMultiple(userQuery);
// fetch the results
foreach (Entity user in retrievedUsers.Entities)
{
// Id of the user
var userId = user.Id;
UserIds.Add(userId);
}
return UserIds;
}
}
}
For Beginners: Create New project in visual studio as class library, Build Project, sign it, Open Plugin Registration Toll and register the dll.
㉺㉼㉴㉳㉽㉾㈕㈔㈆㈅㈄㈄㈃㈁㈀㉤ Ali Hamza Wadood Microsoft Dynamics CRM Developer | Software Engineer - Microsoft Technologies(Asp.Net, Asp.Net MVC) LinkedIn
To achieve this requirement, I have developed custom workflow so that configuration can be done from the Dynamics Workflow interface / window.
Below is Dynamics Workflow screen
For Beginners: Solution -> Processes -> Create New Process as workflow
This is code:
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Workflow;
using System;
using System.Activities;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MT.Workflow.SendEmailTeam
{
public class SendEmailTeam : CodeActivity
{
[Input("Email Template")]
[RequiredArgument]
[ReferenceTarget("template")]
public InArgument<EntityReference> EmailTemplate { get; set; }
[Input("From User")]
[RequiredArgument]
[ReferenceTarget("systemuser")]
public InArgument<EntityReference> EmailSender { get; set; }
[Input("To Team")]
[RequiredArgument]
[ReferenceTarget("team")]
public InArgument<EntityReference> ToTeam { get; set; }
[Input("Case")]
[RequiredArgument]
[ReferenceTarget("incident")]
public InArgument<EntityReference> Case { get; set; }
protected override void Execute(CodeActivityContext executionContext)
{
string DebugDesc = " Started...";
// Create the tracing service
ITracingService tracingService = executionContext.GetExtension<ITracingService>();
if (tracingService == null)
{
throw new InvalidPluginExecutionException("Failed to retrieve tracing service.");
}
// Create the context
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
if (context == null)
{
throw new InvalidPluginExecutionException("Failed to retrieve workflow context.");
}
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
IOrganizationService privService = serviceFactory.CreateOrganizationService(null);
EntityReference _EmailTemplate = EmailTemplate.Get(executionContext);
EntityReference _EmailSender = EmailSender.Get(executionContext);
EntityReference _ToTeam = ToTeam.Get(executionContext);
EntityReference _Case = Case.Get(executionContext);
var TeamMembers = new List<Guid>();
var IsTeam = true;
if (IsTeam) {
TeamMembers = GetTeamMembers(service, _ToTeam.Id.ToString());
Entity email = new Entity("email");
email.Attributes["directioncode"] = true;
Entity FromActivityParty = new Entity("activityparty");
FromActivityParty.Attributes["partyid"] = _EmailSender;
email["from"] = FromActivityParty;
foreach (Guid userid in TeamMembers) {
Entity ToActivityParty = new Entity("activityparty");
ToActivityParty["partyid"] = new EntityReference("systemuser", userid);
EntityCollection EntCol = new EntityCollection();
EntCol.Entities.Add(ToActivityParty);
EntCol.EntityName = ToActivityParty.LogicalName;
email["to"] = EntCol;
}
SendEmailFromTemplateRequest EmailTemplateReq = new SendEmailFromTemplateRequest
{
Target = email,
TemplateId = _EmailTemplate.Id,
RegardingId = _Case.Id,
RegardingType = "incident"
};
service.Execute(EmailTemplateReq);
}
}
public List<Guid> GetTeamMembers(IOrganizationService service, string TeamId)
{
var UserIds = new List<Guid>();
// Id of the specific Team
Guid teamId = new Guid(TeamId);
// main query returing users
QueryExpression userQuery = new QueryExpression("systemuser");
// take all columns
userQuery.ColumnSet = new ColumnSet(true);
// this is the intersect condition
LinkEntity teamLink = new LinkEntity("systemuser", "teammembership", "systemuserid", "systemuserid", JoinOperator.Inner);
// this is the condition to use the specific Team
ConditionExpression teamCondition = new ConditionExpression("teamid", ConditionOperator.Equal, teamId);
// add the condition to the intersect
teamLink.LinkCriteria.AddCondition(teamCondition);
// add the intersect to the query
userQuery.LinkEntities.Add(teamLink);
//get the results
EntityCollection retrievedUsers = service.RetrieveMultiple(userQuery);
// fetch the results
foreach (Entity user in retrievedUsers.Entities)
{
// Id of the user
var userId = user.Id;
UserIds.Add(userId);
}
return UserIds;
}
}
}
For Beginners: Create New project in visual studio as class library, Build Project, sign it, Open Plugin Registration Toll and register the dll.
㉺㉼㉴㉳㉽㉾㈕㈔㈆㈅㈄㈄㈃㈁㈀㉤ Ali Hamza Wadood Microsoft Dynamics CRM Developer | Software Engineer - Microsoft Technologies(Asp.Net, Asp.Net MVC) LinkedIn