Tuesday, December 12, 2017

Sending Emails from SharePoint Solutions Using Microsoft Flow

It’s not at all unusual to want to send an email from some page in SharePoint where there isn’t a native capability available. While there are lots of external services which can send email for us – like SendGrid – we usually want to keep the email “in house” in an enterprise environment. (In fact, there’s even a connector for SendGrid in Flow.)

While using an external service may not be appealing, even Flow is an “external” service. Once you’re in the cloud, you’re in the cloud. However, it seems to make more sense in many cases to simply use Flow to send emails via the Outlook Send an email action.

I’ve started setting up a generic Send an email Flow to support several client projects, so I figured I’d document what I’ve been doing.

The basic idea here is that I want to be able to call a REST endpoint with the details of the email I’d like to send and have it go out to the recipient(s). There’s no validation or tracking here; I just assume it happens. It wouldn’t be all that hard to add another few steps to log the emails to a SharePoint list or something if that were useful for you.

Flow has a perfect trigger for this: When a HTTP request is received. (I would have gone with When an HTTP request is received, personally.)

Start by creating a Flow “from blank”, meaning without using a template. If you search for HTTP, you’ll find the When a HTTP request is received trigger.

This trigger is a great way to create a poor man’s Web Service, just like we need here. Note that the REST endpoint will be provisioned after you save the Flow, so at this point, we don’t know what it will be, but no matter.

I had decided that my payload for the emails was going to be pretty simple, made up only of the To (recipient), Subject, and Body. That’s all it really takes to make a useful email. To set up a sample payload, I decided what I’d like to send in one of my client side SPAs (Single Page Applications) and dummied up some data, like so:

{
  "To": "marc@marc.com",
  "Subject": "This is the email",
  "Body": "Welcome to Flow!"
}

The nice thing here is that Flow will generate the schema it needs from sample data like this. Click on Use sample payload to generate schema and paste in your sample data, like so:When you click Done, you’ll see the schema the trigger needs to “understand” the data you will be sending. If you wanted to make changes to the structure of the incoming data, you could paste in a new sample or edit the schema manually.

{
    "type": "object",
    "properties": {
        "To": {
            "type": "string"
        },
        "Subject": {
            "type": "string"
        },
        "Body": {
            "type": "string"
        }
    }
}

Next we simply add a new step to send the email by clicking on New step, then Add an action. I find it by searching for “email”.

Once you’ve chosen that action, you can add the incoming data properties to the properties the Send an email action uses to form the email.

I like to have the option to send HTML emails (all pretty and everything), so I set the Is HTML advanced option to Yes.

Once you’ve saved the Flow, you can go back into it to get the REST endpoint you need to invoke it.

Finally, you’ll want to call the REST endpoint whenever you want to send an email. Here’s an example function I use in one of my Angular-based SPAs. It’s a pretty generic function, and I simply pass in the to, subject, and body values. Any work I need to do to build up those values happens elsewhere. (Lest you think you can use my Flow, I’ve edited the endpoint inventively. My Flow is still in an undisclosed location.)

self.sendEmail = function (to, subject, body) {

    var deferred = $q.defer();

    var emailData = {
        To: to,
        Subject: subject,
        Body: body
    }

    var request = {
        url: "http://ift.tt/2AOFNFu",
        data: angular.toJson(emailData),
        headers: {
            "Accept": "application/json",
            "content-type": "application/json;odata=nometadata"
        }
    };

    var success = function (response) {
        deferred.resolve(response.data);
    };

    var error = function (response) {
        deferred.reject(response.data);
    };

    $http(request).then(success, error);

    return deferred.promise;

};

And voila! Now you have an easy to use, generic emailing function. One downside to this approach is that the email will be sent using your own connection. For this reason, you may want to set up some fake “users” for the connections in Flow – maybe “SharePoint administrator” or something. I’m hoping the Flow team comes up with a better way for us to manage who the Flow runs as in the future, but for now this works.


by Marc D Anderson via Marc D Anderson's Blog

No comments:

Post a Comment