How To Send Actionable Emails In .NET

Introduction

In any application, email notifications are sent to users if an action is needed, say if some project needs approval. The email notification will be sent to the user and the user usually click on the link, it will navigate to the application, then the user needs to log in and take the necessary action by navigating to that application details page. What if that action button is available in your email notification itself!!? Yes, that is what we are going to discuss in this article. 

Usually, when any meetings are scheduled (like in Microsoft Teams), an email notification will be sent with action buttons (like Accept, Reject, Tentative). So same can be implemented in our application email notifications as well. I had the same requirement and have done a lot of research to achieve it, I'm trying to put all my findings in this article. Emails with action buttons and handling the response from the action buttons can be achieved using actionable emails in outlook. 

Step 1: Design an email card using an adaptive card designer.

We can design our email card with an action button using the Actionable Message Designer. Click on the link https://amdesigner.azurewebsites.net/, it will navigate to the designer page with some pre-defined templates like in the below screenshot. 

How To Send Actionable Emails In .NET

Select any of the templates from the above list, it will take you to the designer section where we can design based on our requirement just by drag & drop as shown in the below screenshot. 

How To Send Actionable Emails In .NET

We can design the card as per our requirement and test it by sending a sample email to our email id. Let's design our sample email card like below. 

How To Send Actionable Emails In .NET

After designing, click on the sign-in button at the top right corner & sign in with any outlook email id. After sign in, we can send a sample email that we designed to our signed-in email id by clicking on send option at the right top corner of the screen. Our sample email looks like below.

How To Send Actionable Emails In .NET

It will also generate a JSON which we will get from the designer section.

Step 2: Register your service with an actionable email developer dashboard. 

We need to register our service with an actionable email developer dashboard using your work account to get the originator Id. The Originator Id must be needed to send actionable email via code i.e.NET. 

Click on the below link to register & get the originator Id.

Step 3: Handle the action button and the response.

We can post the response data to our API via the JSON which we generated from step 1. Say our sample JSON looks like below.

{
  "@type": "ActionCard",
  "name": "Comment",
  "inputs": [
    {
      "@type": "TextInput",
      "id": "comment",
      "isMultiline": true,
      "title": "Input's title property"
    }
  ],
  "actions": [
    {
      "@type": "HttpPOST",
      "name": "Action's name prop.",
      "target": "https://yammer.com/comment?postId=123",
      "body": "comment={{comment.value}}"
    }
  ]
}

In the above JSON, the target key under action is our API endpoint, and response data will be posted to this endpoint with the click of the action button. For more details please go through the link.

After getting JSON from Step 1 & Originator ID from step 2, We can put our JSON in the script tag & develop the HTML template which we can use to send an email that looks like below,

How To Send Actionable Emails In .NET

We can use the above template to send an email via .NET using the below code. Below is the sample .NET code provided by Microsoft in the official document. Please check this link for more details click here.

class Program {
    /// <summary>
    /// Get the private key to sign the card
    /// </summary>
    /// <returns>RSA private key</returns>
    static SecurityKey GetSecurityKeyFromRSAPrivateKeyXml() {
        // This is the Outlook Actionable Message developer key, which is only valid in self-sending senario.
        // Production services should generate their own key pairs and register the public key with Actionable Message team.
        string rsaPrivateKeyXml = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        var rsa = new RSACryptoServiceProvider();
        rsa.FromXmlString(rsaPrivateKeyXml);
        return new RsaSecurityKey(rsa);
    }
    /// <summary>
    /// Generate the Actionable Message email body with signed Adaptive Card
    /// </summary>
    /// <param name="args">Command line args</param>
    static void Main(string[] args) {
        SecurityKey securityKey = GetSecurityKeyFromRSAPrivateKeyXml();
        SigningCredentials signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256Signature);
        JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
        handler.SetDefaultTimesOnTokenCreation = false;
        string adaptiveCardRawJson = File.ReadAllText("card.json");
        string minifiedCard = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(adaptiveCardRawJson));
        // The Actionable Message provider ID generated during provider registration
        string originator = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        // Recipients of the email
        string[] recipients = {
            "XXXXXXXXXXX.com"
        };
        // Sender of the email
        string sender = "XXXXXXXXXXXXXXXXXXXXXX.com";
        ClaimsIdentity subject = new ClaimsIdentity(new Claim[] {
            new Claim("sender", sender),
                new Claim("originator", originator),
                new Claim("recipientsSerialized", JsonConvert.SerializeObject(recipients)),
                new Claim("adaptiveCardSerialized", minifiedCard)
        });
        JwtSecurityToken token = handler.CreateJwtSecurityToken(subject: subject, issuedAt: DateTime.UtcNow, signingCredentials: signingCredentials);
        string emailBody = File.ReadAllText("signed_adaptive_template.html");
        emailBody = emailBody.Replace("{{signedCardPayload}}", token.RawData);
    }
}

The solution file structure looks like below,

How To Send Actionable Emails In .NET

Debugging Actionable emails

We can troubleshoot actionable emails via the Actionable Messages Debugger for Outlook. We can install this chrome plug-in to debug the actionable emails. 

How To Send Actionable Emails In .NET

Summary

In this article, we discussed designing the actionable cards via designer, registering your service with an actionable email developer dashboard, and debugging actionable emails. Hope it's useful.