Convert Speech to Text using OpenAI Whisper in Power Apps

OpenAI has released a new neural network called Whisper, which is an open-source model that can convert speech to text with impressive accuracy. This model is specifically designed to transcribe spoken language into text with high precision and speed, making it an ideal tool for a variety of applications, such as virtual assistants and video captioning. Whisper relies on advanced machine learning algorithms to analyze audio signals from multiple languages and convert them into written text. OpenAI has recently made API endpoints available to the public since March 1, 2023, allowing developers to easily integrate this powerful technology into their own applications.

The Speech to Text Open API can

  • Transcribe audio into whatever language the audio is in.
  • Translate and transcribe the audio into English.

As of the date I am writing this post, this model is not available in Azure. In this blog post, I will cover how to use the Microphone control and File Upload control to convert speech to text using the OpenAI Whisper API in a Power Automate flow.

Download Link to the Sample App: https://github.com/ashiqf/powerplatform/blob/main/OpenAI-SpeechtoText.msapp. Replace the API Key in the Power Automate flow HTTP Action Authorization Header.

OpenAPI Speech to Text API:

The speech to text API provides two endpoints, transcriptions and translations. At present, the maximum file size allowed for uploads is 25 MB and the supported audio formats are mp3, mp4, mpeg, mpga, m4a, wav, and webm. In this blog post, I utilized the Translation API to demonstrate its capability to convert English audio into text, it can understand other languages as well

POST https://api.openai.com/v1/audio/translations

If you have not yet created an API key, please sign up/login for OpenAI and obtain it from there.

Body:

Integration with Power Apps:

I have used a Power Automate flow with the Power Apps trigger to invoke the Speech to Text API via the HTTP connector in Power Automate. Alternatively, you can achieve the same outcome by constructing a Custom Connector. This sample app can be downloaded from this github link.

Microphone Control:

The audio control captures audio input through the device’s microphone and will be sent to the Power Automate flow for conversion into text using the Whisper API. The audio format of the recording depends on the type of device being used

  • 3gp format for Android.
  • AAC format for iOS.
  • Webm format for web browsers.

I’ve tested this control from the app accessed through the web browser. If you encounter an unsupported audio format for OpenAI, you can use utilities such as FFMpeg. Additionally, a .Net version of the control is available for download which can be used in Azure Function. John Liu (MVP) has written a sample Azure function that handles the conversion of audio formats using the aforementioned utility.

Step 1: To add a microphone control to the canvas, insert the Microphone control from the command bar. To preview the recorded audio from the Microphone control, add an Audio control

Step 2: Add a button to convert and to trigger the Power Automate flow. Find below the Power FX code

//Generates a JSON Text with the binary of the Audio file or Recorded audio
Set(varJson,JSON(Microphone1.Audio,JSONFormat.IncludeBinaryData));
Set(strB64Audio, Last(Split(varJson, ",")).Value);
Set(strB64AudioContent, Left(strB64Audio, Len(strB64Audio) - 1));
//Extract Audio Format
Set(varAudioFileType,Mid(varFileContent,Find(":",varFileContent)+1,Find(";",varFileContent)-Find(":",varFileContent)-1));
//Call the Power Automate Flow
Set(audioText,'SpeechtoText-OpenAIWhisper'.Run(strB64AudioContent,varAudioFileType).audiotext);

The Power FX code performs the following task

  • Stores the audio captured by a Microphone control in a variable as JSON data, including binary data.
  • Extracts the base64-encoded audio content from the JSON data using the string manipulation functions Split, Left, Mid.
  • Determines the audio file type by parsing a string variable.
  • Uses the extracted audio content and file type to call the Power Automate flow ‘SpeechtoText-OpenAIWhisper’ to obtain the corresponding text transcription which comes in later section of this post.
  • Assigns the resulting text transcription to a variable named ‘audioText’, this is assigned to a Text Label to display the converted text from the OpenAI Whisper API.

Step 3: Add a Label control to display the converted Text set to the variable audioText

File Upload Control

As of the day I am writing this post there is no file control that can handle all types of files in Power Apps, I have created a custom component utilizing the Attachment control to create a file attachment control. For further details, please refer to blogpost Uploading Files Made Easy: A Guide to Using the Attachment Control in Power Apps to add the control to the app.

Step 1: Add the file attachment control to the app from the component library. Set the input property for Maximum Attachments to 1 from the component.

Step 2: To extract the binary content of an audio file, add an Image control to the app. The Image control is capable of working with any type of file to extract its content.

Step 3: Add a Button control to convert the Audio from the uploaded file. Find the PowerFX below

//Generates a JSON Text with the binary of the Audio file using the Image control
Set(varFileContent,JSON(Image1.Image,JSONFormat.IncludeBinaryData));
//Extract Base64 content
Set(varExtractedFileContent,Last(Split(varFileContent,",")).Value);
//Remove the last character " from the string
Set(varExtractedFileContent,Left(varExtractedFileContent,Len(varExtractedFileContent)-1));
//Extract Audio Format
Set(varAudioFileType,Mid(varFileContent,Find(":",varFileContent)+1,Find(";",varFileContent)-Find(":",varFileContent)-1));
//Call the Power Automate Flow
Set(audioText,'SpeechtoText-OpenAIWhisper'.Run(varExtractedFileContent,varAudioFileType).audiotext);

Step 4: Add a Label control to display the converted Text set to the variable audioText

Power Automate Flow

Now, let’s create a Power Automate flow with the Trigger type Power Apps to invoke the OpenAI Whisper API and convert speech to text. Step 1: Add two compose action (input parameters) to receive the audio format and content from either the recorded audio captured by the Microphone control or the uploaded audio file from the file attachment control in the Power Apps

{
  "$content-type": @{outputs('Compose-AudioFormat')},
  "$content": @{triggerBody()['Compose-FileContent_Inputs']}
}

Step 2: Add a HTTP connector to make a request to the Whisper API endpoint. Refer to the blog post How to use form-data and form-urlencoded content type in Power Automate or Logic Apps HTTP action for handling multipart/form-data in the HTTP action

Request Body:

{
  "$content-type": "multipart/form-data",
  "$multipart": [
    {
      "headers": {
        "Content-Disposition": "form-data; name=\"model\""
      },
      "body": "whisper-1"
    },
    {
      "headers": {
        "Content-Disposition": "form-data; name=\"file\";filename=\"audiofile.webm\""
      },
      "body": @{outputs('Compose-FileContent')}
    }
  ]
}

Step 3: Add the Respond to a PowerApp or a flow action to pass the converted text back to the app. To get the converted text, use the following expression

body('HTTP-CallaOpenApiModel')['Text']

The expression was constructed based on the response of the Whisper API call. In the event that the response property changes in the future, please ensure to update the expression accordingly.

Summary:

In this post, I’ve outlined a step-by-step guide on how to develop a basic app with Speech to Text functionality using Power Apps and a Power Automate flow leveraging the OpenAI’s Whisper API. The possibilities for using this technology are endless, from creating virtual assistants to generating audio captions and translations. Furthermore, the Whisper API can also be used to transcribe video files, adding even more versatility to its capabilities. It’s worth noting that while Azure offers its own Speech to Text service, it currently does not rely on the OpenAI Whisper Model. However, it’s possible that the two services will eventually integrate in the future. 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.

Do you like this article?

Subscribe to my blog with your email address using the widget on the right side or on the bottom of this page to have new articles sent directly to your inbox the moment I publish them.

Advertisement

How to copy an existing DLP Policy in Power Platform

DLP policies are essential in ensuring that data is managed uniformly across an organization, thereby preventing critical business data from being accidentally published to social media or other connectors. These policies can be created at both the tenant and environment levels, with management handled through the Power Platform admin center. However, it is currently not possible to copy an existing DLP policy from the Admin center. This limitation can create difficulties when there is a need to create new policies based on an existing one.

In this blog post, we will explore various options for copying existing DLP policies to streamline the process. By using these options, you can save time and effort when creating new policies based on existing ones.

  • Power Automate Flow
  • DLP Editor Power Apps from CoE starter kit app
  • Power Shell

Note: To create a DLP policy at the Tenant level, you must be a Power Platform or Global Administrator role in AD.

Power Automate Flow:

The Power Platform Connector for Admins, available in both Power Automate and Power Apps, offers a range of environment lifecycle management capabilities, including DLP policy management.

To copy an existing DLP Policy, we will be utilizing the action List DLP Policies and Create DLP Policy in a Button Flow

Step 1: In the trigger, create two parameters to get the input for the existing Policy Name and the New DLP Policy name followed with the action List DLP Policies from the connector Power Platform for Admins to list all the policies in the Organization

Step 2: To select the DLP policy that you want to copy in a Power Automate flow, add a Filter Array action. This action filters the DLP policies obtained from the List DLP Policies action based on a condition. Specifically, it checks whether the displayName of the DLP Policy from the DLP Policies list action matching with the trigger input Existing DLP Policy Name. Once the Filter Array action is executed, it returns a new array containing only the DLP policy that meets the condition. This filtered array can then be used as input for creating a New DLP policy

Step 3: Add the action Create DLP Policy from the Power Platform for Admins connector with the first property Display Name from the Trigger input. For the other input parameters for the action, use the expression from Output of the Filter Array action as shown below

body('Filter_array')[0]['defaultConnectorsClassification']
body('Filter_array')[0]['connectorGroups']
body('Filter_array')[0]['environmentType']
body('Filter_array')[0]['environments']

Save the changes to ensure that they are preserved. Once you have saved the flow, you can test it to make sure that it works as intended. I have the flow definition saved in my github if you wanted to take a copy of it.

CoE Starter Kit App:

The Center of Excellence (CoE) starter kit core components solution includes a Canvas app DLP Editor with a range of useful features to manage and administer DLP policies. One such feature is the ability to copy an existing Data Loss Prevention (DLP) policy, making it easy to replicate policies across multiple environments or tenants.

This app uses the Power Platform for Admins connector.

Power Shell:

Power Apps Administration PowerShell provides a convenient set of cmdlets that enable you to easily create and manage Data Loss Prevention (DLP) Policies. Microsoft has provided a helpful sample script that allows you to manage your tenant and environment policies. With this script, you can perform a wide range of tasks related to DLP policies, including creating new policies, reading existing policies, updating policies, and removing policies. The sample can be found here. By breaking down the sample script into manageable sections, you can gain a deeper understanding of how DLP policies work and how you can modify them to suit your organization’s needs with PowerShell.

Summary:

This blog post provides a overview of different methods that can be used to copy existing Data Loss Prevention (DLP) policies, which is currently not available from the Power Platform admin center. These techniques can help automate the DLP policy creation process, saving time and effort.

Do you like this article?

Subscribe to my blog with your email address using the widget on the right side or on the bottom of this page to have new articles sent directly to your inbox the moment I publish them.

Uploading Files Made Easy: A Guide to Using the Attachment Control in Power Apps

The Attachment control in Power Apps is a useful feature that allows users to upload and delete files, but it can only be used with data sources such as SharePoint List or Dataverse table. However, if you need to upload and delete files without using these data sources, you can create a custom component using the Attachment control or you can directly use this control in the app. I have followed the tip from Shane Young in this YouTube video to add the Attachment control to a component library.

By creating a custom component Library for the attachment control, you can upload and delete files similar to a Picture control but with the ability to handle any file type across any apps within an environment. This blog post is not a tutorial on how to create the component, but rather

  • How to use it
  • To Save the file in SharePoint Document Library using Power Automate Flow
  • How to customize the component to fit your needs.

How to use it – Add the Component to the Power Apps:

To incorporate this component into your app, you need to first import it into your environment. Please find below the steps to follow

Step 1: Download the component library from my github repo.

Step 2: Create a Blank Canvas App with a temporary name, on the studio command bar, click on the ellipsis > Click ‘Open’, browse to select the downloaded .msapp package. Save the App and then publish it. You would now be able to see the component from the Component Libraries.

Step 3: After following the instructions outlined in this documentation to import the Published component into your app, the component will be available for use in any app within the environment as shown below.

Step 4: Modify the input parameters of the component to adjust settings such as maximum number of attachments, border colour, attachment size, and other defined parameters of the component.

Step 5: To display the uploaded file content within the app or to send the file to a Power Automate flow, you can incorporate any of the following controls based on the file type:

In the Media Property of the control, the formula to display the file content is

First(FileAttachment_1.Attachments.FileAttachment).Value

The file content will be uploaded to the app as binary data with the URL appres://blobmanager/ for each file uploaded from the attachment control. To get the file Name:

First(FileAttachment_1.Attachments.FileAttachment).Name

Note: In the above screenshot, I have set the Max Attachments Component property to 1 in the Step 4

Send the File to Power Automate:

In order to send or store a file using a Power Automate flow, I needed to convert the file content to Base64 format. To accomplish this, I used a image control to capture the file content in binary format. Here is how I configured the image control:

This control works with any types of files to get the binary content.

After obtaining the binary content of the file using the JSON function, I performed some string manipulations to extract the binary content while excluding the Content-Type. Specifically, I used a combination of Split(), Left() and Last() functions to separate the content into an variable varExtractedFileContent.

Set(varFileContent,JSON(Image2.Image, JSONFormat.IncludeBinaryData));
Set(varExtractedFileContent, Last(Split(varFileContent, ",")).Value);
Set(varExtractedFileContent, Left(varExtractedFileContent, Len(varExtractedFileContent) - 1));

By performing these manipulations, I was able to extract the binary content of the file in a format that could be easily passed to a Power Automate flow or other API or action.

This allowed me to send the file to a Power Automate flow, which could then save the file in a SharePoint library or call some other API or action that required the data to be in Base64 format.

The Power Automate flow used to save the file to a SharePoint Document Library is simple. The flow consists of a Power Apps trigger and a SharePoint action Create File, which takes two input parameters: File Name and File Content.

I have used the base64toBinary() expression to convert the base64-encoded string to binary data. This expression is a prerequisite for the SharePoint create file action and ensures that the file is saved correctly to the SharePoint Document Library.

PowerFx to call the flow from Power Apps:

ProcessAttachments.Run(First(AttachmentComponent_1.Attachments.FileAttachment).Name,varExtractedFileContent);

If you need to upload multiple files to a library using the Attachment control, you can use Gallery control with the Image control, Collections, ForAll function, and the OnAddFile property from the Attachment control. First, create a collection to store the files that are uploaded using the Attachment control using the OnAddFile property. Then, use the Gallery control to load the binary of the uploaded files in the Image control. Next, use the ForAll function to iterate through each file in the gallery and call the Power Automate flow on a button click.

Customizing the Component:

The component I’ve created is a simple one for handling file attachments, but it does not have all the properties from the Attachment control. If you need more customization, you can easily modify it to suit your specific needs by adding additional input or output properties.

To add a new property, you can simply edit the component code and include the new property as an input or output parameter.

By customizing the component in this way, you can tailor it to your specific requirements and ensure that it meets all of your file attachment needs

Summary:

In summary, the Attachment control in Power Apps is a useful feature for uploading and deleting files, but it is limited to certain data sources. To work around this limitation, you can create a custom component using the Attachment control, which allows you to handle any file type and bypass the use of data sources like SharePoint or Dataverse tables. 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.

Do you like this article?

Subscribe to my blog with your email address using the widget on the right side or on the bottom of this page to have new articles sent directly to your inbox the moment I publish them.

Send Teams Activity Feed notification from Power Automate using custom Teams Bot

Activity feed notifications appears in the Teams activity feed panel with link to various locations thus enabling developers to build actionable content. These notifications are sent as push notifications in the Teams client. In this blogpost, let us see how to send Teams activity feed notification using

  1. Custom Teams App with a Bot
  2. Power Automate standard action: Post a feed notification

Pre-Requisites:

Custom Teams App with a Bot:

Microsoft graph has API endpoints to send activity feed notifications to Teams users. The pre-requisite to use the activity feed graph endpoint is to have a custom Teams app scoped to a Team, or in a chat or user.

Step 1: Custom Teams App scoped to Team:

For this blogpost, I have used a custom Teams app scoped to a Team. Refer to the following blogpost to create a custom Team app scoped to a Team with a Bot capable of sending an Adaptive card message on a channel

Do not install the Teams App yet before completing the other steps given below. After the Teams bot is created, a custom Azure Active directory Application must be registered.

Step 2: Azure AD Application – Microsoft Graph Activity Feed permission:

Register an Azure AD application to add the Microsoft Graph permission to be send activity feed. Copy the Application (client) ID and Tenant Id of the registered app from the Overview section and create a secret from the Certificates & secrets under Manage blade per the screenshot shown below. Once the secret is created, copy the value to be used in the Power Automate cloud flow

Add the application permission TeamsActivity.Send with an admin consent.

Step 3: Link the AD app to the Teams App

The AD application with permission to send activity feed is created, the next step is to link the Teams app created in Step 1 with the AD app. In the Teams Developer portal, enter the Application (client) ID in the apps Basic Information under the Overview section as shown in the below screen shot

Don’t forget to Save the App in the Developer portal after the Application ID is entered. Now go to the App Features and then click Activity Feed notification as shown below

Click + Add an activity and enter the following information per the screenshot below

Type: informationBroadcasted

Description: Information Broadcasted Activity

Title: Notification from {actor} broadcasted by {broadcastedBy}

Click Save. The Teams app is now ready to be installed, follow the instructions here to install the bot in a Team for testing the Activity Feed notifications.

Power Automate Cloud Flow to send Adatpive card message and Activity Feed:

The Teams app is ready and now let’s create an Instant cloud flow with manual trigger to send an Adaptive card message to a Teams channel (General or any standard channel) and then Deep link to the adaptive card post in the Teams Channel to the activity feed notification.  I have used a Premium HTTP connector action to send the adaptive card using Bot Framework REST API. Go through the following post to send the Adaptive card

In the flow after the action HTTP-SendAdaptiveCardMessage, add a compose action with the following expression to get the Message ID of the Adaptive card channel message

body('HTTP-SendAdaptiveCardMessage')?['id']

Add two compose action to store the TeamIdorGroupId and TeamChannelID as shown below

Add a HTTP action (Premium) to send the activity feed to all Team members (Beta) using the Graph Activity Feed API. Find the details below for the HTTP request

Type: POST

URI: https://graph.microsoft.com/beta/teams/teamIdorGroupId/sendActivityNotification

Replace teamIdorGroupId from the compose action

Body:

{
  "topic": {
    "source": "entityUrl",
    "value": "https://graph.microsoft.com/v1.0/teams/@{outputs('Compose-TeamIdorGroupId')}/channels/@{outputs('Compose-ChannelID')}/messages/@{outputs('Compose-MessageId')}"
  },
  "activityType": "informationBroadcasted",
  "previewText": {
    "content": "Urgent Information"
  },
  "recipient": {
    "@odata.type": "microsoft.graph.teamMembersNotificationRecipient",
    "teamId": "@{outputs('Compose-TeamIdorGroupId')}"
  },
  "templateParameters": [
    {
      "name": "broadcastedBy",
      "value": "Mohamed Ashiq Faleel"
    }
  ]
}

If you are having issues (Invalid Expression) while saving the flow, add additional @ keyword in the recipient as shown below

Click Show advanced options in the HTTP action to enter the Authentication details. Enter the Client (Application) ID, Secret and Tenant Id from Step 2

Time to test the Power Automate flow. Find below the Activity Feed message for a Teams user

Note:

The Teams app can also be enabled with Resource Specific Consent, to do so in the Teams Developer portal click Permissions on the Left bar. In the section Team Permissions select TeamsActivity.Send.Group under Application. If you have done this, Step 2 is not required. I will cover this in a different blog post.

Power Automate standard action: Post a feed notification:

There is a standard Teams action Post a feed notification which creates an activity feed with/without Deep link to a chat or Teams Channel using the Power Automate Teams Bot. Find below the action

Summary:

Isn’t this powerful to have engaging and actionable content for the users in Teams. There can be many use cases which could be applied for this setup e.g: Notify user and deep link to a Power App added in Teams channel 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.

Do you like this article?

Subscribe to my blog with your email address using the widget on the right side or on the bottom of this page to have new articles sent directly to your inbox the moment I publish them.

Send Teams channel message aka proactive message using custom Teams bot and Power Automate – Part 2

In the last post, we have seen till the installation of the Teams App with the Bot on a Microsoft Team. Let us now continue to send a proactive message, be it an Adaptive card or a simple Text message on a Teams channel using Bot Framework REST API from a Power Automate Cloud Flow.

A proactive message is any message sent by a bot that isn’t in response to a request from a user. Ex: Welcome messages, Notifications, Scheduled messages, Broadcast message etc

Power Automate Cloud Flow:

For this blog post, I have used a Power Automate Instant cloud flow with manual trigger to send the message to a Teams Channel. To follow along the blog post, be ready with the following information

  1. Team ID & Channel ID

This information is required to send the proactive message to a Microsoft Team Channel. To get this information, in Microsoft Teams Client identify the Team channel in scope > Click the ellipsis of the channel in scope > Get link to channel as shown below

After decoding the channel link, the url will be in the format as shown in the below image from which you can get the channel Id and Team group ID

If you are building a Teams broadcaster or communicator application using Power Apps, these information can be stored in Table or a SharePoint list. There are Graph API endpoints which can used to get the Channel Id’s etc.

  1. Bot ID [Part 1 – Step 6]
  2. Bot Secret [Part 1 – Step 7]
  3. Teams Service URL

The service URL is the base URI for all Bot framework API requests. In Teams the service URL will change based on user’s region [EMEA, America, APAC, India etc]. This example delivers messages only on the Team channel and not to the users directly so you can choose the service URL based on the Microsoft 365 Tenant Location. Find below some URL’s based on region

RegionService URL
EMEAhttps://smba.trafficmanager.net/emea/
Americahttps://smba.trafficmanager.net/amer/
Indiahttps://smba.trafficmanager.net/in/
APAChttps://smba.trafficmanager.net/APAC/

All the required information is now available to proceed with sending the channel message using REST API.

Generate Access Token – Bot Framework REST API:

There are SDK’s in Bot Framework for programming languages like .NET, JavaScript, Python etc to handle all conversations for you but an alternative to using the SDK is leveraging Bot Framework REST API. The first step in using the different REST API endpoints from Bot Framework is to generate an access token which is then added to the Authorization header of each API request in this format

Authorization: Bearer ACCESS_TOKEN

To request an access, make a HTTP request per the following details

Method: POST

Request URL:

https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token

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

Body:

grant_type=client_credentials&client_id=botId&client_secret=botSecret&scope=https://api.botframework.com/.default

Replace the botId and botSecret with the values stored from the previous steps. The Bot Id and the secret are from the custom Teams app created based on the previous post.

Add a HTTP Action in your Power Automate flow to add the above details for generating the token

The JWT access token is valid for 24 hours, if the token expires make another request.

Send Teams Channel Message:

The Teams Channel conversation post or proactive message on a channel can now be sent using the REST API to Create Conversation with the access token generated in above step.

Simple Text Message:

Find below the HTTP request detail to send a simple proactive message on a Teams Channel. The conversation Id is the Teams Channel Id

Type: POST

Request URL:

https://smba.trafficmanager.net/emea/v3/conversations/teamsChannelId/activities

Replace teamsChannelId (conversationId) with the actual Team channel Id

Body:

{
  "type": "message",
  "text": "Simple Text Message"
}

Authorization Header: Bearer access_tokenvalue

The Authentication of the HTTP action should be set to Raw, the value should be in the format

Bearer access_token

You can use Parse JSON Action to extract the access token from the previous HTTP action HTTP-GenerateBOTToken or you can directly get the value using the following expression

body('HTTP-GenerateBOTToken')?['access_token']

The above HTTP request will create a HTTP response with the activity id which can be potentially used to send a reply etc.

Adaptive Card Message:

Adaptive cards are platform-agnostic snippets of UI authored in JSON that different Microsoft apps and services like Teams, Outlook can use. It can be designed using the Adaptive Card designer portal. To send an Adaptive to a Teams Channel, everything else remains the same when comparted with above give HTTP request for the Simple Text message except the Body as below

{
  "type": "message",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
       "msTeams": {
          "width": "full"
        },
        Replace the ADAPTIVE CARD JSON PAYLOAD from the designer portal
      }
    }
  ]
}

You can get the complete body of request from this Link. This method can be used to send the message on any standard channel but not on Private Teams channel, Microsoft has not opened the possibility to send a channel message on private channel using a Bot. Find below adaptive card message posted on the Teams Channel from the Power Automate flow

Summary:

There are lot of possibilities with the Bot connector service REST API, what I have shown above is only an endpoint to send a message in a Teams Channel. Look at this documentation on the available conversation operations like Reply, Delete, Update conversation etc. Using this approach you can build a Company broadcaster app with the possibility of reaching out to multiple Teams without the user being the member or owner of the Team. If you are visiting my blog for the first time, please do look at my other blogposts.

Do you like this article?

Subscribe to my blog with your email address using the widget on the right side or on the bottom of this page to have new articles sent directly to your inbox the moment I publish them.

Send Teams channel message aka proactive message using custom Teams bot and Power Automate – Part 1

Microsoft Teams connector in Power Automate has actions which can send a simple text message or Adaptive card as a flow bot in a Teams channel. Messages or cards are posted as the user who’s signed into the connector in the flow or by using the flow bot.

Messages can be posted on a Teams channel only if the signed in user or account of the connector is a member or an Owner of the Microsoft Team. Recently I had a requirement from my customer to post or broadcast messages on numerous Teams channels (> 1000). It is impossible per the limits for Microsoft Teams to have a dedicated service account as a member of all teams in scope. There is no graph API with application permission which can send a message in a channel. In this blog post, let us see how I have overcome the limitation of posting a message or card in multiple teams with the help of

  1. Custom Teams App with a Bot
  2. Installation of Teams App in Teams
  3. Bot connector REST API to post a Message or Adaptive Card aka proactive message

Custom Teams App with a Bot:

The teams in scope to receive the channel post or Adaptive card message should have a custom Teams app installed. The Teams app should have a Bot as its app features enabling the Microsoft team to receive the message. In this section, let us see how to create a Teams App with a Bot using the Developer Portal for Teams. Step 1: Login to the Teams Developer portal using your Microsoft 365 login ID and then Click + New app as shown below

Step 2: In the following screen for the Basic information of the app, enter the following mandatory information like Short name, App ID (Auto Generated), Short description, Long description, Developer or company name, Website (Valid HTTPS URL), Privacy policy url, Terms of use url. Once all of the above information is entered, click Save at the top left corner as shown below.

To apply a custom logo or an app icon for the Teams app, click Branding on the left navigation bar in the Teams developer portal as shown above.

Application (client) ID – Teams Activity Feed:

You can leave the Application (client) ID as blank. This section will be filled for custom Teams Activity Feed use case.

Step 3: On the left navigation, click App features > Bot

Step 4: Click Create a new bot which will take you to the Bot management portal. If you already have a bot where you are an Owner, it will be listed in the dropdown as shown below.

Step 5: In the Bot management, click + New Bot > Enter the name of the bot > Add

This step also registers an Azure AD app registration in the Azure AD Portal.

Step 6: Once the bot is added. In the Bot management portal url from the Developer Portal, copy the Bot ID and keep it handy to be used in the Power Automate cloud flow.

Step 7: Now click the registered bot in the above screen to Add a secret as shown below. As soon as the secret is generated, copy the value and keep it handy to be used in Power Automate cloud flow.

To change the logo of the Bot, login to this URL https://dev.botframework.com/bots

Step 8: Go back to the created Teams app in the Developer Portal, in App features > Select the created bot > Set the scope to Team > Save

Installation of Teams App in Teams:

The Teams app is now configured with required features to send Teams channel conversation post. Download the App manifest package from the Developer Portal as shown below

Upload app in Microsoft Teams [Side Loading]:

Go through this Microsoft Documentation link to sideload the Teams App to your Teams client as a developer before publishing the package to the Teams Organization App catalog.

Go to the Teams Desktop Client > Apps > Manage your apps > Upload a custom app > Select the App manifest Zip package from above step > Add to a team > Select the Team to install the app > Setup a bot.

Find below the screenshot for your reference from Teams Desktop client

To validate the installation of the app, go to the Installed Team > Manage Team > Apps > You can find the installed app as shown below

Upload app in Microsoft Teams [Organization App Catalog]:

After the app is tested, the app can be deployed at scale once the app is available in the Teams Organization App catalog through Graph API. The pre-requisite to call the Graph API enpoint to install the app is the

  1. Teams ID (Group ID)
  2. Teams APP ID from the App catalog

Summary:

In the next post I will cover how to use Bot Framework REST API in Power Automate Cloud Flow to send the Adaptive card message in a Teams Channel. If you are visiting my blog for the first time, please do look at my other blogposts.

Do you like this article?

Subscribe to my blog with your email address using the widget on the right side or on the bottom of this page to have new articles sent directly to your inbox the moment I publish them.

How to use form-urlencoded content type in Power Automate Custom Connector

Content type x-www-form-urlencoded is used generally to send text data in a query string in the form of name value pairs separated by ampersand. In this blog post, let us see how to use the content-type

  • x-www-form-urlencoded

in a Power Automate custom connector. Refer to this post, if you would like to find out how to use it in a HTTP connector. Find below the screenshot from postman with an API from Twilio (Sample) to send a WhatsApp message with content type x-www-form-urlencoded

x-www-form-urlencoded in a Custom Connector:

The x-www-form-urlencoded content type has its form data which is encoded and sent in a single block on the HTTP request body.

Custom Connector:

To call the above API with the content type x-www-form-urlencoded in a custom connector, the first step is to create a connector from blank with the authentication type filled in (Basic, API Key etc) on the security tab. Now Add a New action to the call the above API. Click + Import from sample to enter details of the API request like Verb, URL and Headers (Content-Type application/x-www-form-urlencoded) and Body. For Body, just add {}. The content on body will sent on the Power Automate cloud flow. PFB screen shot for the action definition

After the above details are entered, click Import.

In the Request section, click the Content-Type under Headers, enter the default value application/x-www-form-urlencoded and then make it required with the visibility set to Internal. This setting will hide the parameter from the cloud flow

Make the body required. Create the connector after all the details has been entered.

Custom Connector in Power Automate Cloud Flow:

The form values to be sent on the API request body with x-www-form-urlencoded implementation must be encoded & the values must be separated by ampersand. Expression encodeUriComponent can be used to encode the form values.

In the Cloud flow, add a compose action with all the values encoded and separated by ampersand (&). Now add the custom connector action which will prompt you to create a connection. In the body section, from the dynamic content select the Outputs of the compose action.

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.

Do you like this article?

Subscribe to my blog with your email address using the widget on the right side or on the bottom of this page to have new articles sent directly to your inbox the moment I publish them.

How to create & setup Dynamic Microsoft 365 Group or Distribution list based on the user’s domain for Teams, Yammer and Exchange

There are many organizations maintaining multiple domains on a single Microsoft 365 or Azure AD tenant, in those cases there might be a need to create dynamic Microsoft 365 groups, security groups & distributions list based on the user’s domain to manage the group’s membership. On this blogpost, let us see how to

  1. Create Dynamic Microsoft 365 group based on the user’s domain for Teams & Yammer
  2. Create a Dynamic distribution list based on user’s domain in Exchange online

To begin with let us see some basics of a Dynamic group. The membership of a dynamic group will automatically update as people join, leave, or move within the organization whenever the user’s Azure Active Directory attributes are changed. In simple terms, rules determines the group membership. The users will be added or removed automatically as and when the user attributes change or users join and leave the tenant which reduces the administrative effort of adding and removing users from a group. Dynamic group can be created based on variety of attributes including role, location, department etc.

Create Dynamic Microsoft 365 group based on the user’s domain for Teams & Yammer

Microsoft Teams and Yammer (Microsoft 365 Connected) supports dynamic membership. It enables the membership of Team or Yammer to be defined by one or more rules that check for certain attributes in Azure AD. Microsoft Teams & Yammer creates a Microsoft 365 group in Azure AD. For this post, the membership rule will be simple one which is based on the user’s domain and country. You can also have a complex rule involving multiple Azure AD attributes like Title, Geography, Department etc. Before we proceed further, there are some pre-requisite & facts to be considered before creating a dynamic group.

  • User Administrator or Global administrator role in Azure AD
  • Users you foresee to be part of a dynamic group membership rule should have an Azure AD premium License P1 or P2
    • Microsoft 365 E3, E5, Front line workers MF3 & MF1 has Azure AD premium 1 service which should suffice.
  • An Azure AD organization can have maximum of 5000 dynamic groups.
  • Any number of Azure AD resources can be members of a single group.

Dynamic Membership based on Domain for Teams:

To create a Dynamic membership MS team, create a Microsoft 365 group first with Dynamic membership in Azure Active directory. You can create a dynamic group from PowerShell but here I will be using Azure Ad GUI to create the dynamic Microsoft 365 group with rule to add users based on their domain and country. I have added a domain m365pal.me to my Azure AD tenant which I will be using here for this example.

  1. Sign in to Azure AD Admin center with administrator role in the Azure AD organization
  2. Click Groups and then click + New Group
  3. Select the Group type as Microsoft 365. Dynamic membership will also work with Security group but for team it should be Microsoft 365 group.
  4. Enter the Group Name & Group email address
  5. Select the Membership type as Dynamic User
  6. Select the Owner and then
  7. Under Dynamic user members section, click Add dynamic query
  8. In Dynamic membership rules panel, add rule to define membership based on users domain & country
    • First rule for Domain: under Property column select userPrinicipalName, Operator should be Contains and the Value should be the domain name in format “@yourdomain.com”. This rule will add all users with the UPN user@yourdomain.com. Now click + Add expression to add the second rule
    • Second rule for country: under Property column select country, Operator should be  Equals and the value should be the country name.
  1. You can also validate the rules by clicking the link Validate Rules and then by adding users to check if the user satisfies the rule
  2. Click Save. This is how it should look like
  1. Click Create.
  2. After waiting for couple of minutes, check the group membership. Please find below screenshot for the group which has two members satisfying the condition. You can also notice the + Add members link is disabled since the group is dynamic membership and not assigned. To modify the rules, click the link Dynamic membership rules link.
  1. Now we are ready to create the MS Teams, go to https://teams.microsoft.com/ and then click Join or create a team at the left bottom corner and then Click Create a team
  2. Click From a group or team and then click Microsoft 365 group
  3. Now select the group you have created in Azure AD and then click Create.
  1. The team is now created, you can find the team on the list. Check the membership of the team which will have the two users satisfying the rules and the owner of the group. One more thing to notice here is the message which says The membership settings prevents you from adding or removing members.
  1. Voila! Dynamic Microsoft team is now created & setup.

If you have an existing team to be converted to a Dynamic team, find the Microsoft 365 group in Azure AD for the Team you wish to convert and then update the membership status from Assigned to Dynamic user with membership rules

Dynamic Membership based on Domain for Yammer:

Yammer (Microsoft 365 Connected) also supports dynamic membership. Find the steps below to create a dynamic yammer group based on the user’s domain. Find the steps below

  1. Sign in to https://yammer.com/ with your organizational ID
  2. Click Create a Community and then Enter the name of the Community
  3. Click the button Create
  1. Now sign in to Azure AD Admin center to the update the membership settings of the Microsoft 365 group connected to the Yammer community. Find the yammer group and then click
  1. Click Properties under the Manage blade and then change the membership type from Assigned to Dynamic user
  1. After updating the membership type to Dynamic user. You will now have option to enter the dynamic query. Click dynamic query
  1. In Dynamic membership rules panel, add rule to define membership based on users domain
    • Rule for Domain: under Property column select userPrinicipalName, Operator should be Contains and the Value should be the domain name in format “@yourdomain.com”. This rule will add all users with the UPN user@yourdomain.com. Now click + Add expression to add rules based on need
    • Click Save
  1. Click Save. Wait for couple of minutes for the membership to be updated.
  2. Now check the Yammer group in Yammer.com for the membership status. Please find below screenshot for your reference which will not have the + icon on the highlighted members section for adding users since this is now a dynamic yammer group

Also, Microsoft 365 group/Security group can be used for different use cases. See some sample use cases below

  • You can use to target SharePoint page/news to specific audience with the help of Microsoft 365 group or Security group. Will it not be more powerful if you use dynamic groups within a SharePoint to target content certain group of audience!
  • Assign Microsoft Licenses to users based on Dynamic Group.
  • Grant access to an App (PowerApps etc) using the dynamic group targeting certain departments, geographies etc

Reference:

https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/groups-create-rule

https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/groups-dynamic-membership

https://docs.microsoft.com/en-us/microsoftteams/dynamic-memberships

https://docs.microsoft.com/en-us/yammer/manage-yammer-groups/create-a-dynamic-group

https://docs.microsoft.com/en-us/yammer/manage-yammer-groups/yammer-and-office-365-groups

https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/directory-service-limits-restrictions

Create a Dynamic distribution list based on user’s domain in Exchange online:

Dynamic distribution groups are mail-enabled Active Directory group to distribute email messages to all its members within a Microsoft Exchange organization. Unlike regular distribution lists that contain a defined set of members, the membership list for dynamic distribution groups is calculated each time a message is sent to the group, based on the filters and conditions that you define in the group. You can create a Dynamic Distribution list from Exchange Admin center as shown below but the options to write advanced filter conditions or rules are limited so PowerShell is preferred.

Dynamic Distribution list from PowerShell:

Make sure the Exchange online PowerShell module is installed. There are some limitations to create a recipient filter (Rules) that worked based on user’s domain with the operator like or contains but there is a workaround. The filter works based on the exchange property WindowsEmailAddress which is always the primary SMTP address, you can also consider using the property WindowsLiveID. Follow the steps below to create a Dynamic Distribution list based on user’s domain

  1. Load the module by the running the command Import-Module ExchangeOnlineManagement
  2. Connect to the Exchange online PowerShell in Microsoft 365
Connect-ExchangeOnline -UserPrincipalName userId@domain.com -ShowProgress $true
  1. After authentication, enter the following command to create the Dynamic DL based on User’s domain. I have added the RecipientTypeDetails in the RecipientFilter to apply the filter rule only to user mailboxes which excludes the SharedMailboxes
New-DynamicDistributionGroup -Name "All Users - M365PAL DL" -RecipientFilter "(RecipientTypeDetails -eq 'UserMailbox') -and (WindowsEmailAddress -eq '*@yourdomain.com')"
  1. You can also validate the users using the following script
Get-Recipient -RecipientPreviewFilter (Get-DynamicDistributionGroup "All Users - M365PAL DL").RecipientFilter
  1. To view the attributes to be used in the recipient filter enter the following command
Get-User -Identity user@yourdomain.com | Format-List

Reference:

https://docs.microsoft.com/en-us/exchange/recipients/dynamic-distribution-groups/dynamic-distribution-groups

https://docs.microsoft.com/en-us/powershell/module/exchange/get-user

https://docs.microsoft.com/en-us/exchange/recipients/dynamic-distribution-groups/view-dynamic-distribution-group-members

Summary: On this post we have seen how to create dynamic groups based on user’s domain. Do some planning to start using the dynamic groups which will help reduce lot of administrative overhead. Hope you have found this informational & helpful. Let me know any feedback or comments on the comment section below

How to setup custom domain and email address in Microsoft 365 online tenant

On this blogpost let us see how to add a custom domain and configure exchange email address for the added domain in a Microsoft 365 tenant. This will allow you to create M365 identities for the users in the Microsoft 365 tenant like user@domain.com instead of user@domain.onmicrosoft.com. This setup is also required if you have a Hybrid setup with users from Onpremise Active directory. Azure AD connect tool helps you synchronize your AD identity from Onpremise to Azure AD or Microsoft 365 tenant directory only if there is a custom domain added to the directory. The custom domain can be added from Microsoft 365 tenant admin center or Azure Active directory portal associated to the M365 tenant.  

Pre-Requisites:

  • Own a Domain from any domain providers
  • Global administrator of Microsoft 365 tenant

If you don’t add a domain, user account in your organization will use the default onmicrosoft.com domain for their email address and UPN. To setup and configure a custom domain, you will have to

  1. Add a TXT or MX record
  2. Add DNS records to connect Microsoft 365 services

For this blog post I have used Domain.com provider to add the DNS records for the custom domain

Add a TXT or MX record:

The first step is to prove you are Owner of the domain and also make the domain is not associated to different tenant. To generate the DNS record values and to add the custom domain login to the Microsoft 365 Admin Center

  1. Select Show all > Settings > Domains
  2. Click Add domain
  3. Enter the custom domain name you own
  4. Click on the button Use this domain

Select Add a TXT record to the domain’s DNS records but you can also add a MX record or add a text file to the domain’s website. Find the different options

  1. The DNS record values for the TXT record will be generated as shown below. TTL 3600 seconds is 1 hour
  1. Add the DNS record for TXT from the domain provider interface for managing the records
  1. Go back to the Admin center and then click Verify. It takes around 15 mins to an hour for the DNS records to propagate, sometimes it may even take more time. Keep trying till the domain in verified. Once the domain is verified you will be able to proceed to the next step for configuring the Microsoft 365 services like exchange etc. You can also Skip and do the configuration later but with this setup you can create user accounts by using the custom domain as its UPN e.x user@domain.com without email address. Find instructions on this link to add a custom domain from Azure Active directory portal.

Add DNS records to connect Microsoft 365 services:

The domain is added & verified, now its time to connect the Microsoft services like Email (Exchange Online, Outlook), Mobile device Management aka MDM with the custom domain. On this post will be connecting only to Exchange online to receive email through Microsoft 365. After this setup is done Exchange online will be your new email host for the domain. After the domain is verified from the step above, select Add your own DNS records and click Continue button as shown below

The following DNS records will be generated as shown below

  • MX Records (Mandatory)
    • Sends incoming mail for your domain to the Exchange Online service in Office 365. Mails are delivered to the mail exchange server with the lowest preference number for this record, typically.
  • CNAME Records (Optional: For Outlook client to work)
    • Helps Outlook clients to easily connect to the Exchange Online service by using the Autodiscover service. Autodiscover automatically finds the correct Exchange Server host and configures Outlook for users
  • TXT Records (Optional: SPF record for prevention of spamming)
    • Helps to prevent other people from using your domain to send spam or other malicious email. Sender policy framework (SPF) records work by identifying the servers that are authorized to send email from your domain

Go back to the domain hosting provider interface to add the above DNS records, to get the values for each record expand each record shown on the above interface.

MX Record:

Set the priority to the Highest or to the number 0 and then add the DNS record. If the domain is xyz.com

Sample value/Content: xyz-com.mail.protection.outlook.com

CNAME Records:

Name: Autodiscover

Value/content: autodiscover.outlook.com

TTL: 1 hour

TXT Records (SPF):

There can be only one SPF record on the DNS records so if there are another record already (default), refer this link for more information. I already had the default one so the valye for the TXT record looked like v=spf1 ip5:XX.XX.XXX.X/XX include:spf.protection.outlook.com -all

ipX:XX.XX.XXX.X/XX is the default one

Now after all the DNS records are added, choose Continue. This will take you to the last page of the wizard with the message Domain setup is complete

Now the setup is completed, you can create users using the new custom domain or change an existing users UPN and email address on Admin center with the following steps

  1. Go to Users > Active users page
  2. Select the user’s name, and then on the Account tab select Manage username.
  3. On the Aliases box, enter the new alias@yourdomain.com and then click Add
  4. Select the new alias and if required change it to the primary email.

Summary: On this post we have seen how to configure a custom domain with email. There can also be multiple domains in one tenant. Hope you have found this informational. Let me know any feedback or comments on the comment section below

Reference:

https://docs.microsoft.com/en-us/microsoft-365/admin/get-help-with-domains/create-dns-records-at-any-dns-hosting-provider

https://support.microsoft.com/en-us/office/connect-your-domain-to-office-365-cd74b4fa-6d34-4669-9937-ed178ac84515

https://docs.microsoft.com/en-us/microsoft-365/admin/setup/add-domain

https://support.microsoft.com/en-us/office/add-a-new-domain-in-microsoft-office-365-285437c3-d6c9-45cd-8b48-ed29c670c796

https://docs.microsoft.com/en-us/microsoft-365/admin/setup/domains-faq?view=o365-worldwide

https://docs.microsoft.com/en-us/microsoft-365/enterprise/external-domain-name-system-records

https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/set-up-spf-in-office-365-to-help-prevent-spoofing?view=o365-worldwide