Send Alert to Microsoft Teams from Event Hub via Azure Functions

Azure Event Hubs is an event ingestion service for big data streaming workloads. It is capable of receiving and processing millions of events per second. Data sent to an event hub can be transformed and stored by using any real-time analytics provider or batching/storage adapters.

It can also be used to receive Machine’s Telemetry data in a Manufacture Organization. A monitoring and alerting system can be deployed on Event Hubs.

In this article, we will learn to send an Alert to Microsoft Teams for disconnected Machines based on the Telemetry data received in the Event Hub. To achieve this, we would use Webhook connectors for Microsoft Teams. A Webhook is an addressable HTTP endpoint that allows external applications to communicate with Azure Services.

So Let’s begin.

Pre-requisites

  • Event Hub Should be up and running.
  • Events Data received by Event Hub should have below Schema:
{
   "MachineName":"AB01",
   "ServerName":"XXXYYZZZZ01",
   "Process":"CNC",
   "LastStatus":3,
   "Status":"Connect",
   "Time":"2020-05-30T16:18:31.7058659Z"
}

Add an Incoming Webhook to a Teams channel

  • Navigate to the channel
  • (•••) More Options from the top navigation bar.
  • Choose Connectors from the drop-down menu and search for Incoming Webhook.
  • Select the Configure button, provide a name, and image(optional). Click Create
  • The dialog window will present a unique URL that will map to the channel. Note the URL
  • Select the Done button. The webhook will be available in the team channel.

Create Azure Function App

  • Go to Function App. Click on Add
  • Provide details and click on Review + Create

Create a Function

  • Click on Functions > Add
  • Click on Event Hub Trigger
  • Provide Details and Click on Create Function. Ensure to select Correct event hub
  • Click on Code +Test. Paste below code in Code Window. Ensure to replace place holder and other details in the code. Replace <placeholders> with actual values.
#r "Microsoft.Azure.EventHubs"
#r "Newtonsoft.Json"
  
using System;
using System.Text;
using Microsoft.Azure.EventHubs;
using Newtonsoft.Json;
 
private static readonly HttpClient HttpClient = new HttpClient();
public static async Task Run(EventData[] events, ILogger log)
{
   var url = "<Webhook URL>";
   foreach (EventData eventData in events)
   {
    try
     {
      string messageBody = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);
      ServerDetails serverDetails = JsonConvert.DeserializeObject<ServerDetails>(messageBody);
              
      var MachineName = serverDetails.MachineName;
      var ServerName = serverDetails.ServerName;
      var Process = serverDetails.Process;
      var Status = serverDetails.Status;
      var Time = serverDetails.Time;
      if(Status == "Disconnect"){
        log.LogInformation($"Server Details Tested: {MachineName}{ServerName}{Process}{Status}{Time}");
        DateTime reportedtime = DateTime.Now;
        reportedtime = reportedtime.ToUniversalTime();
        TimeSpan difference = reportedtime - Time;
        int downtimedays = difference.Days;
        if(downtimedays > 1) {
          var msgtitle  = $"Alert :{MachineName} Disconnected for more than 2 days";
          var msgtext = $"Machine Name: {MachineName}, Server Name: {ServerName}, Process: {Process}, Status: {Status}, Time: {Time}";
          var plainTeamsMessage = new PlainTeamsMessage { Title=msgtitle, Text=msgtext };
          var content = new StringContent(JsonConvert.SerializeObject(plainTeamsMessage), Encoding.UTF8, "application/json");
          var response = await HttpClient.PostAsync(url, content);
 
         log.LogInformation($"Teams Alert Response {response.StatusCode}");
          await Task.Yield();
          log.LogInformation($"Teams Alert Sent");
          }
        }
      }
      catch (Exception e)
      {
       log.LogInformation($"Error{e}");
      }
    }
}
 
public class ServerDetails
{
    public string MachineName { get; set; }
    public string ServerName { get; set; }
    public string Process { get; set; }
    public int  LastStatus { get; set; }
    public string Status { get; set; }
    public DateTime Time { get; set; }
}
 
private class PlainTeamsMessage
{
    public string Title { get; set; }
    public string Text { get; set; }
}

In the above code, we created a ServerDetails Class to capture and de-serialize the events data. Once the events data is de-serialized, we check if the Machine has been disconnected for more than 1 day and then, prepare create an instance of PlainTeamMessage to create content for Microsoft Teams Alert. We log the Alert Sent activity for auditing purposes.

The Alert sent to Microsoft Teams looks something like below:

Microsoft Teams supports a host of other connectors, which enables you to integrate it with your services. Do try them out!!!



Categories: Azure, Azure Functions

Tags: , , , ,

Leave a Reply