DEV Community

Cover image for A simple send umbraco page as test mail content app
Tim Geyssens
Tim Geyssens

Posted on

A simple send umbraco page as test mail content app

Content Apps are companions to the editing experience when working with content or media in the Umbraco backoffice.

So unlike prop editors they don't store any data against the current document.

A usecase I recently encountered was the ability to generate newsletters from Umbraco and send them with a third party tool (so import the outputted html with a mailing service like mailchimp).

But the editors also wanted the ability to first send a single test mail from within Umbraco before migrating the markup.

Send test email

The solution consists of an API Controller that fetches the rendered output and sends that as an email.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
using Umbraco.Core.Logging;
using Umbraco.Web.WebApi;
using Umbraco.Web;
using Umbraco.Core.Models.PublishedContent;
using System.Web.Http;

namespace Acme.Core.Controllers.API
{
    public class NewsLetterController : UmbracoAuthorizedApiController
    {
        private readonly ILogger _logger;
        private readonly IProfilingLogger _profilingLogger;
        public NewsLetterController(ILogger logger, IProfilingLogger profilingLogger)
        {

            this._logger = logger;
            this._profilingLogger = profilingLogger;
        }

        [HttpGet]
        public bool SendTestMail(int newsletterId, string email)
        {
            var doc = this.Umbraco.Content(newsletterId);

            if (doc != null)
            {
                string markup = string.Empty;

                if (this.GetHtmlByUrl(doc.Url(mode: UrlMode.Absolute), out markup))
                {
                    var message = new MailMessage("noreply@acme.com", email);
                    message.Subject = doc.Name;
                    message.Body = markup;
                    message.IsBodyHtml = true;
                    var client = new SmtpClient();
                    client.Send(message);

                    return true;
                }
            }

            return false;
        }

        private bool GetHtmlByUrl(string url, out string fullHtml)
        {
            using (this._profilingLogger.DebugDuration<NewsLetterController>("GetHtmlByUrl(" + url + ")", "GetHtmlByUrl(" + url + ") done"))
            {

                if (!Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
                {
                    fullHtml = "";
                    return false;
                }

                try
                {
                    var httpTimeout = 1000;

                    var cookieDictionary = new Dictionary<string, string>();
                    var webRequest = (HttpWebRequest)WebRequest.Create(uri);
                    httpTimeout *= 1000;
                    webRequest.Timeout = httpTimeout;
                    webRequest.UserAgent = "NewsLetterController";

                    if (cookieDictionary != null && cookieDictionary.Count > 0)
                    {
                        var container = new CookieContainer();
                        var domain = webRequest.Address.DnsSafeHost;
                        foreach (var cookie in cookieDictionary)
                        {
                            container.Add(new Cookie(cookie.Key, cookie.Value, "/", domain));
                        }

                        webRequest.CookieContainer = container;
                    }

                    var webResponse = (HttpWebResponse)webRequest.GetResponse();
                    using (var sr = new StreamReader(webResponse.GetResponseStream()))
                    {
                        fullHtml = sr.ReadToEnd();
                    }

                    return true;
                }
                catch (WebException ex)
                {
                    this._logger.Error<NewsLetterController>(ex, $"Error in NewsLetterController retrieval. Url: {url}");
                    fullHtml = string.Empty;
                }

                return false;
            }
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

And the actual content app, that outputs a text input and a submit button.

View

<div ng-controller="Custom.SendPageAsMail as vm">
  <umb-box>
    <umb-box-header title="Send test mail"></umb-box-header>
    <umb-box-content>
      <input type="text" ng-model="vm.emailAddress" class="umb-property-editor umb-textstring textstring" required no-dirty-check />
      <a class="control__button btn">
        <i class="icon icon-message" ng-click="sendTestMail()">Send</i>
      </a>
    </umb-box-content>
  </umb-box>
</div>

Enter fullscreen mode Exit fullscreen mode

Controller (also populates the input with current user email)

angular.module("umbraco")
    .controller("Custom.SendPageAsMail", function ($scope, editorState, $http, userService) {
        var vm = this;
        vm.CurrentNodeId = editorState.current.id;
        vm.emailAddress = "";

        function _sendTestMail() {

            $http.get('/Umbraco/backoffice/Api/NewsLetter/SendTestMail?newsletterId=' + vm.CurrentNodeId + '&email=' + vm.emailAddress).then(function (response) {

            });


        }

        function _init() {

            $scope.sendTestMail = _sendTestMail;

            userService.getCurrentUser().then(function (user) {
                vm.emailAddress = user.email;
            });
        }

        _init();



});

Enter fullscreen mode Exit fullscreen mode

Package manifest

{

    "contentApps": [
    {
        "name": "Send testmail", 
        "alias": "sendpageasmail", 
        "weight": 0, 
        "icon": "icon-message",
        "view": "~/App_Plugins/SendPageAsMail/SendPageAsMail.html",
        "show": [

            "+content/newsLetter",
            "+contentType/newsLetter"
        ]

    }
    ],

    "javascript": [
        "~/App_Plugins/SendPageAsMail/SendPageAsMail.controller.js"
    ]
}

Enter fullscreen mode Exit fullscreen mode

Latest comments (0)