Skip to content

Commit 201d50d

Browse files
Yvandandrewconnell
andauthored
New article - Create Azure functions for SharePoint webhooks using an azd template (#10118)
* Create sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * replace absolute links to learn site * fix warning * grammatical & markdown fixes - typos - links shouldn't point to "this", rather be descriptive - markdown fixes - paragraphs should be seperated by newlines - bullets should be `-`, not `+` * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * Update sharepoint-webhooks-using-azd-template.md * copy & format edits All the following are inline with MSDOCS rules: - change note about tutorial to NOTE type - use "select" instead of "click" for accessibility - bold whole link, not the text inside the `[]` - copy edits rec'd by Acrolinx * Update sharepoint-webhooks-using-azure-functions.md --------- Co-authored-by: Andrew Connell <[email protected]>
1 parent f866820 commit 201d50d

File tree

2 files changed

+179
-1
lines changed

2 files changed

+179
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
---
2+
title: Create Azure Functions for SharePoint webhooks using an azd template
3+
description: Use Azure Developer cli (azd) to deploy an Azure function app that connects to your SharePoint Online tenant, to register and manage webhooks, and process the notifications from SharePoint.
4+
ms.date: 02/27/2025
5+
ms.localizationpriority: low
6+
---
7+
# Azure Functions for SharePoint webhooks using azd
8+
9+
[Azure Developer CLI (azd)](https://aka.ms/azd) is an open-source tool that accelerates provisioning and deploying app resources in Azure.
10+
11+
This article uses the [Azure function app for SharePoint webhooks public template](https://github.com/Azure-Samples/azd-functions-sharepoint-webhooks) to deploy an Azure function app that connects to your SharePoint Online tenant, to register and manage [webhooks](overview-sharepoint-webhooks.md), and process the notifications from SharePoint.
12+
13+
## Prerequisites
14+
15+
- [Node.js 20](https://www.nodejs.org/)
16+
- [Azure Functions Core Tools](/azure/azure-functions/functions-run-local)
17+
- [Azure Developer CLI (azd)](/azure/developer/azure-developer-cli/install-azd)
18+
- An Azure subscription that trusts the same Microsoft Entra ID directory as the SharePoint tenant
19+
20+
## Permissions required to provision the resources in Azure
21+
22+
The account running **azd** must have at least the following roles to successfully provision the resources:
23+
24+
- Azure role **[Contributor](/azure/role-based-access-control/built-in-roles/privileged#contributor)**: To create all the resources needed
25+
- Azure role **[Role Based Access Control Administrator](/azure/role-based-access-control/built-in-roles/privileged#role-based-access-control-administrator)**: To assign roles (to access the storage account and Application Insights) to the managed identity of the function app
26+
27+
## Deploy the function app in Azure
28+
29+
1. Run **azd init** from an empty local (root) folder:
30+
31+
```console
32+
azd init --template azd-functions-sharepoint-webhooks
33+
```
34+
35+
Enter an environment name, such as **spofuncs-quickstart** when prompted. In **azd**, the environment is used to maintain a unique deployment context for your app.
36+
37+
1. Open the file **infra/main.parameters.json**, and set the variables `TenantPrefix` and `siteRelativePath` to match your SharePoint tenant.
38+
39+
Review the article on [Manage environment variables](/azure/developer/azure-developer-cli/manage-environment-variables) to manage the azd's environment variables.
40+
41+
1. Finally, run the command **azd up** to build the app, provision the resources in Azure and deploy the app package.
42+
43+
## Grant the function app access to SharePoint Online
44+
45+
The authentication to SharePoint is done using `DefaultAzureCredential`, so the credential used depends on whether the function app runs locally, or in Azure.
46+
47+
If you never heard about `DefaultAzureCredential`, you should familiarize yourself with its concept by referring to the section **Use DefaultAzureCredential for flexibility** in [Credential chains in the Azure Identity client library for JavaScript](/azure/developer/javascript/sdk/authentication/credential-chains).
48+
49+
### Using its managed identity
50+
51+
`DefaultAzureCredential` will use a managed identity to authenticate to SharePoint. This may be the existing, system-assigned managed identity of the function app service or a user-assigned managed identity.
52+
53+
This tutorial assumes the system-assigned managed identity is used.
54+
55+
#### Grant the SharePoint API permission Sites.Selected to the managed identity
56+
57+
Navigate to your function app in the [Azure portal](https://portal.azure.com/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft.Web%2Fsites/kind/functionapp) > select **Identity** and note the **Object (principal) ID** of the system-assigned managed identity.
58+
59+
In this tutorial, it is **d3e8dc41-94f2-4b0f-82ff-ed03c363f0f8**.
60+
61+
Then, use one of the scripts below to grant this identity the app-only permission **Sites.Selected** on the SharePoint API:
62+
63+
> [!IMPORTANT]
64+
> The scripts below require at least the delegated permission [`AppRoleAssignment.ReadWrite.All`](/graph/permissions-reference#approleassignmentreadwriteall) (requires admin consent)
65+
66+
<details>
67+
<summary>Using the Microsoft Graph PowerShell SDK</summary>
68+
69+
```powershell
70+
# This script requires the modules Microsoft.Graph.Authentication, Microsoft.Graph.Applications, Microsoft.Graph.Identity.SignIns, which can be installed with the cmdlet Install-Module below:
71+
# Install-Module Microsoft.Graph.Authentication, Microsoft.Graph.Applications, Microsoft.Graph.Identity.SignIns -Scope CurrentUser -Repository PSGallery -Force
72+
Connect-MgGraph -Scope "Application.Read.All", "AppRoleAssignment.ReadWrite.All"
73+
$managedIdentityObjectId = "d3e8dc41-94f2-4b0f-82ff-ed03c363f0f8" # 'Object (principal) ID' of the managed identity
74+
$scopeName = "Sites.Selected"
75+
$resourceAppPrincipalObj = Get-MgServicePrincipal -Filter "displayName eq 'Office 365 SharePoint Online'" # SPO
76+
$targetAppPrincipalAppRole = $resourceAppPrincipalObj.AppRoles | ? Value -eq $scopeName
77+
78+
$appRoleAssignment = @{
79+
"principalId" = $managedIdentityObjectId
80+
"resourceId" = $resourceAppPrincipalObj.Id
81+
"appRoleId" = $targetAppPrincipalAppRole.Id
82+
}
83+
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $managedIdentityObjectId -BodyParameter $appRoleAssignment | Format-List
84+
```
85+
</details>
86+
87+
<details>
88+
<summary>Using az cli in Bash</summary>
89+
90+
```bash
91+
managedIdentityObjectId="d3e8dc41-94f2-4b0f-82ff-ed03c363f0f8" # 'Object (principal) ID' of the managed identity
92+
resourceServicePrincipalId=$(az ad sp list --query '[].[id]' --filter "displayName eq 'Office 365 SharePoint Online'" -o tsv)
93+
resourceServicePrincipalAppRoleId="$(az ad sp show --id $resourceServicePrincipalId --query "appRoles[?starts_with(value, 'Sites.Selected')].[id]" -o tsv)"
94+
95+
az rest --method POST --uri "https://graph.microsoft.com/v1.0/servicePrincipals/${managedIdentityObjectId}/appRoleAssignments" --headers 'Content-Type=application/json' --body "{ 'principalId': '${managedIdentityObjectId}', 'resourceId': '${resourceServicePrincipalId}', 'appRoleId': '${resourceServicePrincipalAppRoleId}' }"
96+
```
97+
</details>
98+
99+
#### Grant the managed identity effective access to a SharePoint site
100+
101+
Navigate to the [Enterprise applications](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/StartboardApplicationsMenuBlade/) > Set the **Application type** filter to **Managed Identities** > select your managed identity and note its **Application ID**.
102+
103+
> [!NOTE]
104+
> In this tutorial, it is **3150363e-afbe-421f-9785-9d5404c5ae34**.
105+
106+
Then, use one of the scripts below to grant it the app-only permission **manage** (minimum required to register a webhook) on a specific SharePoint site:
107+
108+
> [!IMPORTANT]
109+
> The app registration used to run those scripts must have at least the following permissions:
110+
>
111+
> - Delegated permission **Application.ReadWrite.All** in the Graph API (requires admin consent)
112+
> - Delegated permission **AllSites.FullControl** in the SharePoint API (requires admin consent)
113+
114+
<details>
115+
<summary>Using PnP PowerShell</summary>
116+
117+
[PnP PowerShell](https://pnp.github.io/powershell/cmdlets/Grant-PnPAzureADAppSitePermission.html)
118+
119+
```powershell
120+
Connect-PnPOnline -Url "https://YOUR_SHAREPOINT_TENANT_PREFIX.sharepoint.com/sites/YOUR_SHAREPOINT_SITE_NAME" -Interactive -ClientId "YOUR_PNP_APP_CLIENT_ID"
121+
Grant-PnPAzureADAppSitePermission -AppId "3150363e-afbe-421f-9785-9d5404c5ae34" -DisplayName "YOUR_FUNC_APP_NAME" -Permissions Manage
122+
```
123+
</details>
124+
125+
<details>
126+
<summary>Using m365 cli in Bash</summary>
127+
128+
[m365 cli](https://pnp.github.io/cli-microsoft365/cmd/spo/site/site-apppermission-add/)
129+
130+
```bash
131+
targetapp="3150363e-afbe-421f-9785-9d5404c5ae34"
132+
siteUrl="https://YOUR_SHAREPOINT_TENANT_PREFIX.sharepoint.com/sites/YOUR_SHAREPOINT_SITE_NAME"
133+
m365 spo site apppermission add --appId $targetapp --permission manage --siteUrl $siteUrl
134+
```
135+
</details>
136+
137+
## Call the function app
138+
139+
For security reasons, when running in Azure, the function app requires an app key to pass in the query string parameter **code**. The app keys are found in the function app service's **App Keys** keys page.
140+
141+
Most HTTP functions take optional parameters `TenantPrefix` and `siteRelativePath`. If they are not specified, the values in the app's environment variables are used.
142+
143+
Below is a sample script in PowerShell to call the function app:
144+
145+
```powershell
146+
# Edit those variables to match your environment
147+
$funchost = "YOUR_FUNC_APP_NAME"
148+
$code = "YOUR_HOST_KEY"
149+
$listTitle = "YOUR_SHAREPOINT_LIST"
150+
$notificationUrl = "https://${funchost}.azurewebsites.net/api/webhooks/service?code=${code}"
151+
152+
# List all the webhooks registered on a list
153+
Invoke-RestMethod -Method GET -Uri "https://${funchost}.azurewebsites.net/api/webhooks/list?code=${code}&listTitle=${listTitle}"
154+
155+
# Register a webhook in a list
156+
Invoke-RestMethod -Method POST -Uri "https://${funchost}.azurewebsites.net/api/webhooks/register?code=${code}&listTitle=${listTitle}&notificationUrl=${notificationUrl}"
157+
158+
# Show this webhook registered on a list
159+
Invoke-RestMethod -Method GET -Uri "https://${funchost}.azurewebsites.net/api/webhooks/show?code=${code}&listTitle=${listTitle}&notificationUrl=${notificationUrl}"
160+
161+
# Remove the webhook from a list
162+
# Step 1: Call the function /webhooks/show to get the webhook id
163+
$webhookId = $(Invoke-RestMethod -Method GET -Uri "https://${funchost}.azurewebsites.net/api/webhooks/show?code=${code}&listTitle=${listTitle}&notificationUrl=${notificationUrl}").Id
164+
# Step 2: Call the function /webhooks/remove and pass the webhook id
165+
Invoke-RestMethod -Method POST -Uri "https://${funchost}.azurewebsites.net/api/webhooks/remove?code=${code}&listTitle=${listTitle}&webhookId=${webhookId}"
166+
```
167+
168+
## Cleanup the resources in Azure
169+
170+
You can delete all the resources this project created in Azure, by running the command **azd down**.
171+
172+
Alternatively, you can delete the resource group, that has the azd environment's name by default.
173+
174+
## See also
175+
176+
- [Overview of SharePoint webhooks](overview-sharepoint-webhooks.md)

Diff for: docs/apis/webhooks/sharepoint-webhooks-using-azure-functions.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ ms.localizationpriority: high
66
---
77
# Using Azure Functions with SharePoint webhooks
88

9-
[Azure Functions](/azure/azure-functions/functions-overview) offers an easy way to host your SharePoint webhooks: you can add your webhook C# or JavaScript code via the browser, and Azure takes care of the hosting and scaling of your function. This guide shows how to set up and use Azure Functions for your webhooks.
9+
[Azure Functions](/azure/azure-functions/functions-overview) offers an easy way to host your SharePoint webhooks: you can add your webhook C# or JavaScript code via the browser, and Azure takes care of the hosting and scaling of your function.
10+
11+
This guide shows how to set up and use Azure Functions for your webhooks using the Azure portal. Alternatively, you can refer to article [Create Azure Functions for SharePoint webhooks using an azd template](sharepoint-webhooks-using-azd-template.md), to automate the whole process using an **azd** template.
1012

1113
## Create an Azure Function App
1214

0 commit comments

Comments
 (0)