3

Functionally, I can see that we can configure email addresses to be notified when Translation Manager jobs are sent per the documentation.

However, the example in the Sites 9.1 documentation mentions the ErrorEmailNotificationsPlugin.cs sample plugin.

Is this C# example following the old Translation Manager plugin approach?

If not, is there a different example for the Event System? Before recommending possible customization I want to be sure we're following the newer API (Event System for Translation Manager rather than plugin approach). :-)

2 Answers 2

2

Customer should use Event System approach. Old Translation Manager Plugin system is deprecated for many years.

using System;
using System.IO;
using System.Net.Mail;
using System.Web;
using System.Xml;

using Tridion.ContentManager.Extensibility;
using Tridion.TranslationManager.V2;
using Tridion.TranslationManager.V2.EventSystem.Events;

namespace Examples.V1
{
    [TcmExtension("TranslationManagerExamples.ErrorEmailNotifications")]
    public class ErrorEmailNotifications : TcmExtension
    {
        private const string TemplateFolderPath = "[Path to email template file]";
        private const string SmtpSendAddress = "[Smtp send address]";
        private const string SmtpReplyAddress = "[Smtp reply address]";
        private const string SmtpServerUrl = "[Smtp server url]";
        private const int SmtpPort = 25;
        private const int SmtpConnectionTimeoutSeconds = 20;
        private const string SmtpUserName = "[Smtp user name]";
        private const string SmtpPassword = "[Smtp user password]";

        public ErrorEmailNotifications()
        {
            // Subscribe on TranslationJob error event
            EventSystem.Subscribe<ITranslationJob, IErrorEventArgs>(OnTranslationJobError, EventPhases.Initiated, EventSubscriptionOrder.Normal);
        }

        private void OnTranslationJobError(ITranslationJob job, IErrorEventArgs e, EventPhases phase)
        {
            try
            {
                if (!SendEmailNotification(job, e))
                {
                    return;
                }

                // Read template values
                string templateFile = Path.Combine(TemplateFolderPath, "ErrorEmailTemplate.xml");
                string subject = null;
                string body = null;
                string emailAddress = null;
                bool isText = true;
                if (File.Exists(templateFile))
                {
                    XmlDocument template = new XmlDocument();
                    template.Load(templateFile);
                    XmlNode emailAddressNode = template.SelectSingleNode("//email");
                    if (emailAddressNode != null)
                    {
                        emailAddress = emailAddressNode.InnerText;
                    }
                    if (string.IsNullOrEmpty(emailAddress))
                    {
                        job.TmSession.Log(false, "Unable to send error notification emails, the email address is not defined");
                        return;
                    }
                    XmlNode subjectElement = template.SelectSingleNode("//subject");
                    if (subjectElement != null)
                    {
                        subject = subjectElement.InnerText;
                    }
                    isText = template.DocumentElement.GetAttribute("type") == "text";
                    XmlNode bodyElement = template.SelectSingleNode("//body");
                    if (bodyElement != null)
                    {
                        body = ReplacePlaceholders(bodyElement.InnerText, e, isText);
                    }
                }
                // Default values if missing from the template
                if (string.IsNullOrEmpty(subject))
                {
                    subject = "Translation error notification";
                }
                if (string.IsNullOrEmpty(body))
                {
                    isText = true;
                    body = e.ErrorDetails.ExceptionDetails.ToString();
                }
                MailMessage mailMessage = new MailMessage(SmtpSendAddress, emailAddress, subject, body);
                mailMessage.IsBodyHtml = !isText;
                mailMessage.ReplyToList.Add(new MailAddress(SmtpReplyAddress));

                job.TmSession.Log(false, "Sending error notification email to: " + emailAddress);
                SmtpClient smtpClient = GetSmtpClient();
                smtpClient.Send(mailMessage);
            }
            catch (Exception ex)
            {
                job.TmSession.Log(ex);
            }
        }

        private string ReplacePlaceholders(string source, IErrorEventArgs e, bool isText)
        {
            string result = source;
            var exceptionDetails = e.ErrorDetails.ExceptionDetails;

            result = ReplacePlaceholder(result, "_exceptionMessage", exceptionDetails.Message, string.Empty, isText);
            result = ReplacePlaceholder(result, "_exceptionDetails", exceptionDetails.ToString(), string.Empty, isText);
            result = ReplacePlaceholder(result, "_jobId", e.ErrorDetails.JobId.ToString(), "n/a", isText);
            result = ReplacePlaceholder(result, "_jobTitle", e.ErrorDetails.JobTitle, "n/a", isText);
            result = ReplacePlaceholder(result, "_tmsJobId", e.ErrorDetails.TmsJobId, "n/a", isText);
            result = ReplacePlaceholder(result, "_tcmItemCurrentTargetTitle", e.ErrorDetails.TcmItemCurrentTargetTitle, "n/a", isText);
            result = ReplacePlaceholder(result, "_tcmItemNewTargetTitle", e.ErrorDetails.TcmItemNewTargetTitle, "n/a", isText);
            result = ReplacePlaceholder(result, "_tcmItemSourceTitle", e.ErrorDetails.TcmItemSourceTitle, "n/a", isText);
            result = ReplacePlaceholder(result, "_tcmItemSourceUri", e.ErrorDetails.TcmItemSourceUri, "n/a", isText);
            result = ReplacePlaceholder(result, "_tcmItemTargetUri", e.ErrorDetails.TcmItemTargetUri, "n/a", isText);
            result = ReplacePlaceholder(result, "_tmsItemId", e.ErrorDetails.TmsItemId, "n/a", isText);
            result = ReplacePlaceholder(result, "_targetLanguageId", e.ErrorDetails.TargetLanguageId, "n/a", isText);
            return result;
        }

        private string ReplacePlaceholder(string source, string key, string value, string defaultValue, bool isText)
        {
            if (string.IsNullOrEmpty(value))
            {
                value = defaultValue;
            }
            if (!isText)
            {
                value = HttpUtility.HtmlEncode(value);
            }
            return source.Replace("<" + key + "/>", value);
        }

        private bool SendEmailNotification(ITranslationJob job, IErrorEventArgs e)
        {
            if (e.ErrorDetails.Severity != ErrorSeverity.Error)
            {
                // Only send email for critical problems
                return false;
            }

            if (job.Id == 0)
            {
                // The error is not related to a specific Translation Job, but is a more general failure. It
                // could for example happen if the connection to TMS is down.
                return false;
            }
            return true;
        }

        private SmtpClient GetSmtpClient()
        {
            SmtpClient smtpClient = new SmtpClient(SmtpServerUrl, SmtpPort);
            smtpClient.UseDefaultCredentials = false;
            smtpClient.Timeout = SmtpConnectionTimeoutSeconds * 1000;

            // Set credentials if needed
            // The SmtpClient will query the mail server for NTLM support and use it if present
            // (uncomment next line if you need to set credentials)
            
            //smtpClient.Credentials = new NetworkCredential(SmtpUserName, SmtpPassword);

            return smtpClient;
        }
    }
}
2

I think the documentation needs updating. Looking in the Installation Media, theres now an EventHandlers folder with a ErrorEmailNotifications.cs file which using the Event System and not the old plug-in approach.

[TcmExtension("TranslationManagerExamples.ErrorEmailNotifications")]
public class ErrorEmailNotifications : TcmExtension
{
    private const string TemplateFolderPath = "[Path to email template file]";
    private const string SmtpSendAddress = "[Smtp send address]";
    private const string SmtpReplyAddress = "[Smtp reply address]";
    private const string SmtpServerUrl = "[Smtp server url]";
    private const int SmtpPort = 25;
    private const int SmtpConnectionTimeoutSeconds = 20;
    private const string SmtpUserName = "[Smtp user name]";
    private const string SmtpPassword = "[Smtp user password]";

    public ErrorEmailNotifications()
    {
        // Subscribe on TranslationJob error event
        EventSystem.Subscribe<ITranslationJob, IErrorEventArgs>(OnTranslationJobError, EventPhases.Initiated, EventSubscriptionOrder.Normal);
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.