Series
Extending EasyLife 365 with Webhooks:
1: Extending EasyLife 365 with Webhooks: A Step-by-Step Guide to Email Notifications (you are reading this article)
A Step-by-Step Guide to Email Notifications
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:
- Azure subscription with permissions to create resources
- Azure CLI installed from https://aka.ms/installazurecliwindows
- PowerShell 7 or higher
- Access to the EasyLife Cockpit
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:
_powershell_
# 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
powershell
# 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:
powershell
# 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.
powershell
# 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
- EasyLife Documentation
- EasyLife PowerShell Module
- Sample Code Repository
- Azure Functions Documentation
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.