Verint | Telligent Community
Verint | Telligent Community
  • Site
  • User
  • Site
  • Search
  • User
Verint Community 13.x
  • Verint Community
Verint Community 13.x
Developer Training Custom Emails
  • User Documentation
  • Ask the Community
  • API Documentation
  • Manager Training
  • Developer Training
  • Tags
  • More
  • Cancel
  • New
  • Getting Started
  • +External Integration
  • +Plugins/Framework extension
  • +Automations
  • +UI Customization
  • -Notifications and Email
    • Working with Email Studio
    • -Notification Extensibility
      • Custom Notification Types
      • Custom Emails
      • Updating Legacy Emails
  • +Scripting
  • Obsolescence
  • Developer Training
  • Notifications and Email
  • Notification Extensibility

Custom Emails

Custom emails are typically a specialized form of a custom notification. While all notifications can be delivered via the email distribution type, notifications that implement IEmailNotificationType  support rendering specific strings for the email's subject, body, header, and footer. And beyond that, email notifications that implement IScriptedEmail  enable the email's definition to be customized within Email Studio .

Why Should I Create an Email Notification Type?

New email notification types are useful when you want to be more specific about how a notification is represented as email, including defining the email's subject, body, header, and footer and optionally making these components editable in Email Studio.

Creating an IEmailNotificationType that supports scripting with IScriptedEmail

Starting with the previously-created custom INotificationType, add the following interfaces: IEmailNotificationType, IScriptedEmail.

Implement these interfaces as follows:

#region IEmailNotificationType

public string Get(EmailTarget target, Notification notification)
{
	if (notification == null || notification.ExtendedAttributes == null)
		return null;

	var commentIdAttribute = notification.ExtendedAttributes.FirstOrDefault(ea => ea.Key == "TargetCommentId");
	if (commentIdAttribute == null)
		return null;

	var commentId = Guid.Parse(commentIdAttribute.Value);
	var comment = Apis.Get<IComments>().Get(commentId);
	if (comment == null)
		return null;

	var user = Apis.Get<IUsers>().Get(new UsersGetOptions { Id = notification.UserId });
	if (user == null)
		return null;

	return _scriptedEmailController.Render(target, new ScriptedEmailRenderOptions
	{
		Context = new Dictionary<string, object>
		{
			{ "Content", notification.Content },
			{ "Comment", comment }
		},
		ApplicationId = notification?.Content?.Application?.ApplicationId,
		ApplicationTypeId = notification?.Content?.Application?.ApplicationTypeId
	});
}

#endregion

#region IScriptedEmail

IScriptedEmailController _scriptedEmailController;

public Guid ScriptedEmailId => new Guid("efed29fa-e94e-41f4-b36d-74f9f1df29a0");

public void SetController(IScriptedEmailController controller) =>
	_scriptedEmailController = controller;

public IDictionary<string, Type> ContextualData => new Dictionary<string, Type>
	{
		{ "Content", typeof(Content) },
		{ "Comment", typeof(Comment) }
	};

public IDictionary<string, object> GetSampleContext() => new Dictionary<string, object>
	{
		{ "Content", null },
		{ "Comment", null }
	};

#endregion
Note the ContextualData and and the dictionary passed to Render's Context option. The dictionary passed to Render's Context option contains the contextual items made available to this email's script when it executes. ContextualData defines the types of these objects to enable $context_v1_email.Context to be accurately documented within the automatic and inline API documentation for this email. When implemented, GetSampleContext(), allows this email to contain sample defaults for these objects when rendering previews of the email.

Full plugin sample:

Fullscreen 2656.SampleNotificationTypeWithEmail.cs Download
using System;
using System.Collections.Generic;
using System.Linq;
using Telligent.Evolution.Extensibility;
using Telligent.Evolution.Extensibility.Api.Entities.Version1;
using Telligent.Evolution.Extensibility.Api.Version1;
using Telligent.Evolution.Extensibility.Content.Version1;
using Telligent.Evolution.Extensibility.Email.Version1;

namespace Samples
{
	public class SampleNotificationType : INotificationType, IEmailNotificationType, IScriptedEmail
	{
		private INotificationController _notificationController;

		#region IPlugin

		public string Name => "Sample Notification";

		public string Description => "This plugin demonstrates the INotificationType plugin type";

		public void Initialize()
		{
			Apis.Get<IComments>().Events.AfterCreate += CommentEvents_AfterCreate;
		}

		#endregion

		#region INotificationType

		public string NotificationTypeName => "Sample";

		public string NotificationTypeDescription => "Sends a sample notification.";

		public string NotificationTypeCategory => "Samples";

		public Guid NotificationTypeId => new Guid("3C0542FD-5AB0-4386-911C-86CCF530BAEE");

		public bool IsCacheable => true;

		public bool VaryCacheByUser => true;

		public bool CanDeleteNotification(Guid notificationId, int userId)
		{
			var notification = Apis.Get<INotifications>().Get(notificationId);
			return notification != null && notification.UserId == userId;
		}

		public string GetMessage(Guid notificationId, string target)
		{
			var notification = Apis.Get<INotifications>().Get(notificationId);
			if (notification == null || notification.ExtendedAttributes == null)
				return null;

			var commentIdAttribute = notification.ExtendedAttributes.FirstOrDefault(ea => ea.Key == "TargetCommentId");
			if (commentIdAttribute == null)
				return null;

			var commentId = Guid.Parse(commentIdAttribute.Value);
			var comment = Apis.Get<IComments>().Get(commentId);
			if (comment == null)
				return null;

			var user = Apis.Get<IUsers>().Get(new UsersGetOptions { Id = notification.UserId });
			if (user == null)
				return null;

			return $"The following comment was added by {user.DisplayName}: \"{comment.Body()}\"";
		}

		public string GetTargetUrl(Guid notificationId)
		{
			var notification = Apis.Get<INotifications>().Get(notificationId);
			return notification != null && notification.Content != null ? notification.Content.Url : null;
		}

		public void SetController(INotificationController controller)
		{
			_notificationController = controller;
		}

		#endregion

		private void CommentEvents_AfterCreate(CommentAfterCreateEventArgs e)
		{
			if (e == null
				|| e.Content == null
				|| e.User == null
				|| !e.IsApproved
				|| !e.Content.CreatedByUserId.HasValue
				|| e.CommentTypeId.GetValueOrDefault(Guid.Empty) != Guid.Empty)
			{
				return;
			}

			var comment = Apis.Get<IComments>().Get(e.CommentId);
			if (comment != null && comment.IsApproved)
			{
				AddNotifications(e.Content.ContentId, e.Content.ContentTypeId, e.CommentId, e.Content.CreatedByUserId.Value, e.UserId);
			}
		}

		private void AddNotifications(Guid contentId, Guid contentTypeId, Guid commentId, int contentAuthor, int actorId)
		{
			var comment = Apis.Get<IComments>().Get(commentId);
			if (comment == null)
				return;

			var attributes = new List<IExtendedAttribute>
			{
				new ExtendedAttribute { Key = "TargetCommentId", Value = comment.CommentId.ToString("N") }
			};

			_notificationController.CreateUpdate(new NotificationCreateUpdateOptions
			{
				ContentId = contentId,
				ContentTypeId = contentTypeId,
				LastUpdate = DateTime.UtcNow,
				UserId = contentAuthor,
				ActorIdToAdd = actorId,
				ExtendedAttributes = attributes
			});
		}

		#region IEmailNotificationType

		public string Get(EmailTarget target, Notification notification)
		{
			if (notification == null || notification.ExtendedAttributes == null)
				return null;

			var commentIdAttribute = notification.ExtendedAttributes.FirstOrDefault(ea => ea.Key == "TargetCommentId");
			if (commentIdAttribute == null)
				return null;

			var commentId = Guid.Parse(commentIdAttribute.Value);
			var comment = Apis.Get<IComments>().Get(commentId);
			if (comment == null)
				return null;

			var user = Apis.Get<IUsers>().Get(new UsersGetOptions { Id = notification.UserId });
			if (user == null)
				return null;

			return _scriptedEmailController.Render(target, new ScriptedEmailRenderOptions
			{
				Context = new Dictionary<string, object>
				{
					{ "Content", notification.Content },
					{ "Comment", comment }
				},
				ApplicationId = notification?.Content?.Application?.ApplicationId,
				ApplicationTypeId = notification?.Content?.Application?.ApplicationTypeId
			});
		}

		#endregion

		#region IScriptedEmail

		IScriptedEmailController _scriptedEmailController;

		public Guid ScriptedEmailId => new Guid("efed29fa-e94e-41f4-b36d-74f9f1df29a0");

		public void SetController(IScriptedEmailController controller) =>
			_scriptedEmailController = controller;

		public IDictionary<string, Type> ContextualData => new Dictionary<string, Type>
			{
				{ "Content", typeof(Content) },
				{ "Comment", typeof(Comment) }
			};

		public IDictionary<string, object> GetSampleContext() => new Dictionary<string, object>
			{
				{ "Content", null },
				{ "Comment", null }
			};

		#endregion
	}
}

Creating a matching default script implementation

Create the following file in the CFS path using the ScriptedEmailId: /filestorage/defaultemail/efed29fae94e41f4b36d74f9f1df29a0.xml. This defines the default implementation of the email script which can be customized, published, or reverted within Email Studio .

<scriptedEmail name="Sample Email" version="13.0.0.0" description="Raises notifications on comments." id="efed29fae94e41f4b36d74f9f1df29a0">
  <subjectScript language="Velocity"><![CDATA[
$context_v1_email.Context.Comment.User.DisplayName commented on $context_v1_email.Context.Content.HtmlName('Email')
  ]]></subjectScript>
  <headerScript language="Velocity"><![CDATA[
$context_v1_email.Context.Comment.User.DisplayName commented on $context_v1_email.Context.Content.HtmlName('Email')
  ]]></headerScript>
  <bodyScript language="Velocity"><![CDATA[
Comment Body: $context_v1_email.Context.Comment.Body()
  ]]></bodyScript>
  <footerScript language="Velocity" />
</scriptedEmail>

  • Created over 1 year ago
Was this helpful?
  • Yes
  • No
  • More
  • Cancel
  • Telligent
  • Professional Services
  • Submit a Support Ticket
  • Become a Partner
  • Request a Demo
  • Contact Us

About
Privacy Policy
Terms of use
Copyright 2024 Verint, Inc.
Powered by Verint Community