A Step-by-Step Guide to Email Notifications

Serie

Extending EasyLife 365 with Webhooks:

    Today, we're exploring how to extend EasyLife 365 Collaboration’s functionality using webhooks. Webhooks let you execute custom code at different stages of an object’s lifecycle. In this guide, we'll create an Azure Functions-based solution that sends email notifications using the Graph API whenever a team is created using a specific template.

    Introduction to EasyLife 365 Webhooks

    The EasyLife 365 Collaboration platform supports webhooks at multiple points in the workflow:

    • During resource provisioning (Teams, Groups, SharePoint sites, guest accounts)
    • When metadata changes are made to existing resources
    • As part of escalation actions in policies

    This allows you to build sophisticated automation workflows that integrate with your existing systems and processes.

    Components and Setup

    Our sample solution showcases a common webhook use case: sending email notifications when new teams are created. The solution architecture consists of:

    Azure Components

    • Function App with PowerShell runtime
    • App Service Plan
    • Storage Account for queuing
    • Application Insights for monitoring

    Function Components

    Two Azure Functions working together:

    • mailrequest HTTP-triggered function that receives webhook requests from EasyLife and writes them to a storage queue
    • mailqueue: Queue-triggered function that processes messages and sends emails via Graph API

    This architecture ensures reliable message processing with built-in retry capabilities through Azure Storage Queues.

    Prerequisites

    Before starting:

    Infrastructure Deployment

    With PowerShell and Azure CLI

    First, we will use PowerShell and Azure CLI to login to our Azure Subscription, create a resource group and function app and add environment variables to the function app:

      # Update these variables
      $resourceGroup = "rg-easylife-webhook"
      $location = "westeurope"
      $storageAccount = "saeasylifewebhook"
      $functionApp = "func-easylife-webhook"
      $mailFromAddress = "noreply@easylife365.cloud"
      $mailToAddresses = "user1@easylife365.cloud user2@easylife365.cloud"
      # Login to Azure
      az login
      # Create Resource Group
      az group create --name $resourceGroup --location $location
      # Create Storage Account
      az storage account create `
          --name $storageAccount `
          --location $location `
          --resource-group $resourceGroup `
          --sku Standard_LRS
      # Create Function App
      $funcAppOutput = az functionapp create `
          --name $functionApp `
          --storage-account $storageAccount `
          --consumption-plan-location $location `
          --resource-group $resourceGroup `
          --runtime powershell `
          --functions-version 4 `
          --assign-identity '[system]' | ConvertFrom-Json
      # Add Function App Environment Variables
      az functionapp config appsettings set `
          --name $functionApp `
          --resource-group $resourceGroup `
          --settings mailFromAddress=$mailFromAddress mailToAddresses=$mailToAddresses

    Note: The code is available on our GitHub, where you will also find bicep templates. I’ll walk you through that process in a future post.

    Assigning Permissions

    The Azure Function uses its system assigned managed identity to authenticate with Microsoft Graph. After deploying your function app, you'll need to grant the following Graph API permissions to its managed identity:

    • User Read All
    • Group Read All
    • Mail Send
      # Get service principals for permission assignment
      # the PowerShell deployment option will set the following variable
      $servicePrincipalId = $funcAppOutput.identity.principalId
      $graphObjectId = (az ad sp list --display-name 'Microsoft Graph' | ConvertFrom-Json)[0].id
      # Assign permissions to the managed identity
      @(
          'df021288-bdef-4463-88db-98f22de89214', # user.read.all
          '5b567255-7703-4780-807c-7be8301ae99b', # group.read.all
          'b633e1c5-b582-4048-a93e-9f11b44c7e96'  # mail.send
      ) | ForEach-Object {
          $body = @{
              principalId = $servicePrincipalId
              resourceId = $graphObjectId
              appRoleId = $_
          } | ConvertTo-Json -Compress
          $uri = "https://graph.microsoft.com/v1.0/servicePrincipals/$servicePrincipalId/appRoleAssignments"
          $header = "Content-Type=application/json"
          az rest --method POST --uri $uri --header $header --body $body.Replace('"',"'")
      }

    Deploying the PowerShell Code

    Once the infrastructure is set up, the next step is to deploy the function code. The repository contains two main functions:

    • mailrequest/run.ps1: The HTTP-triggered function that receives webhooks
    • mailqueue/run.ps1: The queue-triggered function that sends emails

    Deploy the code using PowerShell and Azure CLI:

      # Update deploy package
      $deployPath = Get-ChildItem | `
          Where-Object { $_.Name -notmatch "deploypkg" -and $_.Name -notmatch "_automation" } | ` `
          Compress-Archive -DestinationPath deploypkg.zip -Force -PassThru
      # Deploy the zipped package
      az functionapp deployment source config-zip `
          --name $functionAppName `
          --resource-group $resourceGroupName `
          --src $deployPath.FullName

    Testing the Function

    After deploying the function app and uploading the PowerShell code, we’re ready for testing.

    1. Get Function URL:

    • Open your Function App in Azure Portal
    • Navigate to Functions > mailrequest
    • Click "Get Function URL"
    • Copy the complete URL with code parameter

    2. Test with PowerShell:

    Use the following snippet to send a simulated EasyLife webhook to the function app to validate it is working as intended. Please note, the first execution of the function app will be slower than subsequent executions.

      # Call Function App HTTP endpoint
      $uri = 'https://<functionAppName>.azurewebsites.net/api/mailrequest?code=<code>'
      $body = @{
          eventType = "groupcreated"
          # the user object contains information about the creator of the team
          user = @{
              # use real userPrincipalName
              userPrincipalName = "testuser@yourdomain.com"
          }
          # the group object contains information about the team
          group = @{
              displayName = "Test Team"
              # Use real group ID of a team
              id = "00000000-0000-0000-0000-000000000000"
          }
      } | ConvertTo-Json –Compress
      Invoke-RestMethod -Uri $uri -Body $body -Method Post

    Configuring EasyLife

    If the test is successful, we are finally ready to add the function app’s URL to the webhook configuration in the EasyLife Cockpit:

    • Open the EasyLife Cockpit
    • Navigate to Templates > Teams
    • Select an existing template or create a new one
    • Under Provisioning, paste your function URL in the webhook field
    • Save changes

    To verify:

    • Create a new team using your configured template
    • Check for the email notification being sent
    • Review Application Insights logs for any issues

    Best Practices

    • Error Handling: Implement comprehensive error handling in your functions.
    • Monitoring: Use Application Insights to monitor function performance.
    • Security: Rotate function keys regularly and store sensitive data securely in Key Vault.
    • Testing: Use a dedicated development environment for testing.
    • Logging: Implement detailed logging for troubleshooting.

    Additional Resources

    Conclusion: Tailor Your Microsoft 365 Governance with Webhook Integration

    Webhooks offer a powerful way to enhance EasyLife 365 Collaboration’s functionality and integrate it seamlessly with your existing systems. This example demonstrates just one possible use case - sending email notifications - but the same pattern can be adapted for many other scenarios, such as:

    • Ticketing system integration
    • Custom notifications for policy escalations
    • Custom SharePoint site provisioning
    • Policy compliance reporting
    • Custom approval workflows

    Keep an eye out for upcoming posts in this series, where we’ll dive into more exciting use cases.

    For more information and support, visit our documentation at docs.easylife365.cloud or reach out to our experts for personalized guidance and support.

    Other Articles