Handle HTTP request failures in Power Automate

If the HTTP request you make in Power Automate gets a 200 OK response, all is good but if the HTTP response has the status codes like 408 – Request Timeout, 429 – Too many requests, 522 – Connection Timeout, 404 – Not found, 400 – Bad request etc there is a problem which needs attention. This post will show you how to handle HTTP request failures using

  • Retry Policy
  • Custom Retry for requests which cannot be handled by Retry Policy
  • Take actions based on HTTP status code

Retry Policy:

A Retry Policy specifies how the action or trigger retries a request when the original request times out or fails. The retry policy handles the following HTTP status codes

  1. 408 – Request Timeout
  2. 429 – Too many requests
  3. 5xx – xx refers to any number like 500 – Internal server error, 503 – Service Unavailable, 522 – Connection timed out etc

HTTP Action supports retry policy and by default the action retries 4 times at exponentially increasing intervals if there is a request failure. In the HTTP action, navigate to settings

If you have to retry the request for more than 4 times or set some custom interval between retries, you can do so by changing the retry policy from Default to Fixed interval or Exponential interval as shown below

Exponential Interval:

The policy waits for a random interval before sending the next request. The random interval is selected from an exponentially growing range.

Fixed Interval:

The policy waits for a specified interval before sending the next request.

There will not be any retry if the policy is set to None. For more details on the retry policies, go through this documentation from Microsoft. Find below screenshot of a Fixed Interval Retry Policy which attempts to make a HTTP request 5 more times after the first failed request with a 10-minute delay between each attempt.

The retry interval accepts value in ISO 8601 format. In the above screenshot for the interval field with value PT10M

P is the duration designator and T is the time designator, where M is the minute designator. PT5S translates to 5 seconds. For testing the policy with the HTTP action you can get sample http request links with different status codes request url’s from https://httpstat.us/.

The retry information will be logged in the flow Run history as shown below

Custom Retry for requests which cannot be handled by Retry Policy:

The retry policy handles only HTTP status codes 408, 429 and 5xx. On this section let us see how to handle the other types of HTTP status codes or non-retry-able errors. Let us take an example with a requirement to retry HTTP request with status code 400 – Bad request till the request succeeds.

Step 1: Initialize a boolean variable ExecuteHTTPAction with the default value true. For the Boolean value use the expression true.

Step 2: Add a Do until control. The loop runs for a maximum of 60 times (Default setting) until the HTTP request succeeds or the condition is met. The Left side placeholder should have the ExecuteHTTPAction variable as a value and the right side should have Boolean variable False. Use Expression to enter the Boolean variable false.

Toggle between Edit in advance mode and Edit in basic mode if the right side placeholder to enter value is disabled.

Step 3: Add the HTTP request action and an action to Set variable ExecuteHTTPAction named as Set Variable – HTTP Action Success. Set the value of the variable to boolean false which means on HTTP action success (200 OK), there should not be any retry.

Step 4: Once the Set variable action is added, just above the action click + and Add a parallel branch as shown in the above picture. On the other side of the branch add an action Set variable named as Set variable – HTTP Action Failure to set the ExecuteHTTPAction variable to true which means there should be retry

Step 5: The last step is to configure Run after for the action Set variable – HTTP Action Failure. Find below screenshot for the Run after configuration

No change is required for Set variable – HTTP Action Success, just ensure the Set variable – HTTP Action Failure has the Run After has failed. You can add a Delay action after the parallel branch to make sure the HTTP request is made after certain interval based on scenario. You can also add scope controls for TRY, RETRY etc.

Alternative Method:

The other way to do this without adding the parallel branch is as shown below

Take actions based on HTTP status code:

If you have to take different actions based on the HTTP status code, for example call a different API when there is an HTTP 404 – Not found etc. The quick way to do this is get the HTTP status code of the HTTP request by adding the Compose action below the HTTP request action and select the Status code from the Dynamic content which is an Output of the action HTTP.

Now configure the run after for the compose action as shown below

The compose action would now be able to capture all type of HTTP status code. With the status code in hand, add a switch control to take different actions based on HTTP status code.

Summary:

On this post we have seen how to handle different HTTP request failures codes with options to Retry in your Power Automate flow. You can apply this technique to handle HTTP request made via custom connector, SharePoint Connector etc.  Hope you have found this informational & thanks for reading. If you are visiting my blog for the first time, please do look at my other blogposts.

Everything to know about Power Automate REST API to manage and administer your flows

Power Automate Management connector enables interaction with Power Automate management service to manage your flows with different actions to create, edit and update flows. If you want to do more but you were not able to find an action with this connector for e.g. get details on the Runs the flow has made, as of now there is no action which gets the run details of a flow with the Power Automate Management connector. So how to get the Runs the flow has made and even more actions like turning on/off/disable a flow etc? There are REST APIs with different endpoints for Power Automate, as of now there is no documentation from Microsoft on these API’s but there is documentation for Azure Logic Apps REST API. It is quite easy to convert the Logic Apps REST API for Power Automate operations. The APIs are secured with Azure AD OAuth 2.0, in this blog post let’s see how to call these API’s using

  1. Custom Connector
  2. Authorization code flow
  3. Implicit flow

Let’s start this post with the API endpoint to list the flow runs for Azure Logic Apps & Power Automate. Find below the API endpoint for Azure Logic apps as per this documentation to list the Workflow Runs

Azure Logic Apps – List Workflow Runs:

GET

https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Logic/workflows/{workflowName}/runs?api-version=2016-06-01

Find below the API endpoint for Power Automate to list the flow runs, the URL was formed based on the above Azure Logic apps URL.

Power Automate – List flow Runs:

GET

https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/xxx-flow-env-guid-xxx/flows/xxx-flow-guid-xxx/runs?api-version=2016-11-01

You can easily notice the differences in the table below:

Azure Logic AppsPower Automate
https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/https://api.flow.microsoft.com/
providers/Microsoft.Logicproviders/Microsoft.ProcessSimple/environments/xxx-flow-env-guid-xxx
workflows/{workflowName}flows/xxx-flow-guid-xxx
runsruns
api-version=2016-06-01api-version=2016-11-01

The API version for Power Automate can be different in Microsoft 365 when compared against Azure Logic Apps. This information can be identified using fiddler or any browser-based developer tool (Network) by analyzing the http request traffic the portal makes to API endpoints for different operations after logging in to the Power Automate Portal. Find below screenshot regarding the API version on the home screen of the portal

As a first step towards accessing the API endpoint for Power Automate, there must be an Azure Active directory app registered in the AD tenant of the Microsoft 365 environment which has the Power Automate environment.

Azure Active Directory App Registration:

Register an application in Azure AD and obtain the client id, client secret & tenant id for the registered application. After the app is registered, follow the below steps to grant permission for the app to call the Power Automate Flow APIs:

  1. In the App, click the API permission under the Manage blade and then click + Add a permission. Under the Microsoft APIs tab, click Flow Service as shown below
  1. The flow API as of now supports only delegated permission (User Context). Now select the Permission based on the requirement. For this post, I have selected the permission Flows.Manage.All for listing the runs of the flow
  1. Add a Web Redirect URI https://global.consent.azure-apim.net/redirect as shown below to use the app in a custom connector

The app is registered with the necessary configurations, let us now see how to call the Power Automate API using a custom connector. The custom connector takes care of generating the authorization token required to access the API using the authorization code flow.

Custom Connector to call the Power Automate APIs:

A custom connector is a wrapper around a REST API (Logic Apps also supports SOAP APIs) that allows Logic Apps, Power Automate or Power Apps to communicate with that REST or SOAP API. In the Power Automate portal expand Data on the left panel > Custom connectors > + New custom connector > Create from blank

After entering the connector name, in the General information enter the description and Host name to api.flow.microsoft.com

Now click Security on the right bottom corner to enter the Azure AD application information for the OAuth 2.0 authentication type. Under the section OAuth 2.0

After the above information is filled in, click Create connector which autogenerates the Redirect URL https://global.consent.azure-apim.net/redirect. This is the URL we have added as a Redirect Web URI in the Azure AD application. The connector is now ready for the actions to list the flow Runs with the help of Power Automate REST API endpoint.

Action to List Flow Runs:

The Power Automate REST API endpoint to list the flow runs is

Http Request Mode: GET

Request URI: https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/{FlowEnvironment}/flows/{FlowGUID}/runs?api-version=2016-11-01

After the custom connector is created in the above step, now click the Definition tab of the Custom Connector > click + New action to enter Summary, Description & Operation ID of the action > Click + Import from sample to enter the above API endpoint to list the flow runs in URL box and Verb as GET > Click Import

Click Update connector. To the test the action, click Test at the bottom right corner. In the following screen, create a connection and then pass the parameters for Power Automate Environment, Flow GUID & API Version of the Power Automate REST API. Flow GUID & Environment ID can be obtained from any of your existing flow in the environment. To get these information navigate to the My Flows section in the Power Automate portal and click any flow, the information will be on the URL as shown on the below sample

Flow Details URL: https://emea.flow.microsoft.com/manage/environments/xxxx-flow-env-guid acb/flows/flow-guid-xxxx-xxxx-xxxxxxxxxxx/details

After entering the details, click Test operation to get the list of run details the flow had till now. You can get details like the status of the flow, flow start time & endtime, flow run id etc on the response

Copy the Response body from the above screen to add it to the default response for the action. Click the + Add default response on the action definition screen > Click + Import from sample > Paste the copied value to the Body section > Click Import.

The above step is recommended to parse the information of the response either in Power Automate or Power Apps. The sample Custom connector used for this blogpost can be downloaded from here.

Find below some REST API endpoints for different operations:

Get Flow Details:

HTTP Request Type: GET

URL: https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/{FlowEnvironment}/flows/{FlowGUID}?api-version=2016-11-01

Resubmit a flow run:

HTTP Request Type: POST

URL: https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/{FlowEnvironment}/flows/{FlowGUID}/triggers/manual/histories/{FlowRunID}/resubmit?api-version=2016-11-01

Cancel a flow run:

HTTP Request Type: POST

URL: https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/{FlowEnvironment}/flows/{FlowGUID}/runs/{FlowRunID}/cancel?api-version=2016-11-01

Turn On or Turn Off a Flow:

HTTP Request Type: POST

Turn Off URL: https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/ {FlowEnvironment}/flows/{FlowGUID}/stop?api-version=2016-11-01

Turn On URL: https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/ {FlowEnvironment}/flows/{FlowGUID}/start?api-version=2016-11-01

Add a Owner:

HTTP Request Type: POST

URL: https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/ {FlowEnvironment}/flows/{FlowGUID}?api-version=2016-11-01

Body:

{“put”:[{“name”:”userGUIDhere”,”properties”:{“principal”:{“id”:”userGUIDhere”,”displayName”:”userDisplayNamehere”,”email”:”userUPNhere”,”type”:”User”}}}]}

Delete a Flow:

HTTP Request Type: DELETE

Turn Off URL: https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/ {FlowEnvironment}/flows/{FlowGUID}?api-version=2016-11-01

The above operations are just some samples, if you would to get the REST API endpoint details for different operations, go through the Logic Apps rest API documentation. You can also use Fiddler tool or browser developer tools to help you in finding the corresponding API endpoints after logging in to the Power Automate portal and then performing various operations within the portal interface.

Custom connector takes care of generating the token automatically to call the Power Automate REST APIs secured with OAuth but if you have to call these API programmatically in an application, you can use any one of the below authentication flows to generate the token.

Authorization code flow for token generation:

As the first step to generate the token using Authorization code flow, add the Redirect URI in the Azure Active directory app for your application. For this example, I have added http://localhost/ as a Redirect URI for the Web platform as shown below

Make the above change on the Azure AD application which was registered initially in this post to access Power Automate REST API. Construct the following URL after replacing the tenantId and azureAppId to generate the code in any browser for generating a token

https://login.microsoftonline.com/tenantId/oauth2/authorize?
client_id=azureAppId
&response_type=code
&redirect_uri=http://localhost/
&scope=https://service.flow.microsoft.com//.default

After the above URL is accessed in the browser, you will be prompted to sign-in. Once the sign-in is complete, a code will be generated in the below format on the browser address bar as a response to the sign-in

http://localhost/?code=0.xxxxxxxxxxxxxxxxAA&session_state=88f349ba-63e3-4064-b9c9-992ba6c5606c#

The code can be used to redeem for an access token. Make the following HTTP request to generate the access token after replacing the tenantId on the request URL

Request Type: POST

Request URL: https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token

Body:

client_id= azureAppId
&scope=https://service.flow.microsoft.com//.default 
&code=0.xxxxxxxxxxxxxxxxAA
&redirect_uri=http://localhost/
&grant_type=authorization_code
&client_secret=appClientSecret

Replace the AzureAppId, code value copied from the above request and the appClientSecret.

Headers:

Key: Content-Type

Value: application/x-www-form-urlencoded

Find screenshot below for the Postman request

The generated token can be used to access different Power Automate REST API endpoints based on the permissions you have consented to the Azure AD application by passing the token on the Authorization header as Bearer.

Reference for the error message I was receiving while working this flow “Access token has been obtained from wrong audience”: https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1735

Implicit flow for token generation:

To generate a token using implicit flow, enable the following setting on the Azure Active directory app

Construct the following URL after replacing the tenantId and azureAppId to generate the access token directly in any browser

https://login.microsoftonline.com/tenantId/oauth2/v2.0/authorize?
client_id=azureAppId
&response_type=token
&redirect_uri=http://localhost/
&scope=https://service.flow.microsoft.com//.default

Or

https://login.microsoftonline.com/common/oauth2/authorize?resource=https://service.flow.microsoft.com/&response_type=token&client_id=azureAppId&redirect_uri=http://localhost/

After any of the above URL is accessed in the browser, you will be prompted to sign-in. Once the sign-in is complete, access token will be generated in the below format on the browser address bar as a response to the sign-in

http://localhost/#access_token=exxxxxxxxxxxxx&token_type=Bearer&expires_in=3599&scope=https://service.flow.microsoft.com//Flows.Manage.All https://service.flow.microsoft.com//User https://service.flow.microsoft.com//.default&session_state=88f349ba-63e3-4064-b9c9-992ba6c5606c

Microsoft recommends Authorization code flow than the implicit flow.

Refer to the following blog posts for more information on accessing an API with delegated permissions

Also go through this documentation from Microsoft which has information of the different types of connectors to automate tasks with Power Automate.

Summary: On this post we have seen how to use Power Automate REST API to manage your cloud flows. These APIs works for both individual flows (My Flows) and flows which is part of the solutions. Power Automate REST APIs are very powerful to manage your cloud flows. I can think of scenario where in you can resubmit all your failed flows programmatically leveraging these API endpoints. Microsoft has documented WEB API for Power Automate flows included in solutions. If you are visiting my blog for the first time, please do look at my other blogposts.

What is GraphQL and how to consume a GraphQL Query based API in Power Automate

I had a recent requirement to call a GraphQL based API secured with OAuth2 in Power Automate, this blog post is to share my learnings on GraphQL & how to call them in Power Automate. Let us quickly see some introduction to GraphQL

GraphQL is an open-source query language for your APIs with a service-side runtime for executing the queries based on pre-defined schema. It is not tied to any specific database but rather backed by your existing code and data.

  • A GraphQL API is different from a REST API in that it allows the client application to query for certain fields of resources. Send a GraphQL query to your API and get exactly what you need, like the name of a user and only receive that data.
  • GraphQL APIs get’s all the data a client needs in a single request.
  • It replaces multiple REST requests with a single call to fetch the data you specify.
  • Provides an abstraction layer to the client, which means that clients do not need to query multiple URLs to access different data.  

Find some comparisons against REST

RESTGraphQL
HTTP Verbs (GET, POST, PATCH, PUT, DELETE) determines the operation to be performedYou will provide a JSON body aka GraphQL query whether you have to read or fetch values (GET) or a mutation (POST, PATCH, PUT, DELETE) to write values
Multiple API Endpoints http://api.com/users http://api.com/products etcSingle API Endpoint
http://api.com/graphql

When a HTTP GraphQL request is made with a query, the GraphQL server parses the query and respond back with data usually in a specific JSON format. There can also be variables in a query which makes it more powerful and dynamic. In GraphQL, the HTTP verb is predominantly POST but there can be implementations where Query & Variables are sent in URL encoded query parameters in the URL. I have used GitHub to learn & test GraphQL queries against my GitHub account.

GitHub GraphQL Explorer:

Github has GraphQL API that allows you to query and perform operations against repositories, users, issues, etc. To follow along this blogpost, sign in with your GitHub account on the GitHub GraphQL explorer URL https://docs.github.com/en/graphql/overview/explorer for testing some GraphQL queries

  1. Create a Repository in your GitHub account
  2. Get all your existing repositories

Let’s make first query on the explorer to get your GitHub Id for creating a new repo, the query is

{
  viewer {
    login
    id    
  }
}

In Explorer

Type your queries on the left side panel and hit play to see the JSON response on the right side. Click the Docs link on the right top corner to go through the documentation. The GitHub graphql explorer can be a great starting point to learn and to write queries

Tip: Hitting Ctrl+Space on the explorer will show you all the available fields that you can query against the API.

Create a Repository in your GitHub account:

Find below the query & variables to create a Repo in your GitHub account. The ownerId on the query variables should be value copied from the previous query. The other observation on the query is we are using mutation since we are creating a repository

Query to create a Repo with out passing a query variable:

mutation createRepo {
 createRepository(input:
{
  name: "GraphQLDemoRepo-Blog",
  ownerId: "xxxxxxxxxxxxxxxxxxxxxx",
  visibility: PRIVATE
}){
  repository
  {
    name
    createdAt
  }
}
}

Get all your existing repositories

Find below the query to get all your existing repositories

{
  viewer {
    name
    repositories(first: 100) {
      totalCount
      nodes {
        name
      }
    }
  }
}

Till now we have seen couple of example queries in GitHub explorer, let us now see how to consume them in Power Automate

Call a GraphQL query in Power Automate:

HTTP connector in Power Automate can be used to call a GraphQL query based API but you will have to first convert the GraphQL query (Query+Variables) to a HTTP request with raw body. You can use the Postman utility to help you with the conversion. To call the above mentioned GraphQL query to create a Repo in Postman, the first step is create a Personal Access token. Create the token as per the instructions given in the following documentation with the scope repo selected

https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token#creating-a-token

In Postman, add a new request as per the following detail

Method: POST

Request URL: https://api.github.com/graphql

Authorization Type: Bearer Token

Token value should be the Personal Access token you have generated above. Find below screenshot for your reference in order to set the authorization token

In the request Body tab, enter the Query and GraphQL variables for creating the repo after selecting the Body type to GraphQL from none

On the query tab, CTRL+Space also works in Postman which autoprompts with some suggestions for fields.

Execute the request by clicking Send button which will create a New repo by the Name GraphQLDemo-blog in your github account. To call this GraphQL query in Power Automate, click the Code button as shown above on the right panel of the postman request and then select HTTP to auto generate a code snippet for making a HTTP request with raw body

Copy the request body as shown above. On the Power Automate HTTP connector, enter the following details to create the Repo

Method: POST

URI: https://api.github.com/graphql

Headers:

Key: Authorization

Value: Bearer PersonalAccessToken

Body: Value copied from Postman

Test the flow. If all is well you can see the repo created in your github account. Find below screenshot from run history

References:

https://graphql.org/learn/

https://docs.github.com/en/graphql/overview/about-the-graphql-api

https://docs.github.com/en/graphql/guides/forming-calls-with-graphql#about-queries

https://www.apollographql.com/docs/apollo-server/deployment/azure-functions/

Playground to test GraphQL queries (No Authentication required): http://graphql.github.io/swapi-graphql/

Summary: On this post we have seen how to call a GraphQL query based API from Github in Power Automate using a HTTP connector to create a Repo, this can be replicated to consume any other GraphQL based APIs. You can also construct dynamic request body on the HTTP connector for various operations. Hope you have found this informational & thanks for reading. If you are visiting my blog for the first time, please do look at my other blogposts.

Call Microsoft Graph API as a signed in user with delegated permission in Power Automate or Azure Logic apps using HTTP Connector

If you have a requirement to access graph endpoint as a signed in user/account on an instant/automated/scheduled flow, this blog post will help you with instructions and steps to access the Microsoft graph API with delegated permissions using the

  1. HTTP connector
  2. Invoke an HTTP request connector

There are resources (Presence information, Planner etc) in Microsoft graph which is available only as delegated permissions and not as application permission. Application permissions can be granted only by an administrator but users can register an application with delegated permission (Except All permission) unless the IT team has restricted the app registration by users.

Access Graph API using HTTP connector:

I have used the HTTP connector to generate a token for accessing the Graph API using the OAuth resource owner Password Credentials grant authentication flow supported by Microsoft Identity platform with the User ID and Password. Once we have the access token, the request to the Graph API endpoint will be made. To follow along this post be ready with the following

Pre-Requisites:

  1. Access to HTTP Premium Connector in Power Automate
  2. Access to register Azure AD Application in Azure AD Portal
  3. A service account without MFA enabled
    1. User ID
    1. Password

If you have an account with MFA enabled, then you should be creating a Custom connector. I have written a blog post on creating a custom connector to call Microsoft Graph API for Power Apps and Power Automate.

Azure Active Directory Application:

Register an application in Azure AD and obtain the client id, client secret & tenant id for the registered application. In this example I have added the delegated permission Presence.Read to get the presence information of the service account.

Add the redirect URI for the web http://localhost as shown on the screenshot below.

The Web redirect URI http://localhost/ is required to provide consent for the Azure AD application for the permission scope by the service account. The consent can be provided by an admin to use this application in flow by all users or the consent has to be provided by an individual user. To provide consent by an individual user in this case by the service account, construct the following url using the tenant ID, Client ID and the scope (ex. Presence.Read)

Individual User Consent URL:

https://login.microsoftonline.com/yourtenantID/oauth2/v2.0/authorize?
client_id=azureadappclientid
&response_type=code
&redirect_uri=http://localhost/
&response_mode=query
&scope=https://graph.microsoft.com/Presence.Read

If there are multiple delegated permissions, the scope should be separated by a space (%20)

scope=https://graph.microsoft.com/Presence.Read%20
https://graph.microsoft.com/Sites.Read.all

Now login to Office.com with the service account and enter the above User Consent url on a separate tab for the consent which will bring up a screen similar to the one shown below

Now Click the Accept button to provide consent for the requested permission for the service account. After the Accept button is clicked there will be a message stating that this site cannot be reached or something similar with the url like below on the browser address bar

http://localhost/?code=xxxxxxxxxxxxxxxxxx&session_state=xxxx-xxx-xxx-xx-xxxxx

The consent is provided, to validate the consent login to My Applications link url and the select the Azure AD application from the list and then click Manage your application as shown below

Find below screenshot with consent for Presence.Read permission. To revoke the permission, click Revoke permissions

To provide Admin consent for all the users to use this app in the flow, the URL is

https://login.microsoftonline.com/yourtenantID/adminconsent?client_id=azureadappclientid

Power Automate Flow:

Now we are ready to generate the graph token using the HTTP connector in flow which is a pre-requisite to call the Graph API endpoint. To generate a token in Flow

  1. Store the Client Secret on a String variable
  2. Make the following HTTP request using the HTTP connector

HTTP Method: POST

URI: https://login.microsoftonline.com/yourtenantID/oauth2/v2.0/token

Headers: Content-Type: application/x-www-form-urlencoded

Body:

Replace the client id, service account username and password

client_id=azureadappclientid&username=serviceaccount@yourdomain.com&password=serviceaccountpassword&grant_type=password&client_secret=azureadappclientsecret&scope=Presence.Read%20offline_access

For the client secret and password (only if there is special character), make sure to URL encode using the expression encodeUriComponent(variables(‘clientSecret’)) else the request will fail due to the presence of special characters.

If there is no consent provided by the user/service account for the Azure AD application then the above HTTP request will generate the following error

{“error”:”invalid_grant”,”error_description”:”AADSTS65001: The user or administrator has not consented to use the application with ID ‘xxxxxxx-65xx-47e0-xxxx-xxxxx0bb22′ named AzureADAppName’.

To extract the token from the above request, add the parse JSON action with Content from the HTTP request body and the following schema

{
    "type": "object",
    "properties": {
        "token_type": {
            "type": "string"
        },
        "scope": {
            "type": "string"
        },
        "expires_in": {
            "type": "integer"
        },
        "ext_expires_in": {
            "type": "integer"
        },
        "access_token": {
            "type": "string"
        },
        "refresh_token": {
            "type": "string"
        }
    }
}

Add the Body from the dynamic content from the HTTP – GET Token action to the content of the Parse JSON action

Include the access token when calling the Microsoft Graph API on the Headers sections as shown below. The access_token is from the output of the Parse JSON action

If you run the flow, you can now see the response with the presence information of the service account as shown below

Use Azure Key vault connector to secure the Client Secret & Password information in the flow.

Invoke a HTTP Request connector:

This connector can be used to fetch resources from various web services authenticated by Azure AD including Microsoft Graph in more easier way. Look for the action with the keyword invoke an HTTP request

If it is accessed for the first time, enter https://graph.microsoft.com on both Base and Azure AD resource URI and then click Sign In

Enter the Graph API endpoint on the Url of the request and select the Method

The API is executed in the context of the action’s connection as shown below. In this example it gets the profile information of the serviceaccount

If you get an error similar to { “error”: { “code”: “Forbidden”, “message”: “” } }, then it could be because the connector has a limited set of scopes. Getting Presence information is not supported with this connector as of now. If your scenario requires something more advanced or not currently supported by the connector, please use the �HTTP� connector as shown above or create a custom connector.

Reference:

https://docs.microsoft.com/en-us/graph/auth/auth-concepts#delegated-and-application-permissions

https://ashiqf.com/2021/03/16/call-microsoft-graph-api-in-power-apps-and-power-automate-using-a-custom-connector/

Summary: There are many endpoints available with Microsoft graph which can be leveraged for different use cases. Keep in mind the HTTP connector in Power Automate is Premium, you can also consider using this approach in Azure Logic apps. The access token is valid only for an hour, if you have to call a graph api after an hour from the initial token generation time the token has to be obtained again. Hope you have found this informational & thanks for reading. If you are visiting my blog for the first time, please do take a look at my other blogposts.

Trigger an Azure Webjob from Power Automate

On this post let us see how to trigger or run a WebJob from Power Automate. WebJob is a powerful service in Azure keeping in mind the supported file types or programs it can run. Before proceeding with the instructions to call a WebJob in Power Automate, let us see some basics of an Azure WebJob. WebJobs is a feature of Azure App Service that enables you to run a program or script in the same instance of the Azure web app with no additional cost. As of now it is not supported in App service plan for Linux. There are two types of WebJobs

  1. Continuous WebJob
    • Starts immediately when the WebJob is created. To keep the job from ending, the program or script typically does its work inside an endless loop.
    • Runs on all instances that the web app runs on. You can optionally restrict the WebJob to a single instance.
  2. Triggered WebJob
    • Starts only when triggered manually or on a schedule based on CRON expression.
    • Runs on a single instance that Azure selects for load balancing.

Supported file types for scripts or programs:

The following file types are supported:

  • .cmd, .bat, .exe (using Windows cmd)
  • .ps1 (using PowerShell)
  • .sh (using Bash)
  • .php (using PHP)
  • .py (using Python)
  • .js (using Node.js)
  • .jar (using Java)

Check here the documentation from Microsoft to choose between Flow, Logic Apps, Functions & Webjobs for your automation services with comparisons against each other. If you are using a Function app with a Consumption plan your function can run only to a max of 10 mins. If you have a long running task on a webjob, set this property in the App service Application setting from the Configuration blade as shown below

The above setting is to avoid idling out if there is no CPU activity. The IDLE timeout setting is set to 1 hour in the above screenshot.

Azure WebJobs SDK:

There is a Powerful Azure WebJobs SDK which simplifies the task of writing background processing code that runs in WebJobs. It makes it easier to write code that reads or writes from Azure Storage account and it also facilitates to trigger the WebJob if there is any new data on the queue, blob, table, service bus for an event driven architecture. Azure functions is built on the WebJobs SDK. If you set your web app to run continuous or scheduled (timer-trigger) WebJobs, enable the Always on setting on your web app’s Azure Configuration page to ensure that the WebJobs run reliably. This feature is available only in the Basic, Standard, and Premium tiers of the App service plan.

Create and Deploy a WebJob:

To call a WebJob from Power Automate, let us create a Triggered WebJob (.Net Framework) from Visual Studio. There is a also support for .NET Core console apps as WebJobs. Refer this documentation from Microsoft to create a WebJob from Visual Studio. In Visual studio there is a template to create a WebJob project as shown below

This is how the VS project looks like

The Program.cs has the code to ensure that the Job will be running continuously, for this case it is not required comment or remove the code which is highlighted. The Functions.cs has the code to pick up the message from the Storage Queue (Event-Driven) through the WebJobs SDK runtime, the WebApp must set to Always on to make it work. For this example, it is not required since it is going to be a triggered Job so the file Functions.cs can be deleted.

If you have any arguments to be passed from Power Automate, you can access it on your code as shown below

To deploy the WebJob, right click the project and select Publish. If there is no publish profile yet, create one or export it from Azure WebApp and then Publish. To know more about the Publish settings In the Publish tab, choose Edit as shown below

The WebJob will be now in Azure. Go to your Azure WebApp or App Service and click WebJobs under the settings blade to find the WebJob deployed from Visual Studio. Find the WebJob in the Azure portal

WebJobs API endpoint for the WebJob:

There are API endpoints available for the Azure WebJob which will be used for triggering the WebJob from Power Automate. Go through the following documentation for more details on the list of available endpoints:

https://github.com/projectkudu/kudu/wiki/WebJobs-API

To Trigger or Start a WebJob, you should have the Webhook URL from the Azure Portal. To get the URL, click Properties after selecting the WebJob as shown below

Copy the Web hook URL, User Name and Password to be later used in Power Automate. Let us trigger the WebJob from Postman client using the above information

Method: Post

URL: https://yourappname.scm.azurewebsites.net/api/triggeredwebjobs/webjobname/run

Authorization Type: Basic Auth

User Name and Password copied from the Portal

This will trigger the Job.

If there are parameters to be passed, the API would be like

https://youwebappname.scm.azurewebsites.net/api/triggeredwebjobs/youwebjobname/run?arguments={arg1} {arg2}

Trigger from Power Automate:

Till now we have the WebJob published in Azure, can we call an API in Power Automate. Yes, it is possible with the help of the Premium action HTTP as shown below

Voila! The WebJob has been triggered from Power Automate.

Summary: On this post we have seen how to call a WebJob using PowerAutomate. There is also a trigger to calla  Flow from a PowerApp, which could be used to start the WebJob. Hope you have found this informational & helpful. Let me know any feedback or comments on the comment section below

Collect response from multiple users with Adaptive Card in Teams using Power Automate

This post is in response to a comment in one of the most viewed article from my blogsite to post an Adaptive card to an user in Teams using PowerAutomate. Assume we have a use case for using Adaptive card for collecting response from n number of users based on the data from an Excel, SQL database etc. The response must be unique for users so there has to be separate instance of Adaptive card flow to each user since the flow has to wait till it gets response from the user.

To handle this scenario, we are going to create two flows

  1. Flow 1 – Send Adaptive card to collect response: This flow creates an adaptive card to collect response from each user
  2. Flow 2 – Microsoft Teams User Details: The main flow which has the user details

For this example, I will be storing the user details on an Array variable but you can dynamically generate user details or based on the data from various datasources like Excel, Database etc. Let us go ahead and create the flows

Flow 1 – Send Adaptive card to collect response

This flow will be called from flow 2 to create the Adaptive card for the team user to collect response.

Step 1: Create an Instant flow with trigger type “When a HTTP request is received” and select the method type to Post by clicking Show advanced options. Now click Use sample payload to generate schema under the section Request Body JSON Schema and the enter the following data for the team user email address and click Done to generate the schema

{
“Email”:”user@domain.onmicrosoft.com”
}

The email address of the Teams user will be passed from Flow 2 on the request body.

Step 2: Add the action Post an Adaptive card to a Teams user and wait for a response. The only change is for the field Recipient which should be Email (request body json schema) from the dynamic content of the trigger When a HTTP request is received.

Step 3: Add Create item for collecting the Team user response to the SharePoint list. Refer to the blogpost Adaptive card to an user in Teams using PowerAutomate for detailed explanation.

Step 4: Saving the flow automatically generates the HTTP POST URL, the URL will be used in the Flow 2. The complete flow should be looking like the below

We are now good to create the second flow from where the Adaptive card collect response flow will be triggered from.

Flow 2 – Microsoft Teams User Details:

This flow is the primary flow which triggers the Flow 1 for the posting the adaptive card to multiple team users.

Step 1: Create an Instant flow with the trigger type “Manually trigger a flow” and add a Array variable to store the user email address for sending the Adaptive card to collect response from multiple users.

Step 2: Add the Parse JSON action to parse the email address from the array variable and then click Generate from sample

Paste the array data as given below and click Done to automatically generate the schema for us. Then for the Content parameter in the action, select Teams Users (array variable) from the dynamic content.

[
{
“Email”: “user1@domain.onmicrosoft.com”
},
{
“Email”: “user2@domain.onmicrosoft.com”
}
]

Step 3: Add a compose action and the select the email attribute from the Parse JSON output to automatically generate a Apply to each loop as below

Step 4: Add the HTTP action to make a Post request to the HTTP url created from the first flow to post an Adaptive Card to the teams user. Find the parameters below

Method: Post

URI: HTTP Request flow URL (when a HTTP request is received) copied from the Flow 1

Headers: Key: Content-Type Value: application/json

Body:

{

  “Email”: Output of JSON Parse action (Email)-to be replaced

}

Authentication: None

This should now create Adaptive card to collect responses from multiple users irrespective of the users response to the Adaptive card.

Summary: On this post we have seen how to send adaptive card to multiple teams users using Power automate. There should be a question? Why cannot we use a Child flow concept to call the Adaptive card from the parent flow using the action Run a Child Flow available in Power platform solutions. Since we are using a For Each loop in Flow 2 Step 3 it will go to the next loop only if the first user responds to the adaptive card since there will be an action Respond to a PowerApp or flow at the end of a child flow (must have in child flow). We will have to keep in mind about the action (HTTP) and triggers (When a HTTP request is received) used in this flow are Premium. Let me know any feedback or comments on the comment section below

Create Tile view card for custom List item image attachments using PowerAutomate & JSON row view formatting

In Modern SharePoint lists you can display list item content in a more modern way using the Tiles view layout. If you have very big list with multiple columns along with picture columns you get a horizontal scroll bar on the list view, the Tiles view can solve this issue since the content will be displayed on the tile card where you can design the layout of the tile card to display the different list column values.

There are many blog posts & PnP Samples which will help you to create a Tiles view using JSON row formatting. If you are new to JSON row formatting, I recommend you to go through this link from Microsoft. Microsoft has recently brought in interface to format the list item row & do conditional formatting by creating rules based on column values

On this blog post, lets see how to create Tiles view as shown above for the Images stored as attachments in the list item. If you add an attachment to list item in SharePoint list, the attachments are stored in the following path

https://domain.sharepoint.com/sites/SiteName/Lists/ListName/Attachments/ItemID/attachmentName.extension

Components used in this blog post

  1. Power Automate Flow: To get the path of the attached file (Image file in this case), we will be creating an automated Flow which gets triggered on List item creation to get the path of the image & update it to the custom hyperlink list column (ProductPhotoHL).
  2. JSON: To create a Tile view layout using list row view formatting.

Pre-Requisites:

  • Create a SP List by the name ProductInformation with the following columns
    1. Title: Single line of text
    2. ProductPhotoHL: Hyperlink (to the image)
    3. ProductPhotoPic: Picture (to the image)
    4. ProductPrice: Number
    5. Features: Multiple lines of text
  • Couple of list items with Images as attachments after the Power automate flow is created
    1. Only images as attachments
    2. Not more than one image as an attachment

Power Automate to get the path of the Image attachment URL:

Create an automated flow with Trigger When an item is created and configure the trigger to the ProductInformation list. Add the Get Attachments action connected to the Product Information list & for Id parameter it should the List item Id (ID) selected using the dynamic content from the trigger When an item is created.

Now with the above action we have the attachment URL of the image, this must be updated to the list column ProductPhotoHL & ProductPhotoPic of the ProductInformation list in order to be displayed in the Tile view. To create the above shown Tile view ProductPhotoPic (Picture) is not required but I’ve used it show you that we can create a Thumnail of the image on the default list view using the Picture column ProductPhotoPic. By the time I am writing this post the Power Automate action Update item is not capable to update a column with Picture as a DataType but it can update a HyperLink column. Action Send an HTTP request to SharePoint to make HTTP requests to any SharePoint Rest endpoints, I’ve used this action to update the ProductPhotoPic (Picture) column as below

I’ve said this on the pre-requisite section that there should not be more than one attachment. In the Body of the HTTP request, the Url parameter for the ProductPhotoHL & ProductPhotoPic gets only the first attachment URL from the previous action “Get attachments” AbsoluteUri as dynamic content. To get the first attachment URL you can use any of the following formula from the expression

  • first(body(‘Get_attachments’))?[‘AbsoluteUri’]
  • body(‘Get_attachments’)?[0]?[‘AbsoluteUri’]

I’ve used the function first() to get the first item from the array. The flow is ready, add couple of items to the list by filling in information only for Title, ProductPrice, Features & a Image as an attachment. The flow gets triggered which will update the ProductPhotoHL & ProductPhotoPic with the image attachment url. You can download the flow template from the following GitHub repo link.

Create Tiles View layout using JSON:

I’ve used the sample from PnP List view formatting samples to create items in tile layout for images. On the sample JSON I’ve updated the column ProductPhoto to ProductPhotoHL. The updated JSON is available here for download. Now copy the JSON & go to the List view & click on the down arrow (All Items)>Format current view>Advanced mode as shown below

The Apply formatting to should be set to Entire Row & paste the JSON to box as shown on the picture and then Save it.

Now you will have another layout by the name Tiles added to the existing layouts List & Compact List as shown below, select it

Now its time to see the need for the column ProductPhotoPic of datatype Picture, with the default layout you can see the thumbnail of the image added as an attachment

Summary: There are many samples available in PnP Github repo for List Row View & Column view formatting. In document & picture libraries the Tiles view layout are added by default, there is also a Column by the name Thumbnail in a Picture library. You can display a Thumbnail view of Images in PowerApps gallery for the Images stored in Document library, go through this link for more information. If you are storing images on a seperate document library & not as an attachment, the url of the image can be added on the HyperLink column. Hope you find this interesting & helpful.

Convert Outlook Email with embedded images to PDF using PowerAutomate

Recently I’ve came across a business case with need to automate the conversion of Outlook email messages with embedded images to PDF document. This could be done manually on Outlook client using Microsoft Print to PDF or browser Print if opened using Outlook on the Web. This process can be automated with the help of PowerAutomate trigger When a new email arrives and actions Export Email, Convert File, Create file but if an email has an embedded image or HTML content it will not work as of now. There are Third party connectors in Power Automate from Muhimbi, Plumsail which might have this functionality but I’ve not tested those yet. PowerAutomate action Export Email converts the email to .eml file.

An EML file is an email message containing the content of the message, along with the subject, sender, recipient(s), and date of the message in plain text format. Once you have the .eml file change the file extension from .eml to .txt where you can see the content. If there is any embedded image it will stored in the Base64 format. You can also change the .eml file extension to .mht and open it directly in Internet Explorer

For this blogpost I’ve used third party API service from ConvertAPI to convert Email message to PDF, they have REST API endpoints to convert Word, Excel, PowerPoint, HTML, PDF and Image formats. There is also a Free Plan with ConvertAPI where you get 1500 seconds API execution time if you sign up.

You can also create your own API service hosted in Azure for conversion with the .NET libraries like iTextSharp, GroupDocs, PDFSharp etc. Let’s go ahead & create flow to

  1. Convert Email to PDF – Without Embedded image
  2. Convert Email to PDF – With Embedded image

The above two flows packages can be downloaded from Github repo.

Convert Email to PDF – Without Embedded image:

Power Automate connector OneDrive for Business has an action Convert file (preview) converts files to different formats such as PDF, HTML, JPG etc. This connector can be used to convert a simple email with out an embedded image.

Step 1: Create a flow with Automated trigger When a new email arrives & configure the trigger parameters by clicking Show advanced options.

Step 2: Add the action Export email with Message Id from the output of the previous action. This action creates the .eml file

Step 3: Add the action Create file from the connector OneDrive for Business. Select the Folder path from your One drive, Enter the File Name for the .eml file & the File Content should be Body from the output of the action Export email (Previous). Find the screenshot below

Step 4: Add the action Convert file from the connector OneDrive for Business with Id from the output of the previous action Create File.

Step 5: Add the action Create file from the connector OneDrive for Business. This step is for storing the PDF file back to the OneDrive. Select the Folder path from your One drive to store the PDF file, Enter the File Name for the PDF file & the File Content should be File content from the output of the action Convert file. Find screenshot below

Note: The storage location I’ve chosen is Onedrive, you can choose SharePoint, Azure blob etc. Based on the need you can choose to delete the .eml files after the file conversion is done.

Convert Email to PDF – With Embedded image:

As already said the previous flow will not convert an email with embedded image as expected. Be ready with the API endpoint from ConvertAPI to convert email to PDF. The endpoint will have the secret as a query string shown as below

https://v2.convertapi.com/convert/eml/to/pdf?Secret=yoursecretkeyfromconvertapi

Note: On this flow I will be using the .eml file generated from the previous flow.

Step 1: Create a flow with Instant trigger Manually trigger a flow.

Step 2: Add the action Get file content from the connector OneDrive for Business. Select the .eml file which has the embedded image from the storage location i.e the file from OneDrive.

Step 3: Add the action Compose from the connector Data Operation. This step is to convert in to base64 representation a requirement for the convert API to work. On the Inputs file go to the expression editor and add the function base64(file content from the previous action get file) for converting .eml to base64.

Step 4: Add the action HTTP (Premium) from the connector HTTP to make a POST request to the API convert API endpoint.

Method: POST

URI: https://v2.convertapi.com/convert/eml/to/pdf?Secret=yoursecretkeyfromconvertapi

Headers:

Key: Content-Type

Value: application/json

Body: You can generate this from the ConvertAPI site by uploading a .eml file on the site. Once this data is added to the HTTP action Body parameter change the Data parameter should be the Output of the previous action Compose – Convert to Base64

{
  "Parameters": [
    {
      "Name": "File",
      "FileValue": {
        "Name": "myemailfile.eml",
        "Data": "@{outputs('Compose_-_Convert_to_Base64')}"
      }
    }
  ]
}

Step 5: Add the action Parse JSON from the connector Data Operation. This step is to parse the response of the HTTP POST action to the ConverAPI endpoint. You can generate the scheme by copying from the Flow run history for the HTTP action output. The schema will be look like

{
    "type": "object",
    "properties": {
        "ConversionCost": {
            "type": "integer"
        },
        "Files": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "FileName": {
                        "type": "string"
                    },
                    "FileExt": {
                        "type": "string"
                    },
                    "FileSize": {
                        "type": "integer"
                    },
                    "FileData": {
                        "type": "string"
                    }
                },
                "required": [
                    "FileName",
                    "FileExt",
                    "FileSize",
                    "FileData"
                ]
            }
        }
    }
}

Step 6: Add the Compose action to convert the base64 data to binary to create the PDF from the HTTP request response. Select the filedata from the Output of the Parse JSON action which will automatically create a Apply to each since the Files is an array. Then add the following to the inputs of the of the compose action

base64toBinary(items(‘Apply_to_each’)?[‘FileData’]).

Now add the Create file action from the connector OneDrive for Business as shown below. The parameter File content should be output of the Compose action. PFB the screenshot of the flow actions

Now its time to test the flow, run the flow & check your OneDrive for the PDF file. PFB the screenshot of the PDF file with embedded image

Summary: I am not vouching to use the ConvertAPI service for converting the email to PDF. Just a sample for a use case where you get some knowledge on different actions usage & some information on the .eml file which Microsoft has used for storing email content. If its going to be heavily used or if the data is secure, then I advise you to create a REST API endpoint of your own hosted in Azure for the conversion. Hope you find this post useful & informational. Let me know if there is any comments or feedback by posting a comment below.

Batch SharePoint requests [GET, POST, PATCH, DELETE] in PowerAutomate and MS Graph

Batching helps you in optimizing the performance of your application by combining multiple requests into a single request. SharePoint Online & MS Graph APIs supports the OData batch query option. Batch requests MUST be submitted as a single HTTP POST request to the batch endpoint of a service as below for

The request body of the above POST request must be made up of an ordered series of query operations [GET] and/or ChangeSets [POST or PATCH or DELETE]. You can have different combination of change sets.

In this blog post, I am going to show you how to batch multiple SharePoint requests for Creating, Reading, Updating & Deleting List items in

  1. PowerAutomate
  2. MS Graph

Pre-Requisites:

Have the following items ready to follow along this post

  1. SharePoint Site
    1. Site Id [GUID of the Site]
    2. Create a SharePoint List by the Name EmployeeInformation with the schema
      1. Title [Default]
      2. Location [Custom: Single Line of Text]
    3. List Id [GUID of the above list]
  2. Graph Explorer to test the Graph batching

Batch SharePoint requests in PowerAutomate:

If there is a requirement for multiple requests to be performed in SharePoint from your flow, the batch request with SharePoint Online REST API helps in reducing the execution time of your flow by combining many operations into a single request to SharePoint. Create an Instant Flow with trigger “Manually trigger a Flow” and the action Send an HTTP request to SharePoint to send the batch requests.

Lets now prepare the parameters to be passed for the Send an HTTP request to SharePoint action:

Site Address: https://mydevashiq.sharepoint.com/sites/test77

Method: POST

Headers:

  • Key: accept Value: application/json;odata=verbose
  • Key: content-type Value: multipart/mixed; boundary=batch_cd329ee8-ca72-4acf-b3bf-6699986af544

The boundary specification with batch_guid used on the content type header can be any random guid. In the request body the batch_guid will be used. To understand more about the OData batch operation, go through this documentation.

Body:

The request body given below is for reading all the items [GET], creating a list item, deleting an existing item & updating an existing item on the EmployeeInformation List using REST API endpoints. A ChangeSet (random guid) is used to group one or more of the insert/update/delete operations and MUST NOT contain query operations [GET]. For the query operation there must be separate batch as per the example below

--batch_cd329ee8-ca72-4acf-b3bf-6699986af544
Content-Type: application/http
Content-Transfer-Encoding: binary

GET https://domain.sharepoint.com/sites/sitename/_api/web/lists/GetByTitle('EmployeeInformation')/items?$select=Title,Location HTTP/1.1
Accept: application/json;odata=nometadata

--batch_cd329ee8-ca72-4acf-b3bf-6699986af544
Content-Type: multipart/mixed; boundary="changeset_64c72699-6e7c-49c4-8d9b-6b16be92f7fc"
Content-Transfer-Encoding: binary

--changeset_64c72699-6e7c-49c4-8d9b-6b16be92f7fc
Content-Type: application/http
Content-Transfer-Encoding: binary

POST https://domain.sharepoint.com/sites/sitename/_api/web/lists/GetByTitle('EmployeeInformation')/items HTTP/1.1
Content-Type: application/json;odata=verbose

{
    "__metadata": {
      "type": "SP.Data.EmployeeInformationListItem"
    },
    "Title": "Mohamed Shaahid Faleel",
    "Location": "England"
}

--changeset_64c72699-6e7c-49c4-8d9b-6b16be92f7fc
Content-Type: application/http
Content-Transfer-Encoding: binary

DELETE https://domain.sharepoint.com/sites/sitename/_api/web/lists/GetByTitle('EmployeeInformation')/items(37) HTTP/1.1
If-Match: *

--changeset_64c72699-6e7c-49c4-8d9b-6b16be92f7fc
Content-Type: application/http
Content-Transfer-Encoding: binary

PATCH https://domain.sharepoint.com/sites/sitename/_api/web/lists/GetByTitle('EmployeeInformation')/items(30) HTTP/1.1
Content-Type: application/json;odata=nometadata
If-Match: *

{
    "Title": "Mohamed Faleel",
    "Location": "USA
}

--changeset_64c72699-6e7c-49c4-8d9b-6b16be92f7fc--

--batch_cd329ee8-ca72-4acf-b3bf-6699986af544--

Once the above action is executed the response can be parsed to get the required information if you’ve used a GET request as per this documentation from Microsoft. PFB the screenshot of the action

The request body can be generated dynamically based on the requirement.

Batch SharePoint requests in MS Graph:

As we have done batching using the SharePoint REST APIs, in a similar manner you can combine multiple requests in one HTTP call using JSON batching for MS Graph. Here I will use the MS Graph explorer to test the batch request. Find the request parameters

Endpoint URL: https://graph.microsoft.com/v1.0/$batch

Method: POST

Body:

I’ve used the Site Id and List Id for the EmployeeInformation list to construct the SP endpoint URL’s as per the documentation for Creating, Reading, Updating & Deleting SP list items.

{
    "requests": [
      {
        "id": "1",
        "method": "POST",
        "url": "/sites/{77b3a8c8-549f-4848-b82c-8bb6f4864918}/lists/{2f923934-d474-4473-8fc0-3486bd0c15c5}/items",
         "body": {
          "fields":{"Title":"Test from Graph","Location":"Oslo"}
        },
        "headers": {
          "Content-Type": "application/json"
        }
      },
      {
        "id": "2",
        "method": "GET",
        "url": "/sites/{77b3a8c8-549f-4848-b82c-8bb6f4864918}/lists/{2f923934-d474-4473-8fc0-3486bd0c15c5}/items"
      },
      {
        "id": "3",
        "url": "/sites/{77b3a8c8-549f-4848-b82c-8bb6f4864918}/lists/{2f923934-d474-4473-8fc0-3486bd0c15c5}/items/44",
        "method": "PATCH",
        "body": {
            "fields":{"Title":"Mohamed Ashiq Faleel","Location":"Stockholm"}
        },
        "headers": {
          "Content-Type": "application/json"
        }
      },
      {
        "id": "4",
        "url": "/sites/{77b3a8c8-549f-4848-b82c-8bb6f4864918}/lists/{2f923934-d474-4473-8fc0-3486bd0c15c5}/items/50",
        "method": "DELETE"
      }
    ]
  }

On a same way you can batch different APIs endpoint from MS Graph. JSON batching also allows you to sequence the requests. Find below the screenshot from Graph explorer

Graph explorer also generates code snippets for the different programming languages

JavaScript Code snippet

Summary: On this post we have seen how to batch SharePoint requests using PowerAutomate & MS Graph. Microsoft has used request batching on many first party features. Hope you have found this informational & helpful in some way. Let me know any feedback or comments on the comment section below

Create/Delete a SharePoint custom theme using PowerAutomate

In a modern SharePoint site you can create custom themes using PowerShell, REST API & CSOM. In this blogpost I will show you how to create themes using PowerAutomate. The following REST endpoints are available

There is an online Theme Generator tool that you can use to define new custom themes. At the time of writing this post, the endpoints are open to everybody & not just to the SharePoint tenant admins which seems to be quite buggy. Laura Kokkarinen has written a very detailed blog post about this topic. I’ve got the inspiration to write about this topic from John Liu who has recently recorded a video about this. Find screenshot from the Theme generator tool:

Once you have defined the theme from the tool, click on the Export theme button on the Right top corner of the tool to export the theme as a code block in JS, JSON & PowerShell. In this case, click JSON & Copy the generated block

{
  "themePrimary": "#50AFC6",
  "themeLighterAlt": "#f7fcfd",
  "themeLighter": "#def1f6",
  "themeLight": "#c3e6ee",
  "themeTertiary": "#8ecddd",
  "themeSecondary": "#61b8ce",
  "themeDarkAlt": "#489eb3",
  "themeDark": "#3c8597",
  "themeDarker": "#2d626f",
  "neutralLighterAlt": "#faf9f8",
  "neutralLighter": "#f3f2f1",
  "neutralLight": "#edebe9",
  "neutralQuaternaryAlt": "#e1dfdd",
  "neutralQuaternary": "#d0d0d0",
  "neutralTertiaryAlt": "#c8c6c4",
  "neutralTertiary": "#d9d9d9",
  "neutralSecondary": "#b3b3b3",
  "neutralPrimaryAlt": "#8f8f8f",
  "neutralPrimary": "gray",
  "neutralDark": "#616161",
  "black": "#474747",
  "white": "#ffffff"
}

Flow for Creating or adding the Theme to the tenant:

Let’s create an instant flow with trigger Manually trigger a flow to add a theme to the tenant. Add two Compose actions as shown below

The first compose action is the actual definition copied from the theme generator tool

{
  "palette" : 
JSON block copied from the Theme generator tool
}

The second compose action has the name of the theme & its stringified JSON from the output of the previous compose action. To convert the JSON to string add a string expression on the dynamic content pane

{
"name":"My first Custom theme created using FLOW", 
"themeJson": @{string(outputs('Compose_-_Custom_Theme_Pallete'))}
}

Now add the action Send an HTTP request to SharePoint with the following parameters

Site Address: https://domain.sharepoint.com/sites/sitename

Method: POST

URI: /_api/thememanager/AddTenantTheme

Headers:

Key: Accept

Value: application/json;odata.metadata=minimal

Body: Output of the Second compose action (Compose – Theme Name)

Now you are ready to test the flow. Once its successful you can apply the custom theme to the site

Click cog wheel on the site to select the theme by selecting the Change the look link

For deleting the theme, add the action Send a HTTP request to SharePoint with the following parameters

Site Address: https://domain.sharepoint.com/sites/sitename

Method: POST

URI: /_api/thememanager/DeleteTenantTheme

Headers:

Key: Accept

Value: application/json;odata.metadata=minimal

Body: { “name”:”the name of your custom theme” }

Summary: Hope you find this post useful & informational. Let me know if there is any comments or feedback below.