In modern DevOps environments, quick notification of system issues is crucial. Let’s explore how to integrate Azure Smart Detector Alerts with Google Chat using Azure Functions, enabling real-time monitoring notifications directly in your team’s chat space.
GoogleChatIntegration/
├── Functions/
│ └── SmartDetectorAlert.cs
├── Models/
│ ├── Alert.cs
│ └── ResponseMessage.cs
├── Program.cs
└── README.md
Let’s implement each component step by step.
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
services.AddHttpClient();
})
.Build();
host.Run();
public class Alert
{
public string SchemaId { get; set; }
public AlertData Data { get; set; }
}
public class AlertData
{
public Essentials Essentials { get; set; }
public AlertContext AlertContext { get; set; }
}
public class Essentials
{
public string AlertId { get; set; }
public string AlertRule { get; set; }
public string Severity { get; set; }
public string SignalType { get; set; }
public string MonitorCondition { get; set; }
public string MonitoringService { get; set; }
public List<string> AlertTargetIDs { get; set; }
public List<string> ConfigurationItems { get; set; }
public string OriginAlertId { get; set; }
public string FiredDateTime { get; set; }
public string Description { get; set; }
public string EssentialsVersion { get; set; }
public string AlertContextVersion { get; set; }
}
public class ResponseMessage
{
public string text { get; set; }
}
public class SmartDetectorAlert
{
private readonly ILogger<SmartDetectorAlert> _logger;
private readonly HttpClient _httpClient;
public SmartDetectorAlert(ILogger<SmartDetectorAlert> logger, HttpClient httpClient)
{
_logger = logger;
_httpClient = httpClient;
}
[Function("SmartDetectionRule")]
public async Task<IActionResult> SmartDetectionRule(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
var googleSpaceUrl = Environment.GetEnvironmentVariable("GOOGLE_SPACE_URL")
?? throw new InvalidOperationException("GOOGLE_SPACE_URL environment variable is not set.");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
_logger.LogTrace($"Received request body: {requestBody}");
try
{
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var requestData = JsonSerializer.Deserialize<Alert>(requestBody, options);
if (requestData?.Data?.Essentials?.Description != null)
{
var messageText = $"Alert: {requestData.Data.Essentials.AlertRule} - {requestData.Data.Essentials.Description}";
var responseMessage = new ResponseMessage { text = messageText };
var json = JsonSerializer.Serialize(responseMessage);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(googleSpaceUrl, content);
if (response.IsSuccessStatusCode)
{
_logger.LogInformation($"Message sent to Google Chat successfully: {responseMessage.text}");
return new OkObjectResult($"Message sent to Google Chat successfully: {responseMessage.text}");
}
else
{
_logger.LogError($"Error: {response.StatusCode}");
return new StatusCodeResult((int)response.StatusCode);
}
}
else
{
_logger.LogWarning("Deserialized data is missing expected properties");
return new BadRequestObjectResult("Invalid alert data structure");
}
}
catch (JsonException ex)
{
_logger.LogError($"JSON Deserialization error: {ex.Message}");
return new BadRequestObjectResult($"Error parsing JSON: {ex.Message}");
}
}
}
This integration provides real-time monitoring alerts directly in Google Chat, helping teams stay informed about critical system events. The solution is scalable and can be extended to handle different types of Azure alerts.
Stay tuned for our next post about deploying this solution using Azure DevOps Pipelines!
WRITTEN BY
Thuso Kharibe
Looking for some more adventure?
How about this next article.