This probably isn't the most pretty email that you've seen … thankfully, umbraco allows us to override the HTML template!HTML and plain-text email copy can be found in the (slightly hidden) Umbraco language files:\Umbraco\Config\Lang

Each file here represents a different culture which the Umbraco backend supports. The backend can be displayed in each of these cultures (this setting is user specific).Depending on your user's setting please find en.xml / en_us.xml files and modify settings for following keys: mailBody, mailBodyHtml, mailSubject

Note: it's easy to test email sending by modifying your development web.config for all SmtpClient email to be sent to file system directory:

That's great - we have a way to customise the HTML template, and make umbraco send nicely branded emails.Umbraco uses SmtpClient internally so emails will always be sent using mailSettings configuraiton specified in the web.config.That means email can be sent using services like SendGrid, dotMailer, other email sender service or even your own SMTP.

This functionality may already cover your requirements and you can stop reading! :) If you need more complicated customisation you will quite likely run into several… :

Problems

The functionality described above comes with following issues:

NotificationService's code for finding usersUp until version 7.5.4 the notification service was getting all the users in the system, getting all of their notifications and getting ALL existing versions of node that was modified.As you can imagine, that approach could slow down publishing on installations with large number of users and updates.Currently Umbraco only retrieves last 2 versions but maybe you don't need to display property changes in HTML email?

Html in configMaybe you want to have a better way of managing your email content generation.One of the common ways is to use *.cshtml file and RazorEngine to generate HTML email. That option is suitable when editors don't need the control over email template generation.But what if it's required to manage the email template via 3rd party service like dotMailer? https://www.dotmailer.com/platform/email-marketing/

Construction of HTML for updated properties.I personally don't think this code should be there at all, 1st screenshot in this post shows how the email looks when JSON-based property values exist in the template.But for people who do want to display some sort of list of changes then there should be a way of creating a provider; an injectable piece of code where you can decide which properties are displayed, in what format and how the HTML looks for this. Currently umbraco does this:

Additional data / processingMaybe you want to do some additional processing before sending the email.Maybe something like … recording each notification sent to the user and updating email with copy like "Send for Approval has been performed on [Page], You have [X] outstanding approvals".

Not using SMTP.Most of the 3rd party email providers allows sending transactional emails via SMTP but … not all of them.You might want to send emails by sending message using provider's web-service API.Maybe some editors prefer to be notified via text-message… or a message on Slack/Yammer?Currently umbraco makes an assumption that it will be SMTP client.

Further Problems

If we decide that we do want to change how notifications are constructed and sent you may think "ok, that's easy, Umbraco has a collection of various services that implement interfaces! I'll just write my own INotificationService implementation".Yes…and no….Umbraco does indeed have these services but there is (currently!) no easy, non-hacky way to change registration of them.Umbraco's ServiceContext has 2 constructors:

1st takes 26 parameters, where each is an object that implements one of umbraco's services.

This one is only used for Umbraco Unit Tests but looks like a good candidate!

Unfortunately …there are 27 services that need to be assigned (!) - IServerRegistrationService is missing from the constructor parameters.Until this problem is resolved, using this constructor will make umbraco throw an exception ( http://issues.umbraco.org/issue/U4-9097 )

2nd constructor takes several parameters like cache helper, logger, repository factory etc.When called it will assign all services with Umbraco's implementation of interfaces - this constructor doesn't allow any service customisation.

ServiceContext is created during Umbraco startup process.CreateServiceContext is a virtual method on BootManager class and a splendid candidate for what we need.

This is the preferred solution and should be used, unfortunately currently (7.5.4) constructor is missing 1 parameter as mentioned above.

Custom EventHandlers for various umbraco actions (Publish, Save, Send to publish etc) and custom code to send notifications.It doesn't feel like this is the correct solution because it would require trying to disable / not use umbraco’s send notification functionality while at the same time writing code that will find the user's notification subscription and handler various events

Unless you want to totally overwrite umbraco functionality, it's worth creating a wrapper for Umbraco notification service and overwrite only methods we need to change.SendNotifications method can be a bit confusing so I'll try to explain what each of the parameters does:

operatingUser - user that performed action that triggered notification

entities - entities that are involved in change that triggered notification.

action - letter code representing action that was performed

actionName - readable name of the action that was performed

http - current http context..

Last 2 parameters are slightly strange delegates. I suggest to ignore these parameters and construct email subject and body on your own.I'm going to explain them briefly in case you wanted to know what they do.

"body vars" is an array with 8 items:[0] - name of the notification recipient.[1] - readable name of the action[2] - name of the content / node[3] - name of the user that performed action that triggered notification[4] - URL of format: serverName:port/umbraco [5] - content / node ID[6] - summary of changes as HTML table rows, see point 3) from Problems section above.[7] - URL of format: scheme://serverName:port/nodeId.aspxArray of strings is used by umbraco to replace elements of email subject and body from language file. e.g.<key alias="mailSubject">[%0%] Notification about %1% performed on %2%</key>Here you can see that %0%, %1% and %2% will be replaced with first, second and third element in "subject vars"

We have learned how to replace umbraco services which can be very useful when customising umbraco behaviour.Now we can change how umbraco sends notifications and we also have a good starting point for changing other services like content service, if, of course, we ever need to :)