title | description | services | author | manager | editor | ms.service | ms.tgt_pltfrm | ms.devlang | ms.topic | ms.date | ms.author |
---|---|---|---|---|---|---|---|---|---|---|---|
Microsoft Graph bindings for Azure Functions |
Understand how to use Microsoft Graph triggers and bindings in Azure Functions. |
functions |
mattchenderson |
cfowler |
functions |
na |
multiple |
article |
12/20/2017 |
mahender |
This article explains how to configure and work with Microsoft Graph triggers and bindings in Azure Functions. With these, you can use Azure Functions to work with data, insights, and events from the Microsoft Graph.
The Microsoft Graph extension provides the following bindings:
- An auth token input binding allows you to interact with any Microsoft Graph API.
- An Excel table input binding allows you to read data from Excel.
- An Excel table output binding allows you to modify Excel data.
- A OneDrive file input binding allows you to read files from OneDrive.
- A OneDrive file output binding allows you to write to files in OneDrive.
- An Outlook message output binding allows you to send email through Outlook.
- A collection of Microsoft Graph webhook triggers and bindings allows you to react to events from the Microsoft Graph.
[!INCLUDE intro]
Note
Microsoft Graph bindings are currently in preview for Azure Functions version 2.x. They are not supported in Functions version 1.x.
The auth token input binding is provided in the Microsoft.Azure.WebJobs.Extensions.AuthTokens NuGet package. The other Microsoft Graph bindings are provided in the Microsoft.Azure.WebJobs.Extensions.MicrosoftGraph package. Source code for the packages is in the azure-functions-microsoftgraph-extension GitHub repository.
[!INCLUDE functions-package-v2]
Microsoft Graph bindings are available through binding extensions. Binding extensions are optional components to the Azure Functions runtime. This section shows how to set up the Microsoft Graph and auth token extensions.
Binding extensions are available only for Azure Functions 2.0 preview.
For information about how to set a function app to use the preview 2.0 version of the Functions runtime, see How to target Azure Functions runtime versions.
To install an extension from the Azure portal, navigate to either a template or binding that references it. Create a new function, and while in the template selection screen, choose the "Microsoft Graph" scenario. Select one of the templates from this scenario. Alternatively, you can navigate to the "Integrate" tab of an existing function and select one of the bindings covered in this article.
In both cases, a warning will appear which specifies the extension to be installed. Click Install to obtain the extension. Each extension only needs to be installed once per function app.
Note
The in-portal installation process can take up to 10 minutes on a consumption plan.
If you are using Visual Studio, you can get the extensions by installing the NuGet packages that are listed earlier in this article.
The bindings outlined in this article require an identity to be used. This allows the Microsoft Graph to enforce permissions and audit interactions. The identity can be a user accessing your application or the application itself. To configure this identity, set up App Service Authentication / Authorization with Azure Active Directory. You will also need to request any resource permissions your functions require.
Note
The Microsoft Graph extension only supports Azure AD authentication. Users need to log in with a work or school account.
If you're using the Azure portal, you'll see a warning below the prompt to install the extension. The warning prompts you to configure App Service Authentication / Authorization and request any permissions the template or binding requires. Click Configure Azure AD now or Add permissions now as appropriate.
The auth token input binding gets an Azure AD token for a given resource and provides it to your code as a string. The resource can be any for which the application has permissions.
This section contains the following subsections:
See the language-specific example:
The following example gets user profile information.
The function.json file defines an HTTP trigger with a token input binding:
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"type": "token",
"direction": "in",
"name": "graphToken",
"resource": "https://graph.microsoft.com",
"identity": "userFromRequest"
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
The C# script code uses the token to make an HTTP call to the Microsoft Graph and returns the result:
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, string graphToken, TraceWriter log)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", graphToken);
return await client.GetAsync("https://graph.microsoft.com/v1.0/me/");
}
The following example gets user profile information.
The function.json file defines an HTTP trigger with a token input binding:
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"type": "token",
"direction": "in",
"name": "graphToken",
"resource": "https://graph.microsoft.com",
"identity": "userFromRequest"
},
{
"name": "res",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
The JavaScript code uses the token to make an HTTP call to the Microsoft Graph and returns the result.
const rp = require('request-promise');
module.exports = function (context, req) {
let token = "Bearer " + context.bindings.graphToken;
let options = {
uri: 'https://graph.microsoft.com/v1.0/me/',
headers: {
'Authorization': token
}
};
rp(options)
.then(function(profile) {
context.res = {
body: profile
};
context.done();
})
.catch(function(err) {
context.res = {
status: 500,
body: err
};
context.done();
});
};
In C# class libraries, use the Token attribute.
The following table explains the binding configuration properties that you set in the function.json file and the Token
attribute.
function.json property | Attribute property | Description |
---|---|---|
name | Required - the variable name used in function code for the auth token. See Using an auth token input binding from code. | |
type | Required - must be set to token . |
|
direction | Required - must be set to in . |
|
identity | Identity | Required - The identity that will be used to perform the action. Can be one of the following values:
|
userId | UserId | Needed if and only if identity is set to userFromId . A user principal ID associated with a previously logged-in user. |
userToken | UserToken | Needed if and only if identity is set to userFromToken . A token valid for the function app. |
Resource | resource | Required - An Azure AD resource URL for which the token is being requested. |
The binding itself does not require any Azure AD permissions, but depending on how the token is used, you may need to request additional permissions. Check the requirements of the resource you intend to access with the token.
The token is always presented to code as a string.
The Excel table input binding reads the contents of an Excel table stored in OneDrive.
This section contains the following subsections:
See the language-specific example:
The following function.json file defines an HTTP trigger with an Excel input binding:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"type": "excel",
"direction": "in",
"name": "excelTableData",
"path": "{query.workbook}",
"identity": "UserFromRequest",
"tableName": "{query.table}"
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
The following C# script code reads the contents of the specified table and returns them to the user:
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
public static IActionResult Run(HttpRequest req, string[][] excelTableData, TraceWriter log)
{
return new OkObjectResult(excelTableData);
}
The following function.json file defines an HTTP trigger with an Excel input binding:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"type": "excel",
"direction": "in",
"name": "excelTableData",
"path": "{query.workbook}",
"identity": "UserFromRequest",
"tableName": "{query.table}"
},
{
"name": "res",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
The following JavaScript code reads the contents of the specified table and returns them to the user.
module.exports = function (context, req) {
context.res = {
body: context.bindings.excelTableData
};
context.done();
};
In C# class libraries, use the Excel attribute.
The following table explains the binding configuration properties that you set in the function.json file and the Excel
attribute.
function.json property | Attribute property | Description |
---|---|---|
name | Required - the variable name used in function code for the Excel table. See Using an Excel table input binding from code. | |
type | Required - must be set to excel . |
|
direction | Required - must be set to in . |
|
identity | Identity | Required - The identity that will be used to perform the action. Can be one of the following values:
|
userId | UserId | Needed if and only if identity is set to userFromId . A user principal ID associated with a previously logged-in user. |
userToken | UserToken | Needed if and only if identity is set to userFromToken . A token valid for the function app. |
path | Path | Required - the path in OneDrive to the Excel workbook. |
worksheetName | WorksheetName | The worksheet in which the table is found. |
tableName | TableName | The name of the table. If not specified, the contents of the worksheet will be used. |
This binding requires the following Azure AD permissions:
Resource | Permission |
---|---|
Microsoft Graph | Read user files |
The binding exposes the following types to .NET functions:
- string[][]
- Microsoft.Graph.WorkbookTable
- Custom object types (using structural model binding)
The Excel output binding modifies the contents of an Excel table stored in OneDrive.
This section contains the following subsections:
See the language-specific example:
The following example adds rows to an Excel table.
The function.json file defines an HTTP trigger with an Excel output binding:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"name": "newExcelRow",
"type": "excel",
"direction": "out",
"identity": "userFromRequest",
"updateType": "append",
"path": "{query.workbook}",
"tableName": "{query.table}"
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
The C# script code adds a new row to the table (assumed to be single-column) based on input from the query string:
using System.Net;
using System.Text;
public static async Task Run(HttpRequest req, IAsyncCollector<object> newExcelRow, TraceWriter log)
{
string input = req.Query
.FirstOrDefault(q => string.Compare(q.Key, "text", true) == 0)
.Value;
await newExcelRow.AddAsync(new {
Text = input
// Add other properties for additional columns here
});
return;
}
The following example adds rows to an Excel table.
The function.json file defines an HTTP trigger with an Excel output binding:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"name": "newExcelRow",
"type": "excel",
"direction": "out",
"identity": "userFromRequest",
"updateType": "append",
"path": "{query.workbook}",
"tableName": "{query.table}"
},
{
"name": "res",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
The following JavaScript code adds a new row to the table (assumed to be single-column) based on input from the query string.
module.exports = function (context, req) {
context.bindings.newExcelRow = {
text: req.query.text
// Add other properties for additional columns here
}
context.done();
};
In C# class libraries, use the Excel attribute.
The following table explains the binding configuration properties that you set in the function.json file and the Excel
attribute.
function.json property | Attribute property | Description |
---|---|---|
name | Required - the variable name used in function code for the auth token. See Using an Excel table output binding from code. | |
type | Required - must be set to excel . |
|
direction | Required - must be set to out . |
|
identity | Identity | Required - The identity that will be used to perform the action. Can be one of the following values:
|
UserId | userId | Needed if and only if identity is set to userFromId . A user principal ID associated with a previously logged-in user. |
userToken | UserToken | Needed if and only if identity is set to userFromToken . A token valid for the function app. |
path | Path | Required - the path in OneDrive to the Excel workbook. |
worksheetName | WorksheetName | The worksheet in which the table is found. |
tableName | TableName | The name of the table. If not specified, the contents of the worksheet will be used. |
updateType | UpdateType | Required - The type of change to make to the table. Can be one of the following values:
|
This binding requires the following Azure AD permissions:
Resource | Permission |
---|---|
Microsoft Graph | Have full access to user files |
The binding exposes the following types to .NET functions:
- string[][]
- Newtonsoft.Json.Linq.JObject
- Microsoft.Graph.WorkbookTable
- Custom object types (using structural model binding)
The OneDrive File input binding reads the contents of a file stored in OneDrive.
This section contains the following subsections:
See the language-specific example:
The following example reads a file that is stored in OneDrive.
The function.json file defines an HTTP trigger with a OneDrive file input binding:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"name": "myOneDriveFile",
"type": "onedrive",
"direction": "in",
"path": "{query.filename}",
"identity": "userFromRequest"
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
The C# script code reads the file specified in the query string and logs its length:
using System.Net;
public static void Run(HttpRequestMessage req, Stream myOneDriveFile, TraceWriter log)
{
log.Info(myOneDriveFile.Length.ToString());
}
The following example reads a file that is stored in OneDrive.
The function.json file defines an HTTP trigger with a OneDrive file input binding:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"name": "myOneDriveFile",
"type": "onedrive",
"direction": "in",
"path": "{query.filename}",
"identity": "userFromRequest"
},
{
"name": "res",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
The following JavaScript code reads the file specified in the query string and returns its length.
module.exports = function (context, req) {
context.res = {
body: context.bindings.myOneDriveFile.length
};
context.done();
};
In C# class libraries, use the OneDrive attribute.
The following table explains the binding configuration properties that you set in the function.json file and the OneDrive
attribute.
function.json property | Attribute property | Description |
---|---|---|
name | Required - the variable name used in function code for the file. See Using a OneDrive file input binding from code. | |
type | Required - must be set to onedrive . |
|
direction | Required - must be set to in . |
|
identity | Identity | Required - The identity that will be used to perform the action. Can be one of the following values:
|
userId | UserId | Needed if and only if identity is set to userFromId . A user principal ID associated with a previously logged-in user. |
userToken | UserToken | Needed if and only if identity is set to userFromToken . A token valid for the function app. |
path | Path | Required - the path in OneDrive to the file. |
This binding requires the following Azure AD permissions:
Resource | Permission |
---|---|
Microsoft Graph | Read user files |
The binding exposes the following types to .NET functions:
- byte[]
- Stream
- string
- Microsoft.Graph.DriveItem
The OneDrive file output binding modifies the contents of a file stored in OneDrive.
This section contains the following subsections:
See the language-specific example:
The following example writes to a file that is stored in OneDrive.
The function.json file defines an HTTP trigger with a OneDrive output binding:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"name": "myOneDriveFile",
"type": "onedrive",
"direction": "out",
"path": "FunctionsTest.txt",
"identity": "userFromRequest"
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
The C# script code gets text from the query string and writes it to a text file (FunctionsTest.txt as defined in the preceding example) at the root of the caller's OneDrive:
using System.Net;
using System.Text;
public static async Task Run(HttpRequest req, TraceWriter log, Stream myOneDriveFile)
{
string data = req.Query
.FirstOrDefault(q => string.Compare(q.Key, "text", true) == 0)
.Value;
await myOneDriveFile.WriteAsync(Encoding.UTF8.GetBytes(data), 0, data.Length);
return;
}
The following example writes to a file that is stored in OneDrive.
The function.json file defines an HTTP trigger with a OneDrive output binding:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"name": "myOneDriveFile",
"type": "onedrive",
"direction": "out",
"path": "FunctionsTest.txt",
"identity": "userFromRequest"
},
{
"name": "res",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
The JavaScript code gets text from the query string and writes it to a text file (FunctionsTest.txt as defined in the config above) at the root of the caller's OneDrive.
module.exports = function (context, req) {
context.bindings.myOneDriveFile = req.query.text;
context.done();
};
In C# class libraries, use the OneDrive attribute.
The following table explains the binding configuration properties that you set in the function.json file and the OneDrive
attribute.
function.json property | Attribute property | Description |
---|---|---|
name | Required - the variable name used in function code for file. See Using a OneDrive file output binding from code. | |
type | Required - must be set to onedrive . |
|
direction | Required - must be set to out . |
|
identity | Identity | Required - The identity that will be used to perform the action. Can be one of the following values:
|
UserId | userId | Needed if and only if identity is set to userFromId . A user principal ID associated with a previously logged-in user. |
userToken | UserToken | Needed if and only if identity is set to userFromToken . A token valid for the function app. |
path | Path | Required - the path in OneDrive to the file. |
This binding requires the following Azure AD permissions:
Resource | Permission |
---|---|
Microsoft Graph | Have full access to user files |
The binding exposes the following types to .NET functions:
- byte[]
- Stream
- string
- Microsoft.Graph.DriveItem
The Outlook message output binding sends a mail message through Outlook.
This section contains the following subsections:
See the language-specific example:
The following example sends an email through Outlook.
The function.json file defines an HTTP trigger with an Outlook message output binding:
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"name": "message",
"type": "outlook",
"direction": "out",
"identity": "userFromRequest"
}
],
"disabled": false
}
The C# script code sends a mail from the caller to a recipient specified in the query string:
using System.Net;
public static void Run(HttpRequest req, out Message message, TraceWriter log)
{
string emailAddress = req.Query["to"];
message = new Message(){
subject = "Greetings",
body = "Sent from Azure Functions",
recipient = new Recipient() {
address = emailAddress
}
};
}
public class Message {
public String subject {get; set;}
public String body {get; set;}
public Recipient recipient {get; set;}
}
public class Recipient {
public String address {get; set;}
public String name {get; set;}
}
The following example sends an email through Outlook.
The function.json file defines an HTTP trigger with an Outlook message output binding:
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"name": "message",
"type": "outlook",
"direction": "out",
"identity": "userFromRequest"
}
],
"disabled": false
}
The JavaScript code sends a mail from the caller to a recipient specified in the query string:
module.exports = function (context, req) {
context.bindings.message = {
subject: "Greetings",
body: "Sent from Azure Functions with JavaScript",
recipient: {
address: req.query.to
}
};
context.done();
};
In C# class libraries, use the Outlook attribute.
The following table explains the binding configuration properties that you set in the function.json file and the Outlook
attribute.
function.json property | Attribute property | Description |
---|---|---|
name | Required - the variable name used in function code for the mail message. See Using an Outlook message output binding from code. | |
type | Required - must be set to outlook . |
|
direction | Required - must be set to out . |
|
identity | Identity | Required - The identity that will be used to perform the action. Can be one of the following values:
|
userId | UserId | Needed if and only if identity is set to userFromId . A user principal ID associated with a previously logged-in user. |
userToken | UserToken | Needed if and only if identity is set to userFromToken . A token valid for the function app. |
This binding requires the following Azure AD permissions:
Resource | Permission |
---|---|
Microsoft Graph | Send mail as user |
The binding exposes the following types to .NET functions:
- Microsoft.Graph.Message
- Newtonsoft.Json.Linq.JObject
- string
- Custom object types (using structural model binding)
Webhooks allow you to react to events in the Microsoft Graph. To support webhooks, functions are needed to create, refresh, and react to webhook subscriptions. A complete webhook solution requires a combination of the following bindings:
- A Microsoft Graph webhook trigger allows you to react to an incoming webhook.
- A Microsoft Graph webhook subscription input binding allows you to list existing subscriptions and optionally refresh them.
- A Microsoft Graph webhook subscription output binding allows you to create or delete webhook subscriptions.
The bindings themselves do not require any Azure AD permissions, but you need to request permissions relevant to the resource type you wish to react to. For a list of which permissions are needed for each resource type, see subscription permissions.
For more information about webhooks, see Working with webhooks in Microsoft Graph.
The Microsoft Graph webhook trigger allows a function to react to an incoming webhook from the Microsoft Graph. Each instance of this trigger can react to one Microsoft Graph resource type.
This section contains the following subsections:
See the language-specific example:
The following example handles webhooks for incoming Outlook messages. To use a webhook trigger you create a subscription, and you can refresh the subscription to prevent it from expiring.
The function.json file defines a webhook trigger:
{
"bindings": [
{
"name": "msg",
"type": "GraphWebhookTrigger",
"direction": "in",
"resourceType": "#Microsoft.Graph.Message"
}
],
"disabled": false
}
The C# script code reacts to incoming mail messages and logs the body of those sent by the recipient and containing "Azure Functions" in the subject:
#r "Microsoft.Graph"
using Microsoft.Graph;
using System.Net;
public static async Task Run(Message msg, TraceWriter log)
{
log.Info("Microsoft Graph webhook trigger function processed a request.");
// Testable by sending oneself an email with the subject "Azure Functions" and some text body
if (msg.Subject.Contains("Azure Functions") && msg.From.Equals(msg.Sender)) {
log.Info($"Processed email: {msg.BodyPreview}");
}
}
The following example handles webhooks for incoming Outlook messages. To use a webhook trigger you create a subscription, and you can refresh the subscription to prevent it from expiring.
The function.json file defines a webhook trigger:
{
"bindings": [
{
"name": "msg",
"type": "GraphWebhookTrigger",
"direction": "in",
"resourceType": "#Microsoft.Graph.Message"
}
],
"disabled": false
}
The JavaScript code reacts to incoming mail messages and logs the body of those sent by the recipient and containing "Azure Functions" in the subject:
module.exports = function (context) {
context.log("Microsoft Graph webhook trigger function processed a request.");
const msg = context.bindings.msg
// Testable by sending oneself an email with the subject "Azure Functions" and some text body
if((msg.subject.indexOf("Azure Functions") > -1) && (msg.from === msg.sender) ) {
context.log(`Processed email: ${msg.bodyPreview}`);
}
context.done();
};
In C# class libraries, use the GraphWebHookTrigger attribute.
The following table explains the binding configuration properties that you set in the function.json file and the GraphWebHookTrigger
attribute.
function.json property | Attribute property | Description |
---|---|---|
name | Required - the variable name used in function code for the mail message. See Using an Outlook message output binding from code. | |
type | Required - must be set to graphWebhook . |
|
direction | Required - must be set to trigger . |
|
resourceType | ResourceType | Required - the graph resource for which this function should respond to webhooks. Can be one of the following values:
|
Note
A function app can only have one function that is registered against a given resourceType
value.
The binding exposes the following types to .NET functions:
- Microsoft Graph SDK types relevant to the resource type, such as
Microsoft.Graph.Message
orMicrosoft.Graph.DriveItem
. - Custom object types (using structural model binding)
The Microsoft Graph webhook input binding allows you to retrieve the list of subscriptions managed by this function app. The binding reads from function app storage, so it does not reflect other subscriptions created from outside the app.
This section contains the following subsections:
See the language-specific example:
The following example gets all subscriptions for the calling user and deletes them.
The function.json file defines an HTTP trigger with a subscription input binding and a subscription output binding that uses the delete action:
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"type": "graphWebhookSubscription",
"name": "existingSubscriptions",
"direction": "in",
"filter": "userFromRequest"
},
{
"type": "graphWebhookSubscription",
"name": "subscriptionsToDelete",
"direction": "out",
"action": "delete",
"identity": "userFromRequest"
},
{
"type": "http",
"name": "res",
"direction": "out"
}
],
"disabled": false
}
The C# script code gets the subscriptions and deletes them:
using System.Net;
public static async Task Run(HttpRequest req, string[] existingSubscriptions, IAsyncCollector<string> subscriptionsToDelete, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
foreach (var subscription in existingSubscriptions)
{
log.Info($"Deleting subscription {subscription}");
await subscriptionsToDelete.AddAsync(subscription);
}
}
The following example gets all subscriptions for the calling user and deletes them.
The function.json file defines an HTTP trigger with a subscription input binding and a subscription output binding that uses the delete action:
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"type": "graphWebhookSubscription",
"name": "existingSubscriptions",
"direction": "in",
"filter": "userFromRequest"
},
{
"type": "graphWebhookSubscription",
"name": "subscriptionsToDelete",
"direction": "out",
"action": "delete",
"identity": "userFromRequest"
},
{
"type": "http",
"name": "res",
"direction": "out"
}
],
"disabled": false
}
The JavaScript code gets the subscriptions and deletes them:
module.exports = function (context, req) {
const existing = context.bindings.existingSubscriptions;
var toDelete = [];
for (var i = 0; i < existing.length; i++) {
context.log(`Deleting subscription ${existing[i]}`);
todelete.push(existing[i]);
}
context.bindings.subscriptionsToDelete = toDelete;
context.done();
};
In C# class libraries, use the GraphWebHookSubscription attribute.
The following table explains the binding configuration properties that you set in the function.json file and the GraphWebHookSubscription
attribute.
function.json property | Attribute property | Description |
---|---|---|
name | Required - the variable name used in function code for the mail message. See Using an Outlook message output binding from code. | |
type | Required - must be set to graphWebhookSubscription . |
|
direction | Required - must be set to in . |
|
filter | Filter | If set to userFromRequest , then the binding will only retrieve subscriptions owned by the calling user (valid only with HTTP trigger). |
The binding exposes the following types to .NET functions:
- string[]
- Custom object type arrays
- Newtonsoft.Json.Linq.JObject[]
- Microsoft.Graph.Subscription[]
The webhook subscription output binding allows you to create, delete, and refresh webhook subscriptions in the Microsoft Graph.
This section contains the following subsections:
See the language-specific example:
The following example creates a subscription. You can refresh the subscription to prevent it from expiring.
The function.json file defines an HTTP trigger with a subscription output binding using the create action:
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"type": "graphWebhookSubscription",
"name": "clientState",
"direction": "out",
"action": "create",
"subscriptionResource": "me/mailFolders('Inbox')/messages",
"changeTypes": [
"created"
],
"identity": "userFromRequest"
},
{
"type": "http",
"name": "$return",
"direction": "out"
}
],
"disabled": false
}
The C# script code registers a webhook that will notify this function app when the calling user receives an Outlook message:
using System;
using System.Net;
public static HttpResponseMessage run(HttpRequestMessage req, out string clientState, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
clientState = Guid.NewGuid().ToString();
return new HttpResponseMessage(HttpStatusCode.OK);
}
The following example creates a subscription. You can refresh the subscription to prevent it from expiring.
The function.json file defines an HTTP trigger with a subscription output binding using the create action:
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"type": "graphWebhookSubscription",
"name": "clientState",
"direction": "out",
"action": "create",
"subscriptionResource": "me/mailFolders('Inbox')/messages",
"changeTypes": [
"created"
],
"identity": "userFromRequest"
},
{
"type": "http",
"name": "$return",
"direction": "out"
}
],
"disabled": false
}
The JavaScript code registers a webhook that will notify this function app when the calling user receives an Outlook message:
const uuidv4 = require('uuid/v4');
module.exports = function (context, req) {
context.bindings.clientState = uuidv4();
context.done();
};
In C# class libraries, use the GraphWebHookSubscription attribute.
The following table explains the binding configuration properties that you set in the function.json file and the GraphWebHookSubscription
attribute.
function.json property | Attribute property | Description |
---|---|---|
name | Required - the variable name used in function code for the mail message. See Using an Outlook message output binding from code. | |
type | Required - must be set to graphWebhookSubscription . |
|
direction | Required - must be set to out . |
|
identity | Identity | Required - The identity that will be used to perform the action. Can be one of the following values:
|
userId | UserId | Needed if and only if identity is set to userFromId . A user principal ID associated with a previously logged-in user. |
userToken | UserToken | Needed if and only if identity is set to userFromToken . A token valid for the function app. |
action | Action | Required - specifies the action the binding should perform. Can be one of the following values:
|
subscriptionResource | SubscriptionResource | Needed if and only if the action is set to create . Specifies the Microsoft Graph resource that will be monitored for changes. See Working with webhooks in Microsoft Graph. |
changeType | ChangeType | Needed if and only if the action is set to create . Indicates the type of change in the subscribed resource that will raise a notification. The supported values are: created , updated , deleted . Multiple values can be combined using a comma-separated list. |
The binding exposes the following types to .NET functions:
- string
- Microsoft.Graph.Subscription
There are two approaches to refreshing subscriptions:
- Use the application identity to deal with all subscriptions. This will require consent from an Azure Active Directory admin. This can be used by all languages supported by Azure Functions.
- Use the identity associated with each subscription by manually binding each user ID. This will require some custom code to perform the binding. This can only be used by .NET functions.
This section contains an example for each of these approaches:
See the language-specific example:
The following example uses the application identity to refresh a subscription.
The function.json defines a timer trigger with a subscription input binding and a subscription output binding:
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 * * */2 * *"
},
{
"type": "graphWebhookSubscription",
"name": "existingSubscriptions",
"direction": "in"
},
{
"type": "graphWebhookSubscription",
"name": "subscriptionsToRefresh",
"direction": "out",
"action": "refresh",
"identity": "clientCredentials"
}
],
"disabled": false
}
The C# script code refreshes the subscriptions:
using System;
public static void Run(TimerInfo myTimer, string[] existingSubscriptions, ICollector<string> subscriptionsToRefresh, TraceWriter log)
{
// This template uses application permissions and requires consent from an Azure Active Directory admin.
// See https://go.microsoft.com/fwlink/?linkid=858780
log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
foreach (var subscription in existingSubscriptions)
{
log.Info($"Refreshing subscription {subscription}");
subscriptionsToRefresh.Add(subscription);
}
}
The following example uses the application identity to refresh a subscription.
The function.json defines a timer trigger with a subscription input binding and a subscription output binding:
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 * * */2 * *"
},
{
"type": "graphWebhookSubscription",
"name": "existingSubscriptions",
"direction": "in"
},
{
"type": "graphWebhookSubscription",
"name": "subscriptionsToRefresh",
"direction": "out",
"action": "refresh",
"identity": "clientCredentials"
}
],
"disabled": false
}
The JavaScript code refreshes the subscriptions:
// This template uses application permissions and requires consent from an Azure Active Directory admin.
// See https://go.microsoft.com/fwlink/?linkid=858780
module.exports = function (context) {
const existing = context.bindings.existingSubscriptions;
var toRefresh = [];
for (var i = 0; i < existing.length; i++) {
context.log(`Deleting subscription ${existing[i]}`);
todelete.push(existing[i]);
}
context.bindings.subscriptionsToRefresh = toRefresh;
context.done();
};
The following example uses the user identity to refresh a subscription.
The function.json file defines a timer trigger and defers the subscription input binding to the function code:
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 * * */2 * *"
},
{
"type": "graphWebhookSubscription",
"name": "existingSubscriptions",
"direction": "in"
}
],
"disabled": false
}
The C# script code refreshes the subscriptions and creates the output binding in code, using each user's identity:
using System;
public static async Task Run(TimerInfo myTimer, UserSubscription[] existingSubscriptions, IBinder binder, TraceWriter log)
{
log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
foreach (var subscription in existingSubscriptions)
{
// binding in code to allow dynamic identity
using (var subscriptionsToRefresh = await binder.BindAsync<IAsyncCollector<string>>(
new GraphWebhookSubscriptionAttribute() {
Action = "refresh",
Identity = "userFromId",
UserId = subscription.UserId
}
))
{
log.Info($"Refreshing subscription {subscription}");
await subscriptionsToRefresh.AddAsync(subscription);
}
}
}
public class UserSubscription {
public string UserId {get; set;}
public string Id {get; set;}
}
[!div class="nextstepaction"] Learn more about Azure functions triggers and bindings