@ mention user & channel in Teams using MS Graph API

There are ways to @mention a user while posting a conversation in Teams channel using flow action but as far as I know its not possible as of now to @mention a Teams channel using Flow actions. In this post, I will show you how to @mention a channel & user using a POST call to a MS Graph beta endpoint. To construct the endpoint URL you will need to know the TeamID & ChannelID, to get the information go to Teams > click the three dots > click Get link to channel > Copy the URL

Now decode the copied url, I’ve used Meyerweb Decoder. Your url will look something like below

End Point URL: https://graph.microsoft.com/beta/teams/groupIDorTeamID/channels/Channel ID/messages

Method: POST

Request Body:

{
 "importance": "high",
  "subject": "@Mention in Teams channel post!",
  "body": 
  {
    "content": "Hello <at id ='0'>Channel Name</at>, Test message on the channel with at mention.",
    "contentType": "html"
  },
  "mentions": [
    {
      "id": 0,
      "mentionText": "Channel Name",
      "mentioned": {
                        "conversation": {
                            "id": "ChannelID",
                            "displayName": "Channel Name",
                            "conversationIdentityType@odata.type": "#Microsoft.Teams.GraphSvc.conversationIdentityType",
                            "conversationIdentityType": "channel"
                        }
      }
    }
  ]
}

I’ve used Graph explorer to test the endpoint, if you have not signed in do sign in

Once you run the query on the explorer, you will see the Post in Channel with at mention as shown below

To @mention a user using Graph API, the endpoint is same as before but the request body has some changes as shown below

Request Body:

{
  "body": {
    "contentType": "html",
    "content": "Hello World User Display Name"
  },
  "mentions": [
    {
      "id": 0,
      "mentionText": "User Display Name",
      "mentioned": {
        "user": {
          "displayName": "User Display Name",
          "id": "UserID",
          "userIdentityType": "aadUser"
        }
      }
    }
  ]
}

To get your UserID, you can use the endpoint https://graph.microsoft.com/v1.0/me/

Reference: https://docs.microsoft.com/en-us/graph/api/channel-post-messages?view=graph-rest-beta&tabs=http

Summary: The endpoint which has been used in this post are beta endpoints. Graph API can be easily called using Power Automate, if you need some example on using a Graph API refer this post. Hope you find this post useful & informational. Let me know if there is any comments or feedback below.

Collect response from a user with Adaptive Card in Teams using Power Automate

This is in continuation to my earlier post using Adaptive card for collecting information in Outlook also known as Outlook actionable message. On this post I am going to show you how to collect information from a user in Teams and storing the values back in a SharePoint list. The following Power Automate actions under Microsoft Teams connector are now available in preview mode which helps us to capture data back from a Teams adaptive card meaning you would be able to make POST calls back to the flow by click of a button (Action.Submit) on the Adaptive card

  1. Post an adaptive card as the Flow bot to a Teams user, and wait for a response
  2. Post an adaptive card as the Flow bot to a Teams channel, and wait for a response

Once an Adaptive card is posted in Teams using the above actions, the flow run will not continue until the recipient or someone in the channel (if sent to channel) responds to inputs that are required within the card till then the flow is put on wait for maximum period (Async calls) of 30 days as per the documentation. Post that period the flow will time out if no one responds to the card. There can be use case to collect responses from users in Teams & post it to Azure services like SQL etc, this avoids the users to have access to premium services or license since the card is sent using Power automate. The use case I’ve chosen for this post is to collect Name & Email address of a teams user by sending them an input form which stores the responses in a SharePoint list after the user responds. Find the resources I’ve used for this example

  • Adaptive Card Designer for creating JSON
  • Automated Flow with action to post an JSON Adaptive card using the connector MS Teams
  • SharePoint custom list with columns Name & Email
  • Microsoft Teams with the Flow App installed

Adaptive Card Creation:

Let’s start by designing the card using the Adaptive card designer. Click on Open Sample, select Input Form as shown below

Then change the host app from the default Bot Framework Webchat to Microsoft Teams – Light (Optional Step). Remove the Phone number Text Block [Element] & the corresponding Text.Input [Inputs] field to keep it simple & I’ve also changed the Adaptive card image URL on the right column to the following URL since the image default image on the sample has got some issues rendering on teams. Find some information on image size & resolutions limits here.

Click Copy Card JSON from ribbon for this card to be used on the flow. We now have the adaptive cards JSON ready with us, let’s go ahead and the create the flow using Power Automate. Find the generated JSON below

{
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "type": "AdaptiveCard",
    "version": "1.0",
    "body": [
        {
            "type": "ColumnSet",
            "columns": [
                {
                    "type": "Column",
                    "width": 2,
                    "items": [
                        {
                            "type": "TextBlock",
                            "text": "Tell us about yourself",
                            "weight": "Bolder",
                            "size": "Medium"
                        },
                        {
                            "type": "TextBlock",
                            "text": "We just need a few more details to get you booked for the trip of a lifetime!",
                            "isSubtle": true,
                            "wrap": true
                        },
                        {
                            "type": "TextBlock",
                            "text": "Don't worry, we'll never share or sell your information.",
                            "isSubtle": true,
                            "wrap": true,
                            "size": "Small"
                        },
                        {
                            "type": "TextBlock",
                            "text": "Your name",
                            "wrap": true
                        },
                        {
                            "type": "Input.Text",
                            "id": "myName",
                            "placeholder": "Last, First"
                        },
                        {
                            "type": "TextBlock",
                            "text": "Your email",
                            "wrap": true
                        },
                        {
                            "type": "Input.Text",
                            "id": "myEmail",
                            "placeholder": "youremail@example.com",
                            "style": "Email"
                        }
                    ]
                },
                {
                    "type": "Column",
                    "width": 1,
                    "items": [
                        {
                            "type": "Image",
                            "url": "https://download-ssl.msgamestudios.com/content/mgs/ce/production/SolitaireWin10/dev/adapative_card_assets/v1/tile_spider.png",
                            "size": "auto"
                        }
                    ]
                }
            ]
        }
    ],
    "actions": [
        {
            "type": "Action.Submit",
            "title": "Submit"
        }
    ]
}

Flow Creation:

Create an Instant flow with trigger “Manually trigger a Flow”, this will post an Adaptive card to a Teams user with the Input form which collects response to a SharePoint list. Create a SharePoint list with two columns for us to store the Name and Email submitted from the adaptive card on Teams.

Add the flow action “Post an adaptive card as the Flow bot to a Teams user, and wait for a response”, on the action

  1. Enter the email address of the user in the Recipient field
  2. Paste the JSON copied from the card designer in the Message field
  3. Enter information to be shown to the user on the field Update message after the Submit button is clicked
  4. Field Should update card to be set as Yes

Now add the action “Create item” to store the form response in the SharePoint list created above with the request body information mapped to Name (myName) & Email (myEmail) using the dynamic content. The dynamic content has also information about the user (Email, Display Name, Response time etc) responded in Teams

The flow is ready, Run the flow to test it. The recipient would have received the card in Teams as below

After the user keys in the Name & Email address on Teams and clicking Submit button will complete the flow till then the flow will be in wait state for a period of 30 days maximum. The data will be submitted to the SharePoint list and the card will be updated with the update message as below

There is an Adaptive card designer in Power Automate which is an experimental feature currently with which you would able to design/update Adaptive card in the Power Automate action. To enable it, click the cog wheel on your flow environment and click  “View All Power Automate settings”. On the popup toggle the Experimental Features to On and click Save button.

Go back to the flow in Edit mode, the Teams action will now have an Adaptive card designer as shown below

Senior Program Manager for Power Automate Audrie Gordon has a great video on Adaptive cards for Power Automate which has lot of information.

If you run in to an error while submitting the form or triggering the flow, look at the Troubleshooting tips for Adaptive cards. There are few known issues documented here with regards to using this action on Power Automate.

Reference: https://docs.microsoft.com/en-us/power-automate/overview-adaptive-cards

Summary: You now have created an input form for collecting information from a user in teams. To know the future road map for Adaptive cards, click here to know. There are couple of amazing templates available in the Flow environment, just search for Adaptive card in templates where you get template for different use cases. Hope you have enjoyed reading this post and find it useful. If you have any comments or feedback, please provide it on the comments section below.

Accessing SharePoint modern page Likes & Comments using Power Automate

In a SharePoint modern page, you as an author would be able to turn on or turn off comments while creating a page. Everyone with minimum Read access on a SharePoint site would be able to Post, Like, reply to a comment at a single level, @mention a person while commenting in a SharePoint page.

When someone comments on a page or news post, SharePoint notifies the author or the person mentioned in the header of the page via an email. The SharePoint mobile app also alerts the author whenever a comment is made. If there are multiple comments, it will be batched so that the authors receive a single email when several comments have been made within a short period of time. Additionally, author gets email notices when users reply to comments or leave a “like”.  Author or a user can unsubscribe from notifications by clicking the “Unsubscribe” link in the footer of the email.

UnSubscribe

User with contribute access on a site would be able to delete any comments posted on the page which is quite an issue & not yet addressed by Microsoft. User with Read access to the site would be able to delete only the comments they have posted. Do you know where the comments are stored when ever you make a comment, they are stored in a separate data store with references to the Site Pages library guid & the item id of the page. The comments & likes are accessible via Rest API of the site. Find the different endpoints available for executing below actions

  • Getting comments & likes of a page item
  • Posting a comment on a page
  • Deleting a existing comment

There are couple of nice blog posts covering this topic with the API details. Find the links below:

On this blog post I am going to show you how to access the comments details of a SharePoint page using Power Automate.

Let’s create an automated flow with trigger “Manually Trigger a Flow”, add an action “Send an Http request to SharePoint” since the API to retrieve the comments is an SharePoint rest API.

The API for getting the comments of a SharePoint page is

https://tenantname.sharepoint.com/sites/sitename/_api/web/lists/GetByTitle(‘Site Pages’)/GetItemById(pageitemid)/Comments

Method: Get

Header Information: accept: application/json;odata.metadata=none

The odata.metadata=none option reduces the size of the payload significantly, and for many scenarios this is all that you need when working with list items

Run the flow, the output of this action would have all the data related to the comments posted by users on the page in a JSON format. To get the required information we will have to parse the JSON with the help of the Parse JSON action. Add the Parse to JSON action as below with content to the Body from Outputs of the action “Send an Http request to SharePoint”

Click on the button “Generate from sample” which loads a popup “Insert a Sample JSON payload” paste the run data of the flow for generating the schema automatically. To get the run data, go to the run history and click the run and go to outputs of the action “Send an Http request to SharePoint” copy everything inside the Body

Find the information of the body in the JSON online viewer to decide what information you need & what is available on JSON output

Add the compose action to see all the information available from the Output of the parse action, I’ve added only text which has the comment text & email has the email address of the user posted the comment

Summary: There are different Rest API endpoints available for comments & likes in Modern SharePoint page, you can select the any of them based on the requirement. The api’s can also be used on SPFx solutions for customizing Comments feature. Hope you find this post useful. Let me know if there is any comments or feedback by posting a comment below.

Restricting Power Apps users from viewing or updating the SharePoint List content from SharePoint GUI

There are many developers & power users using SharePoint lists as a data source to store data submitted from a Power App. There should be various reasons for this, please find mine below

  • Enterprise users with license (E5, E3, E1) has access to Power App & SharePoint as a service
  • SharePoint is a standard connector & not a premium one which means the user would be able to access SharePoint with the license they have assigned. Its not required for the users to have an additional license (App based license or user based license) to access the premium connectors like Azure SQL etc
  • There are many triggers & actions available for SharePoint connector

Let’s say on the Power App you have developed or developing has many custom logics on different screens. For e.g data being stored on different lists on click of a button in a Power App screen/form. If the user has to store data to SharePoint from Power App, user should have at the least edit/contribute access which means the user to be added on the out of the box site members group.

If the power app user gets to know the SharePoint site url which is connected as a data source in the Power App, the user would be able to access all the lists from the site by going to the Site contents page or by directly going to the list view url. This might create an issue because the user might edit, create or delete an item from the SharePoint interface rather from the Power Apps interface. As an app owner, you would like to avoid this. There is a way to avoid this by creating a custom permission level for the app users in SharePoint. Please find the steps below

  1. Go to the Site Permissions
  2. Click Permission Levels on the Ribbon
  3. Click an existing permission level “Contribute” from the list.
  4. You will be navigated to Edit Permission level for “Contribute”
  5. Scroll the page to the bottom & click on the button “Copy Permission Level”
  6. Name the permission level as “Power Apps – Custom Permission” & give some meaningful description
  7. Remove/Uncheck the permission “View Application Pages” under the category “List Permissions”
  8. Scroll down and click “Create” button

The custom permission level is ready, let’s assign this to a new SharePoint group. Find steps below to create a new group & assign the custom permission level to the group

  1. Go to the Site Permissions
  2. Click “Create Group” on the ribbon
  3. Name it as “Power App Users”
  4. Change the Owner field to the Site Owners group – Optional Step
  5. Scroll down & select the Permission level created above
  6. Click Create

The group is ready, add the power app users to this group. This access will not allow the members of this group to access the Site contents (Application Page), view forms or views (Allitems.aspx) but they would be able to create/update from Power Apps. Technically the user would still be able to access/modify the list content programmatically using CSOM/JSOM etc, but the GUI in SharePoint is blocked. They will receive an access denied message while trying to access the list view/form or site contents page.

Summary: You can play around with the different types of permissions while creating the permission level for Power Apps users, grant only the required permissions. A site owner will have access to create or update permission level. Microsoft has very detailed documentation on permission levels. In a SharePoint site, the permissions are inherited from the Site>Lists>Item. Based on the need, the permissions can be broken at any level. Hope you find this post useful. Let me know if there is any comments or feedback by posting a comment below.

Actionable Outlook Message using Adaptive Card connected to SharePoint using Power Automate

Adaptive Cards a new way for developers to display & exchange content in a common and consistent way across different applications. It can be hosted on

  • Bot Framework Webchat
  • Cortona Skills
  • Outlook Actionable Messages
  • Windows Timeline
  • Microsoft Teams
  • Windows Notifications

SDKs (.NET, JavaScript, Android, React, iOS etc) are available for authoring & rendering cards inside your own apps. Microsoft has got a very great documentation on this. The schema explorer has got information about all the list of available Card elements, containers & actions sets to use. Adaptive card templating features which is now available in preview mode to help create, reuse & share the cards you develop & enable you to separate the data from the layout in an Adaptive card. There is also a plugin available called as Adaptive Card Viewer in Visual studio code for visualizing the card & a Team app called as App Studio.

Develop a card using the Adaptive Card Designer from the scratch or you can start with some available samples. Card Authors describe their content as a simple JSON object with the help of the designer which could then be rendered natively inside a Host Application as shown above, automatically adapting to the look and feel of the Host.

On this blog post, I am going to show you how to create an Outlook actionable message using a sample (Input Form) available in Adaptive card designer, this collects information (Name, Email) from the user & storing it in a SharePoint list using two flows. On submission of the form, a simple response message will be shown using a response Adaptive card. For the outlook version requirements for actionable message, click on this link. Find the flows to be created below

  1. Instant flow with the manual trigger for sending the adaptive card in an email
  2. Instant Flow using trigger When a Request is received for sending information to SharePoint list

Actionable messages can be via Email which I am focusing on this blog post or using connectors. Check here the supported scenarios via an Email.

Steps Involved to create actionable message via an Email:

  • Creating the Adaptive card for the host application (Outlook)
  • Creating the Flows

Let’s start with creating the card using the Adaptive Card designer

Adaptive Card Creation:

There is going to be two adaptive cards

  • First one is the initial form to be sent on email using the sample Input form
  • Second one is a response card which will be shown after the input form is submitted

First Adaptive Card:

Go the designer & click on Open Sample, select Input Form as shown below

Adaptive Card Designer

Then change the host app from the default Bot Framework Webchat to Outlook Actionable Messages. Remove the Phone number Text Block [Element] & the corresponding Text.Input [Inputs] field to keep it simple. Remove the Submit action set, add the action set of type Action.Http for us call the flow with method POST for us to interact with SharePoint

Update the following attributes of the just added element action set

  1. Rename the Title of the element to Submit from Action.Http
  2. Add the Id submit
  3. Change the Style to Positive from Default
  4. Select the Method to POST
  5. Url to be set to our second FLOW (When a Http request is received) HTTP POST url later once we have it ready with us
  6. Add the following to the Body
{
"inputName":"{{myName.value}}",
"inputEmail":"{{myEmail.value}}"
}
  1. Set the HTTP Headers
    • Click the Add New header, enter “Authorization” to Name and leave the Value blank. If this is not done, you will receive an HTTP 401 unauthorized message while clicking the button on the email. The HTTP request is received flow does not have any authentication its anonymous so be careful with the URL and have some steps to validate on the flow so check if its triggered from valid source
    • Add one more header, enter “Content-type” to Name and Value should be “application/json”. This is required to make the POST request from the email

The first card is ready, lets us go ahead and create the second one which is the response card. This will be shown once the response is submitted

Second Adaptive Card:

This is going to be a very simple card, lets start from the scratch. Go to the designer and select New Card

  1. Add a Container
  2. Add a TextBlock with text “Your Response has been submitted successfully” on the container

Click Copy Card JSON from ribbon for this card to be used on the flow. We now have the adaptive cards ready with us, let’s go ahead and the create the flows using Power Automate. Find the generated JSON below

{
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "Container",
      "items": [
        {
          "type": "TextBlock",
          "text": "Your response has been submitted successfully",
          "id": "response text"
        }
      ]
    }
  ],
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}

Instant Flow using trigger When a Request is received:

This flow is an Instant flow with trigger “When a HTTP request is received”, this is going to be called from email for submitting the Input form to a SharePoint list. Create a SharePoint list with two columns for us to store the Name and Email submitted from the adaptive card on email.Create the flow with the trigger as said above. The POST url will be generated after the flow is saved with an action. Click Generate from sample on the trigger and copy and paste below information which would automatically generate the schema for you. If you have more advanced JSON schema with, try using this tool.

{
	"inputName": "",
	"inputEmail": ""
}

Click Advanced options to select the method POST. Add the action create item to store the user form response to SharePoint list created above with the request body information mapped to Title (Name – inputName) & Email (inputEmail) using the dynamic content

Add the Compose action, paste the JSON of the second adaptive card to the Inputs.

Compose action

Add the Response action, a premium one with the header key CARD-UPDATE-IN-BODY and the value as true. The body parameter should be the outputs of the compose action JSON

Response Action – Premium Action

Save the flow, the POST url will now be generated copy it and go to the first adaptive card and paste it on the url attribute for the Submit action set. After this copy the JSON from ribbon, we are now ready for creating the next flow

Instant flow with the manual trigger for sending the Adaptive Card

This flow is an instant flow with trigger Manually Trigger a flow for sending the adaptive card an outlook actionable message in an Email. You can have a different type of trigger based on the requirement. Add the compose & send an email (v2) action, paste the JSON for the first adaptive card to the inputs field of compose action. Make sure JSON also has the POST Url of the first flow on the Action set. On the compose action, also include the script tags as given below

<script type=”application/adaptivecard+json”>

— JSON of First Adaptive Card—

</script>

<script type="application/adaptivecard+json">
{
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "type": "AdaptiveCard",
     "version": "1.0",
    "body": [
        {
            "type": "ColumnSet",
            "columns": [
                {
                    "type": "Column",
                    "width": 2,
                    "items": [
                        {
                            "type": "TextBlock",
                            "text": "Tell us about yourself",
                            "weight": "Bolder",
                            "size": "Medium"
                        },
                        {
                            "type": "TextBlock",
                            "text": "We just need a few more details to get you booked for the trip of a lifetime!",
                            "isSubtle": true,
                            "wrap": true
                        },
                        {
                            "type": "TextBlock",
                            "text": "Don't worry, we'll never share or sell your information.",
                            "isSubtle": true,
                            "wrap": true,
                            "size": "Small"
                        },
                        {
                            "type": "TextBlock",
                            "text": "Your name",
                            "wrap": true
                        },
                        {
                            "type": "Input.Text",
                            "id": "myName",
                            "placeholder": "Last, First"
                        },
                        {
                            "type": "TextBlock",
                            "text": "Your email",
                            "wrap": true
                        },
                        {
                            "type": "Input.Text",
                            "id": "myEmail",
                            "placeholder": "youremail@example.com",
                            "style": "Email"
                        }
                    ]
                },
                {
                    "type": "Column",
                    "width": 1,
                    "items": [
                        {
                            "type": "Image",
                            "url": "https://upload.wikimedia.org/wikipedia/commons/b/b2/Diver_Silhouette%2C_Great_Barrier_Reef.jpg",
                            "size": "auto"
                        }
                    ]
                }
            ]
        }
    ],
    "actions": [
        {
            "type": "Action.Http",
            "title": "Submit",
            "url": "HTTP POST FLOW URL",
            "id": "submit",
            "style": "positive",
            "method": "POST",
            "body": "{\"inputName\":\"{{myName.value}}\",\"inputEmail\":\"{{myEmail.value}}\"}",
            "headers": [
                {
                    "name": "Authorization",
                    "value": ""
                },
                {
                    "name": "Content-type",
                    "value": "application/json"
                }
            ]
        }
    ]
}
</script>
Instant Flow for sending the actionable message

On the Send an email (V2) action, click the html view and select the outputs of the compose JSON which has the first adaptive card JSON. The flow is ready, click the Test link on the right corner of your flow to trigger it. The email will be received to the sender as below

Email – Input for collection information (Name & Email)

Once the information is Submitted, you would see the response as below

Email response after the form is submitted

If you would like to test with the tenant or global users, then register your adaptive card actionable message on the Actionable Email Developer Dashboard to enable this service. Enter the Flow URL (HTTP Request response), scope & sender email address. For more information on the developer dashboard refer here. Regarding security of the actionable message, refer here.

New Provider Registration

Once your provider is approved. Add the Provider Id (originator) field to the originator attribute in your JSON of the adaptive cards next to the type key, as follows:

“originator”: “ProviderId”,

Summary: You now have an actionable message adaptive card on outlook for collecting information from users on email. It provides you more functionality than the available Out of the box actions Approvals or Emails with options. To know the future road map, click here to know. Hope you have enjoyed reading this post and find it useful. If you have any comments or feedback, please provide it on the comments section below.

Automate the backup of your Flow & Power Apps canvas application

Microsoft Power Automate & Power Apps have turned quite important & popular service now a days within Office 365, there are many users (developers & IT pro users) who are creating business applications leveraging these services very quickly but if an app or a flow is deleted by mistake then its not an easy job to spin it back up with out involving Microsoft support. In this blog post, am going to give you some ideas to back up a Flow & Power Apps automatically with the help of connectors available in Power automate. Once it is backed up, I will show you steps to restore from the back up.

Once I’ve deleted a flow accidentally and I was not able to restore it back, I have recreated the complete flow with all the steps which took some time. I will show you steps to back up & restore your Flow & Power Apps.

  • Backup & Restore your Flow
  • Backup & Restore your Power Apps

Backup & Restore your Flow:

A flow could be backed up by copying the flow definition & connection references with the help of an action “Get Flow” under the flow connector “Flow Management”. With the flow definition & connector references we would be able to restore it back whenever needed. Thanks to John Liu for the tips & guidance on showing us a way to copy the flow definition. Before showing you steps to get the flow definition & connection references, I will show you some examples on the type of information it stores on these fields.

Flow Definition:

It has details about the triggers & actions used with in a flow in a JSON format.

Flow Definition

Triggers: Information about the trigger used in the flow (Instant, Automatic, Scheduled)

Actions: Information about all actions used in the flow

Connection References:

It has details about all connections used against each action

Connection References

Add the action “Get Flow” under connector “Flow Management”, which has the fields flow definition & connection references. This action would be able to get only the flows to which you have access to. If you don’t see the flow under the drop down, enter the Flow ID by selecting custom value.

Now let’s store the Flow definition & connection references to a file in some location so that we would be able to retrieve the files for restoration. On this example I will use “One Drive for business connector” action “Create File” to store the content in two files but you can also get it stored on SharePoint Document Library, Azure Blob, GitHub etc. The extension of these files can also be .txt but I’ve used .json.

One Drive for Business connector

Restore Flow:

Flow action “Create Flow” helps us to restore flow from the flow definition & the connection references stored on One drive. Only the file content should be passed for the Flow Definition, connectionReferences and not the actual file.

Backup & Restore your Power App:

A Power App could be backed up by creating a MSAPP file for the PowerApp to be backed up. The file with extension .msapp is just a ZIP file which has all the definitions of the app. There are open source tools (Review Tool, Theme editor, App merger, Phone to tablet converter) available in github which helps us to peek at the definitions of the .msapp file.

PowerApps Review Tool

PowerApps for App Makers connector has an action called “Get App” which helps us to get all the information related to the specified app. This action has a field called “readonlyValue”. It points to a link that has the PowerApps msapp file. With the help of the premium connector HTTP, we will make a GET request to the readonlyValue link (Blob storage path). This step allows you to retrieve the contents of the msapp file which could then be stored as a backup file in Onedrive, SharePoint, Github etc. Lets now look at the contents of the msapp file, change the extension of the .msapp file to .zip file and open it.

AssetsAll the media files (Images, Videos, Audio)
ControlsInformation about all the controls (First Party, Custom components etc) used in the different screens of the app. Data is in JSON format.
ReferencesInformation about Datasources, Templates (Label, Gallery, Textbox etc), Resources (Images etc), Themes used in the app etc
ResourcesPublish information, user locale etc
Properties.jsonInformation of the app like Author, PowerApp name, no of screens etc
Properties.json file

Add the action “Get App”, enter the App ID of the Power App

Get App action

This action retrieves all the information of the app including the “readonlyvalue” as explained above. Using this result we will make a GET request using the HTTP connector to retrieve the app data in this Flow.

HTTP (Premium connector)

Add the action “Create file” in OneDrive for Business connector and set the body from HTTP connector. This allows you to save your app to OneDrive for Business. As said earlier you can instead store it to other storage like Azure Blob Storage, SharePoint document library, GitHub etc.

Restore Power App:

The msapp file is with us now, lets now restore the PowerApp. Create a Blank app from the Power Apps studio then open the.MSApp file via the File > Open > Browse menu option. This enables you to select the .MSApp file from your local file system then save & publish the App. The app is now back. Let me know on the comment section if there is a automated way to restore the PowerApp from the MSApp file.

Summary: On this blog post, we have seen ways to backup & restore your app & flow using a Flow. If you are an Power App/Power Automate environment admin (Premium license), you could backup all the apps & flow available in the environment using the Apps for Admin connector. There are Power Shell cmdlets available for Admins & creators which could also be used. If you have a more complex business application including PowerApps Canvas, multiple flows, custom connector, Model driven apps, entity etc, solutions is recommended. Exporting a solution as a package is very easy by click of a button, restoring is also quite an easy task. Hope you find this post useful, let me know your feedback on the comments section.

Managing users for a Power App with SharePoint as a data source

In this blog post, I am going to show you how to manage users for a Power App which has SharePoint as a data source. Let’s take an example, you’ve built a Power App application which has its data stored in SharePoint. After the application is developed, you want to share the app with some users. To do so you’ll have to give the user access to

  • PowerApps
  • Access to the Data source (SharePoint in this case), it could be Read/Write based on the use case

Only after the user has been granted access, they would be able to use the application. To setup the process for managing users we are going to use an action “Edit App Role Assignment” under the connector “PowerApps for App Makers” in the flow. Find the steps to executed to make this happen

  1. Create an Interface/screen for the Admins in PowerApps (custom role) to maintain (Add/Remove) the users of the application
  2. Flow for granting access to the users
    1. Action to grant access to the PowerApps
    1. Action to add the user to the SharePoint site

Step 1: Create an Interface for the Admins in PowerApps to manage the users for the application

Create a list (User Roles) on the SharePoint site which acts as a data source for application with the below schema to maintain the users

ColumnType
UserNamePerson or Group
RoleChoice (value: Admin, User)
RoleStatusSingle line of text (Default value: Add)
List Schema for UserRoles

Add a screen on the Power App as shown on the image below. I’ve given some information on the image the type of controls I’ve added on the screen.  This screen will be shown only to the Admin role, the navigation to this screen could be based on click of a button placed somewhere on the screen. The visibility of the button to navigate to the admin interface could be set based on the data (Role) from the list User Roles list. In this example, I will have two roles an Admin and User. Find the below screen in PowerApp built for managing the users

PowerApp Admin Interface screen

Once the user name and the role has been entered on the section 1, click add which adds the user information to the list User Roles. Once a user is added, the flow will be triggered which has actions to grant access for a Power App.

Step 2: Flow for granting access to the users

I will be using a flow to grant access to PowerApp & SharePoint site. Let’s build the automated flow with trigger “When an item is created or modified” connected to the list User Roles

Automated Flow Trigger

Add the action “Get User profile”, the input should be the email address of the user who must be given access to PowerApp. This step is required to get the user guid, to be given on a later step for granting access to PowerApp action

Get User profile

Now Add the action “Edit App Role Assignment” under the connector “PowerApps for App Makers”, this action is in preview mode by the time I am writing this post. To get more details on the different actions and its parameters with this connector go through this link. Make sure the connection to this action has access (Owner/Co-Owner) to share an App to a user.  You would be able to get the GUID (App ID) of the Power App by going to the details section of an app.

Edit App role assignment flow action

Now let’s add an action to grant the user access to SharePoint site. I would be using a flow action “Send an HTTP request to SharePoint” to call a Rest API (POST) to get the user added to the SP site groups (Members/Viewers/Visitors). The connection for this action should have access (Site Owner) to share the site. Find the rest api details to add the user to a group

URI: _api/web/sitegroups(groupId)/users

Method: POST

Request Body: {‘LoginName’:’i:0#.f|membership|Emailaddressoftheuser’}

To get the SharePoint group id, navigate to the url https://domainname.com/sites/sitename/_layouts/15/user.aspx and click the group name and copy the URL which will have the groupid at the end.

https://domainname/sites/sitename/_layouts/15/people.aspx?MembershipGroupId=3

Find the action with the configurations

SP HTTP request action

Execute the flow by adding the user to the list from the PowerApps interface, the flow gets triggered which will in turn grant the user access to PowerApp & SharePoint. Tada!!!

To revoke the access to a user, if you scroll back to the admin interface image for managing the user there is a delete button. Assume that the delete button click will update the column status on the User Roles list to “Revoke” for a user which would then trigger the same flow. On the same flow add a Switch which would then based on the value in the RoleStatus (Add/Revoke) column, add steps to revoke the access. This could be achieved in multiple ways. For e.g After the delete button is clicked the item on the UserRoles list can be deleted which will in turn call a flow created using the trigger “When an Item is deleted” with actions to revoke access

Action to Revoke Power App access, its the same action we used for adding user to an app but with some different parameters as shown below

Edit Role assignment – Remove user

The rest api details for revoking the user access from a SharePoint group

URI: _api/web/sitegroups(groupId)/users/removeByLoginName

Method: POST

Request Body: {‘loginName’:’i:0#.f|membership|Emailaddressoftheuser’}

The action to grant access to Power App can also be called from a Power App by creating a connection to the data source “PowerAppsforAppMakers” as below

Editapproleassignment from powerapp

Summary:This approach would help the super users of the app to manage user permissions for the Power App within Power Apps interface. On this post we have seen adding the user permission to SharePoint data source. Based on needs there should be ways to add users to different data sources if there’s an api endpoint or with the help of standard connectors available in Power Platform. Let me know any feedback or comments on the comment section below

Post a Teams Conversation on a Channel using API call/HTTP Request

On this blog post, I am going to cover different options to post a Teams conversation in a Teams channel using API call.

  • Using a Flow with HTTP Request trigger & Flow action
  • Create an Incoming Webhook in Teams
  • Graph Endpoint to create a Teams conversation

I do now see more requirements from customer to integrate Teams with different applications. These options for posting a message in a Teams channel could be to used on an External application or from a SharePoint Site using SPFx.

Create a Flow with HTTP Request trigger

Create an Instant flow with Trigger “When a HTTP request is received” a premium trigger which gets triggered to a HTTP request. This is a responsive trigger as it responds to an HTTP Request. The structure of the requests/responses that Microsoft Flow uses is a RESTful API web service known as REST. The API or HTTP post URL will be generated only after the flow is saved with at least one action.

Let’s say I would like to post a Teams conversation with @mention to a specific user and some message. In this case I will have to pass the information either in Parameters or on the body of the call. On this example we will be passing the information on the request Body

{
    "To":"ashiqf@####.onmicrosoft.com",
    "Message": "Hello from HTTP Request"
}

Copy the above sample and paste it on the popup you get after clicking on Generate Schema. The tool will automatically generate the JSON schema for you. Also jsonschema.net could be used to generate the schema

Find the generated schema below for the information email address & message which would be passed on the request body while making the POST call

Add the action “Post a message as the Flow bot to a channel”, this will create a Teams conversation on a specific channel in a Team. On the below screenshot, look at the way I am doing @mention to a user, leaving a New line & making a text appear Bold

After you save the flow, the HTTP Post URL will be generated for us to use in an external application or where ever we want. The API is not secured its anonymous. Lets now use Postman client to trigger. Don’t forget to set the headers for content-type to application/json, Information on the body & method to POST else the trigger will fail

After the Post button is clicked on Postman client which would then trigger the flow. The message on Teams channel will appear as shown below

In Postman client, there is an option to generate the code to call the API for different programming languages

As already said, the HTTP post URL is anonymous. If you would like to secure the flow actions, you could do it after the flow is triggered with some validations. If you look at the output from the Flow run for the Trigger, there is information on the field “User-Agent”, with this information you would able to add some validations

Create an Incoming Webhook in Teams for a Specific channel

Incoming webhooks could be used to create Teams Conversations on a specific channel on a team. It’s special type of Connector in Teams that provides a simple way for an external app to share content in team channels

To create a Webhook, go to the Teams channel where you would like to have the conversation posted. Click connectors

Create Webhook

Look for Incoming Webhook from the list of connectors then click Add

Provide a Name for the webhook and click Create. Now the URL will be generated, click Done

The generated URL will be on this format, get this copied

I will now use post man to create a conversation in Teams, it has to be Post request with the information passed on the Body. The header information is not required for this POST call

{"text":"<b>Post using Incoming Webhook</b><br>Message from External Application!"}
Postman Client
Teams Channel conversation

Ref: https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook

Refer the below Microsoft documentation which has some example to create an Adaptive card in teams

https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using

Graph Endpoint to create a Teams conversation

There is also endpoint (REST) available in MS-Graph to post/create a Teams conversation. The time I am writing this post, its a Beta endpoint and its not recommended for production use

POST /teams/{id}/channels/{id}/messages

The ID of the Teams and the Channel ID must be passed along with the bearer Token to create a team’s conversation. To get the bearer token create a Azure AD app with API permissions for Graph to create a message. The permission could be either Delegated or Application permissions based on the requirement. There are lot of articles which covers the steps to create an App in Azure so am not going to cover those in this post.

Ref: https://docs.microsoft.com/en-us/graph/api/channel-post-messages?view=graph-rest-beta&tabs=http

Summary:

I’ve described different ways to create team’s conversation using API calls. Hope you find this post informative & useful. If you have any comments or questions, let me know on the comment section.

Get attendees details of a meeting event using Power Automate/MS Flow

Its fairly easy to create an event using Power automate in Office 365 Outlook using the action Create Event but there is no action to get the attendees details on who has Accepted, tentatively accepted, Declined & No response if you are trying to automate.

MS Graph comes to the rescue to get the attendees details, there is an endpoint available to fetch the attendee’s details of an outlook event.

Let’s assume you are creating Outlook Event using flow action Create Event which has a connection using a different account (For e.g a service account with mailbox enabled). After the event is created the Event ID (Unique ID of an Event) is stored on a SharePoint Custom list or SQL etc to get the attendees information.

Before you start, you need to make sure you have the following:

  • Access to an Office 365 tenant with administrative access to Azure AD
  • Access to create flows in Microsoft Flow

Step 1 – Create an Application in Azure AD with API permissions to Calendar

You will need to register an application within Azure AD.

Navigate to Azure Active Directory from https://portal.azure.com and select App registrations. Select New registration. I am not going to list the steps required to create an Application in Azure AD, there are lot of blog posts & Microsoft articles which covers the steps. For this requirement, Redirect URI is not required to filled on the Azure app.

To get authorized to call Microsoft Graph in Power Automate/MS Flow, we’ll need the following information:

  • Tenant ID
  • Client ID
  • Client secret
  • API Permission to Read Calendar
  • Token Endpoint

Once the application is created, go to the API Permissions. To configure application permissions for the AD app to get the event information, API permission to the Calendar is required. Find the steps below to grant read permission to the calendar

  1. Click on the API Permissions menu item in the navigation panel.
  2. Click on the Add a Permission button.
  3. Click Microsoft Graph under the tab Microsoft APIs.
  4. Click on the Application Permissions button.
  5. Expand the Calendars section.
  6. Select the Calendars.Read option. This step gives access to the app for reading all the calendars in the mailboxes across the tenant.
  7. Click on the Add Permissions button.
  8. Click on the Grant Admin Consent button.
  9. Click on the Yes button to confirm consent.
API Permissions on the AD App

I use the Graph Explorer https://developer.microsoft.com/en-us/graph/graph-explorer# to test & explore different endpoints.

This explorer will not work for delegated permissions since it uses your permissions to access the API endpoint but you can use Postman to test the graph endpoint with the Oauth authentication.

Find the documentation for the different endpoints available for Calendar in the link

For this requirement we are interested in the following HTTP request/endpoint to the get details of a different user using the version 1.0

GET /users/{id | userPrincipalName}/calendar/events/{id}

Step 2 – Create a Flow

With the Azure AD application created, you have to create a flow using it. You could even create a Azure logic Apps. Find the steps below to create a scheduled flow

First, go to https://flow.microsoft.com and go to My flows. Select New > Create Scheduled-from blank to create a new flowThis flow will be running on scheduled basis to get the attendees details.

Flow Trigger

Call the token endpoint of the tenant’s Azure AD which will provide us an access token for Microsoft Graph in return for the information contained in the request body. Use the Flow action HTTP which is premium action to make a HTTP post request for getting a token.

Before we construct the HTTP request, we need encode the client secret to avoid having URL unsafe characters:

encodeUriComponent(variables('ClientSecret'))
The HTTP methodPOST
The request URLhttps://login.microsoftonline.com/your tenant id/oauth2/v2.0/token
The Content-Type headerapplication/x-www-form-urlencoded
The request bodytenant=tenantID&client_id=clientID&client_secret=@{decodeUriComponent(variables(‘ClientSecret’))}&grant_type=client_credentials&scope=https://graph.microsoft.com/.default

The token endpoint URL can be obtained from the AD App by clicking on the Endpoint link as shown below

Active Directory App – Overview
HTTP Action

When the above HTTP request is made, we get authenticated, and in the response, we’ll receive the access token for calling Microsoft Graph. Before we can use the access token, we need to parse the JSON in the response body to make the token available to us in the dynamic content panel

The next step is to the parse the JSON response of the HTTP – Get Access token action and get the token type and access token to make a call to the Graph endpoint. To do this Add the action Parse JSON

  • The Content has to be the Body of the action HTTP – Get Access token and to build the schema.
  • Run the flow, copy the outputs [Body] of the action HTTP – Get Access token
  • Click the button Generate from Sample, paste the Body and click Done. These steps will generate the schema automatically
Parse JSON Action

The next step is to call the Graph endpoint using the HTTP action with the token type & access token on the Headers obtained from the above method

GET URI: https://graph.microsoft.com/v1.0/users/useremailaddress/calendar/events/eventID/attendees

Event ID should be the ID of the event you would like to get the attendees information and Headers information is constructed from the Parse JSON – Access token.

Run the Flow, you will now have the attendee’s information in the JSON format as shown below. The JSON will have information about the users details and the responses. JSON Parse action could be used to parse the JSON and get the information as per the requirement

Hopefully you enjoyed reading this article and find it useful.