A simple send umbraco page as test mail content app
Tags: umbraco, umbracov8
Published: 2022-01-10 09:23:02

[Content Apps](https://our.umbraco.com/documentation/extending/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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqxencjda5fx2alj6zot.png)

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;
            }
        }
    }
}

```
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>

```

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();



});

```

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"
    ]
}

```