private void HandleNonCustomAction(IPluginExecutionContext context, ITracingService tracing, IOrganizationService service) { var target = context.InputParameters.ContainsKey("Target") ? context.InputParameters["Target"] as Entity : null; if (target == null) { return; } var targetField = _config.TargetField; var template = _config.Template; var templateField = _config.TemplateField; var dataSource = GenerateDataSource(context, target); if (!CheckExecutionCriteria(_config, dataSource, service, tracing)) { tracing.Trace("Execution criteria not met, aborting"); return; } ValidateConfig(targetField, template, templateField); var templateText = RetrieveTemplate(template, templateField, dataSource, service, tracing); if (string.IsNullOrEmpty(templateText)) { tracing.Trace("Template is empty, aborting"); return; } var output = TokenMatcher.ProcessTokens(templateText, dataSource, _organizationConfig, service, tracing); target[targetField] = output; TriggerUpdateConditionally(output, dataSource, _config, service); }
public void Execute(IServiceProvider serviceProvider) { var context = serviceProvider.GetService(typeof(IPluginExecutionContext)) as IPluginExecutionContext; var crmTracing = serviceProvider.GetService(typeof(ITracingService)) as ITracingService; var serviceFactory = serviceProvider.GetService(typeof(IOrganizationServiceFactory)) as IOrganizationServiceFactory; var service = serviceFactory.CreateOrganizationService(context.UserId); var target = GetTarget(context); var targetRef = GetTargetRef(context); if (target == null && targetRef == null) { return; } var shouldExecute = CheckExecutionCondition(target, service, crmTracing); if (!shouldExecute) { crmTracing.Trace("Execution condition not met, aborting"); return; } var attributes = target != null ? target.Attributes.Keys.ToList() : null; var filteredAttributes = config.Value.CapturedFields != null ? attributes.Where(a => config.Value.CapturedFields.Any(f => string.Equals(a, f, StringComparison.InvariantCultureIgnoreCase))).ToList() : attributes; var eventData = new EventData { UpdatedFields = filteredAttributes, EventRecordReference = target?.ToEntityReference() ?? targetRef }; var eventTarget = string.IsNullOrEmpty(config.Value.ParentLookupName) && eventData.EventRecordReference.Id != Guid.Empty ? eventData.EventRecordReference : GetValue <EntityReference>(config.Value.ParentLookupName, target, context.PreEntityImages); if (eventTarget == null) { crmTracing.Trace("Failed to find parent, exiting"); return; } var subscriptionsQuery = service.Query("oss_subscription") .Where(e => e .Attribute(a => a .Named(config.Value.SubscriptionLookupName) .Is(ConditionOperator.Equal) .To(eventTarget.Id) ) .Attribute(a => a .Named("statecode") .Is(ConditionOperator.Equal) .To(0) ) ) .IncludeColumns("ownerid", "oss_emailnotificationsenabled", "oss_emailnotificationssender") .Link(l => l .FromEntity("oss_subscription") .ToEntity("systemuser") .FromAttribute("ownerid") .ToAttribute("systemuserid") .With.LinkType(JoinOperator.LeftOuter) .Link(l2 => l2 .FromEntity("systemuser") .ToEntity("usersettings") .FromAttribute("systemuserid") .ToAttribute("systemuserid") .With.LinkType(JoinOperator.LeftOuter) .With.Alias("usersettings") .IncludeColumns("localeid") ) ); if (!config.Value.NotifyCurrentUser) { subscriptionsQuery.AddCondition( (a => a .Named("ownerid") .Is(ConditionOperator.NotEqual) .To(context.UserId) ) ); } var subscriptions = subscriptionsQuery.RetrieveAll(); var serializedNotification = JsonSerializer.Serialize(eventData); var eventType = GetEventType(context); var messageConfig = config.Value.MessageConfig ?? new Dictionary <string, string>(); var messages = subscriptions.Select(s => s.GetAttributeValue <AliasedValue>("usersettings.localeid")?.Value as int?) .Select(locale => locale != null ? locale.Value.ToString() : "default") .Distinct() .ToDictionary( (k) => k, (k) => messageConfig.ContainsKey(k) ? TokenMatcher.ProcessTokens(messageConfig[k], target, new OrganizationConfig(), service, crmTracing) : (messageConfig.ContainsKey("default") ? TokenMatcher.ProcessTokens(messageConfig["default"], target, new OrganizationConfig(), service, crmTracing) : null) ); subscriptions.ForEach(subscription => { var localeCode = subscription.GetAttributeValue <AliasedValue>("usersettings.localeid")?.Value as int?; var locale = localeCode != null ? localeCode.Value.ToString() : "default"; var message = messages.ContainsKey(locale) ? messages[locale] : null; var user = subscription.GetAttributeValue <EntityReference>("ownerid"); var notification = new Entity { LogicalName = "oss_notification", Attributes = { ["oss_subscriptionid"] = subscription.ToEntityReference(), ["ownerid"] = user, ["oss_event"] = new OptionSetValue((int)eventType), [config.Value.NotificationLookupName] = eventTarget, ["oss_data"] = serializedNotification, ["oss_text"] = message } }; if (config.Value.GlobalNotificationConfig != null) { var messageKey = config.Value.GlobalNotificationConfig.Keys.FirstOrDefault(k => k == locale) ?? config.Value.GlobalNotificationConfig.Keys.FirstOrDefault(k => k == "default"); if (messageKey != null) { var notificationMessage = config.Value.GlobalNotificationConfig[messageKey]; var payload = new GlobalNotificationActionPayload { EntityName = eventTarget?.LogicalName, Message = notificationMessage }; notification["oss_globalnotificationactionpayload"] = JsonSerializer.Serialize(payload); } } notification.Id = service.Create(notification); var emailNotificationsEnabled = subscription.GetAttributeValue <bool>("oss_emailnotificationsenabled"); if (!emailNotificationsEnabled) { return; } SendEmailNotification(message, locale, user, subscription, notification, service); }); }
private void HandleCustomAction(IPluginExecutionContext context, PersistentTracingService tracing, IOrganizationService service) { var config = ProcessorConfig.Parse(context.InputParameters["jsonInput"] as string); if (config.Target == null && config.TargetEntity == null) { throw new InvalidPluginExecutionException("Target property inside JSON parameters is needed for custom actions"); } ColumnSet columnSet; if (config.TargetColumns != null) { columnSet = new ColumnSet(config.TargetColumns); } else { columnSet = new ColumnSet(true); } try { var dataSource = config.TargetEntity != null ? config.TargetEntity : service.Retrieve(config.Target.LogicalName, config.Target.Id, columnSet); if (!CheckExecutionCriteria(config, dataSource, service, tracing)) { tracing.Trace("Execution criteria not met, aborting"); var abortResult = new ProcessingResult { Success = true, Result = config.Template, TraceLog = tracing.TraceLog }; context.OutputParameters["jsonOutput"] = SerializeResult(abortResult); return; } var templateText = RetrieveTemplate(config.Template, config.TemplateField, dataSource, service, tracing); if (string.IsNullOrEmpty(templateText)) { tracing.Trace("Template is empty, aborting"); return; } var output = TokenMatcher.ProcessTokens(templateText, dataSource, new OrganizationConfig { OrganizationUrl = config.OrganizationUrl }, service, tracing); var result = new ProcessingResult { Success = true, Result = output, TraceLog = tracing.TraceLog }; context.OutputParameters["jsonOutput"] = SerializeResult(result); TriggerUpdateConditionally(output, dataSource, config, service); } catch (Exception ex) { var result = new ProcessingResult { Success = false, Error = ex.Message, TraceLog = tracing.TraceLog }; context.OutputParameters["jsonOutput"] = SerializeResult(result); if (config.ThrowOnCustomActionError) { throw; } } }