fotw Archives - Microsoft Power Platform Blog Innovate with Business Apps Tue, 10 Sep 2024 20:22:38 +0000 en-US hourly 1 Advanced | Flow of the Week: Triage and Team Assignment with Microsoft Flow http://approjects.co.za/?big=en-us/power-platform/blog/power-automate/advanced-flow-of-the-week-triage-and-team-assignment-with-microsoft-flow/ Wed, 29 May 2019 20:46:46 +0000 Triage and Team Assignment Flow Whats up Flow Friends! This post is written by George Culler and Brian Osgood from the Azure team.

The post Advanced | Flow of the Week: Triage and Team Assignment with Microsoft Flow appeared first on Microsoft Power Platform Blog.

]]>
Triage and Team Assignment Flow

Whats up Flow Friends!

This post is written by George Culler and Brian Osgood  from the Azure team. They Contacted me and asked to show me a set of Flows they had made for their team and after seeing this all in action, i asked them to share the post with all of you, as i know we can all use this same concept in many ways!

Anyways, onward and Enjoy!

 Overview:

Hi, Flow Community!

We are excited to share a customized Triaging and Team Assignment Flow which will help speed up your teams processing times and ensure more accurate work.

We built this Flow out of a need to quickly triage to the right teammate and check for errors in tickets coming from a much larger customer facing team. Below we will show you the steps taken to run Flow through five different checks, as well as send TFS tickets to the right team member for processing. This Flow allows your organization to cut down on churn between teams, provide more accurate information and overall improve customer experience. It will be assumed that you have a understanding of how Flow works so we are going to dive right into creation.

Prereqs:

  • Basic Expression Function Knowledge
  • Advanced Flow Knowledge
  • SharePoint list creation
  • Intermediate TFS / DevOps Knowledge

Steps:

Create a new Flow with a DevOps “When Work Item is Created” trigger

Fill in your required fields and select your work item type. For our Flow, we are using our in-house “Credit Issue” work item. (this helps the Flow pull the correct data fields if you have multiple work items)

We are going to be checking for five “pain points” on each work item. These five points are:

  1. Date issue reported; we have a requirement that issues be reported within a certain amount of days since service start.
  2. Is a file attached? We require that a calculation file be attached to some issues so we will need to check the issue category and then check a field for its value.
  3. Is this Issue a duplicate category for the same customer? We have a couple of one time use categories that we need to check aren’t given multiple times.
  4. Is the dollar amount below a certain threshold? If so, it should be marked by the creator as Pre-Approved.
  5. Auto calculate the dollar amount based on the exchange rate.

We will be running our checks in parallel so let’s add some parallel conditions and get this Flow started!

Date Reported:

Starting with a condition action, we will use the dynamic content to pull in the “Date Issue Reported” field. Our conditional statement will check if the field is blank. We used an expression for this with the “empty” function.

empty(triggerBody()?[‘fields’]?[‘Ops_DateIssuewasReported’])

This function returns true if the field is empty. If its empty, we tag it as “BOT: NODATE”. If the field is populated, we will perform some date calculations to check if the reported time is within 120 days of the Date Issue Started. Using the “Date Time” connector and the “Add to Time” action. We can add 120 days to the Date Issue Began field.


We now have two Dynamic date values we can use, but to compare the date difference, we will use another expression function, the “Ticks” function which we can use in a conditional action to compare if our date issue started + 120 days is greater than the date issue was reported.

ticks(triggerBody()?[‘fields’]?[‘Ops_DateIssuewasReported’])

ticks(body(120_Day_Addition))

If the condition results in a “Yes” then we will tag the ticket as “BOT: 120Days” and leave a message in the Bot Box (this is a field we have added to our TFS template that automatically displays a message when a ticket is created incorrectly). If the condition results in a “No” we do nothing as the ticket is within our criteria.

Calc. file check:

Currently, our check for the file is dependent on if the creator has marked “No” in a dropdown. If so, we tag it “BOT: CF” and then update our custom “Bot Box” to have a message.




Empowerment Check:

For this branch, we will use our SharePoint connector to pull from a custom list. We add a SharePoint action “Get Items” and add our site address and select our List Name. This will return an array that we need to iterate through using the “Apply to Each” action on the “value” dynamic variable from our “Get Items”.


We then run a condition on the ticket item checking for criteria, if its marked correctly, and what the dollar amount is in USD.

If the condition returns a “Yes” we tag the ticket with “BOT: EMP” and leave a message in the Bot Box. We played with the idea of re-assigning the ticket to the creator but that would cause too many headaches for the small amount of time we might save.

Duplicate scenarios:

Since we have three, one time use categories, we need to make sure we are not giving a customer more than once, however we have thousands of customer’s so we cannot just go look over every customer’s request and find certain categories every time. We built a custom query in TFS to pull all tickets where we approved a refund in those categories within the last two months. We then used the DevOps connector “Get Query Results” action to find our custom query and pulled from it.

This returns an array, so we need to use the “apply to each” action again. Inside the “apply to each” we need get the details of each ticket. For this we use the DevOps “Get Work Item Details”. After we have the details, we run a condition, this checks if the customer number on the new ticket is equal to the customer number in an old ticket and if the category is the same for that ticket.

If the conditions are met, we update the ticket, and you get one guess on what we do to the ticket… did you say, “Tag it”? Congrats, we tag it!

Currency Calculation:

This one was tricky to do and involves A LOT of string parsing and variable initialization. Here is the branch overview.

We won’t go through all the individual variables, but I will go over the FX Rate (Exchange Rate) and how we pull from a list and parse the value out. Inside of DevOps, we have a tab that is manually updated by the finance group. It is a long list of semicolon separated values for each of that month’s specific exchange rates for each currency. We will use the split expression function to split on a delimiter. The format of the list is:

USD-1; EUR-0.9;

So we need to split on the semicolon and then the dash. This is the expression we used.

float(split(split(split(variables(‘FX Rates For Current Month’),variables(‘currency value’))[1],’;’)[0],’-‘)[1])

It returns a float that corresponds to the currency that is used in the ticket and the month the ticket was created to then use for a local currency to USD calculation.

Once all the variables are created, we can update the TFS work item with our Tag, “BOT: FX”. All our branches are completed, if there are issues with any of these instances, they will be tagged for the team member to be made aware of and check.

So, let’s go to the final step.

Pre-Triage Tag:

Once all checks have been run, if the ticket passes all previous criteria it will get tagged as BOT: Triage. Signaling the system to send the ticket to its sister Flow where we triage tickets out to individual team members. First, we must determine that this is a new case and is not coming from certain teams already approved. To do this we will use the condition action. Setting the state of the ticket to only run when equal to new cases. Further, we consider certain other teams who are excluded from this action using the or function.

When the parameters for the condition have been set we use the update work item in Azure DevOps for both the yes and no condition trees. Both are, once again, only going to change the tags on the ticket which will later trigger the team triage process.

If the conditions are not met then the Flow will follow the no path and tag the ticket Bot: NA, this signals to the system that the appropriate conditions were not met and to not move forward with the triaging to team members.

If the correct conditions are met it will mark the issue as Bot: Triage, which gives the go ahead to the system to send the ticket to the triage Flow and distribute to the appropriate team member.

This is the end of our initial Flow, to recap, a ticket has been checked for our five initial problems and has been tagged as such to alert the team member of the problem. Further, if a TFS issue has met all the necessary criteria it is marked “Bot: Triage” signaling to the system it is ready to be sent to a team member.

Queue Triage:

This will be a separate Flow in which we take what was done in the previous Flow and distribute TFS tickets to individual team members. As a brief overview, this is what the formatting will look like when done correctly. Below we will dig into what all of this is doing and walk through the process.

First, we need to set up our trigger, we are using a scheduled recurrence to run this Flow. Every five minutes it will run and look for updated tickets with the necessary tag from our previous section. Once it sees a TFS ticket with the tag it will move on with the Flow.

We then built individual queries within TFS for each member of the team and the categories they own. A new feature within Azure Devops called “get query results” allows us to check these queries quickly and as team members come and go be more flexible.

When you have built your query, use the “apply to each” condition and select value as the output. This will allow you to access all data fields in the TFS query we have built.

After we have identified the correct query, we will need to add a separate condition that ensures the issue was tagged by the pre-check Flow talked about earlier.

Once the update condition has been met, we once again need to use the “update work” item in Azure Devops. This will finally send the TFS ticket to the correct team member with the ticket checked for any of our known issues before being received.


Conclusion:

Overall, Flow has helped us cut down our own triage processing times from over 6 hours to 1-2 minutes and given us the flexibility to focus on the core business projects.

We know this post will help you think differently about more creative ways Flow can be used to reduce manual work, speed up your business, and solve redundant problems you run into on a daily basis.

If you have any suggestions or questions, feel free to comment on this post.

We’d love to hear your feedback!

Brian and George

 

 

 

 

The post Advanced | Flow of the Week: Triage and Team Assignment with Microsoft Flow appeared first on Microsoft Power Platform Blog.

]]>
Beginner | Flow of the Week: Generating Flows From Visio http://approjects.co.za/?big=en-us/power-platform/blog/power-automate/beginner-flow-of-the-week-generating-flows-from-visio/ Sat, 09 Feb 2019 18:33:20 +0000 This post comes from Microsoft Flow MVP Daniel Laskewitz. Daniel is a Business Productivity Consultant & Microsoft Business Solutions MVP who is very enthusiastic about all things Office 365, Microsoft Flow, PowerApps, Azure & SharePoint (Online). Since the preview, Daniel has been working with Microsoft Flow and later on with Microsoft PowerApps. That led to …

The post Beginner | Flow of the Week: Generating Flows From Visio appeared first on Microsoft Power Platform Blog.

]]>
This post comes from Microsoft Flow MVP Daniel Laskewitz. 
Daniel is a Business Productivity Consultant & Microsoft Business Solutions MVP who is very enthusiastic about all things Office 365, Microsoft Flow, PowerApps, Azure & SharePoint (Online).
Since the preview, Daniel has been working with Microsoft Flow and later on with Microsoft PowerApps. That led to him being awarded an MVP Award for Business Solutions. He loves to blog, present and evangelize about improving productivity in the modern workspace with these amazing tools!
Here is his post!
Many people have asked for this, and it’s finally in preview: the ability to generate Flows from Visio. After the Word Online Connector for Microsoft Flow and reusable components for PowerApps, In my opinion this is the next big announcement from the Microsoft Power Platform this year.
Let that sink in for a bit. The Power Platform is on a roll, and that’s something incredibly exciting!
Today, I’ll explain what you can expect from the ability to generate Flows from Visio. For the SharePoint-people: it’s not the same as it used to be with the SharePoint Workflows. It’s just a start.
 Let’s start with the inevitable: the licensing! If you want to use Microsoft Flow with Visio, you have to get the Visio Online Plan 2 license. So make sure to get that license if you want to play with this feature.
 From Visio build 11231+, which is available in the monthly channel (targeted), you have a group of new actions to your disposal.

 After opening Visio, make sure to select the Basic Flow BPMN Diagram template or if that’s not available like in the image below, search for it.

 At the moment of writing, there are four templates available:
– Basic Flow Diagram
– Microsoft Forms Feedback Analysis
– Manager Approval Process
– Purchase Order Workflow 

 Make sure to try out all the different templates to get a better view of how you can create some Flows from Visio. For this Flow of the Week select the Basic Flow Diagram, the right units (Metric or US) and click create.

Now we end up with an empty canvas where we can start building our diagram. Let’s start by adding the start event from the BPMN Basic Shapes at the left side of the screen. You can do this by dragging and dropping it onto the canvas. Double click on the start event and give it a name. I am naming my start event ‘When a file is added in SharePoint’. When you click next to the start event, the textbox closes, and the text you just entered is the label of the start event. 

Hover over the start event with your mouse, and you see 4 arrows, on the top, right, bottom and left side of the start event. These arrows help you to define the next step.  

If you hover over one of the arrows, you get options to add new parts to your diagram. For now, let’s select the top one – which is a task. A box appears, and you can drag and drop this to a convenient spot. Double click on the box and add a label. The label I am using is ‘Start an approval’ since that is the Flow action we add to this task later. Hover the task we just created, hover over the arrow on the right with your mouse and select the second symbol in the row, which is a gateway. Next, add two actions on two of the remaining two of the three sides of the gateway that is not used by a connector. Make sure to add the labels and make it look like the following image. 

Now we go back to the group of new actions. You can find the group of new actions in the Process tab. The first Microsoft Flow action that is available there is Prepare to Export.  

Select that action and two things happen: 
1. A sidebar appears where you can map the BPMN gateways to Flow Conditions and apply Microsoft Flow triggers or actions to different shapes in our BPMN Diagram
2. Icons appear next to the shapes of our BPMN Diagram to indicate that we can map these shapes to triggers or actions in Microsoft Flow. 

There are a couple of actions we need to do before we can export our BPMN Diagram to Microsoft Flow.  
– Click ‘if yes’ in the map condition part in the sidebar to make sure that the if yes part of the Flow condition gets mapped to the right part of our BPMN Diagram:  the approve path after the gateway
– Select the shapes in the BPMN Diagram one by one and make sure to map it to Flow triggers and actions via the triggers and actions tab in the sidebar 

Map the shapes to the following triggers/actions:
– Start event: SharePoint – When a file is created (properties only)
– Action (start an approval): Approvals – Start an approval
– Action (remove file): SharePoint – Delete file
– Action (send email): Office 365 Outlook – Send an Email (V2)
If you mapped the shapes correctly, your BPMN Diagram looks like this: 

Select the Flow Mapping tab in the sidebar, click the refresh button on the top, and you can see there are no issues to resolve. 

Click the Export button and make sure to log into the account you want to use to export your Flow. Fill in a creative name for your Flow and click ‘Create flow’ to create the flow in your environment.

Head over to Microsoft Flow in your browser and go to the My Flows section. Edit the Flow and make sure to fill in all the properties correctly. Save the Flow and your Flow will start working. 

This was a quick tour of the Visio features that are now in Public Preview. I hope this will make it easier for you to get started.
If not, the Visio team prepared some great content. Enjoy the new features!

The post Beginner | Flow of the Week: Generating Flows From Visio appeared first on Microsoft Power Platform Blog.

]]>
Advanced | Flow of The Week: Role Based Security in PowerApps using Flow & SharePoint Groups http://approjects.co.za/?big=en-us/power-platform/blog/power-automate/advanced-flow-of-the-week-role-based-security-in-powerapps-using-flow-sharepoint-groups/ Wed, 30 Jan 2019 16:00:00 +0000 Enabling role based security in PowerApps controlled by SharePoint Security Groups has been a common customer ask. For example, can you make an Admin screen that is visible only to users who belong to a specific SharePoint Security Group? Yes, you can and this is where Microsoft Flow comes to the rescue!
This blog post is an attempt to share an approach for finding out the SharePoint Group membership of a signed in user and make certain features or screens of an app available to them.

The post Advanced | Flow of The Week: Role Based Security in PowerApps using Flow & SharePoint Groups appeared first on Microsoft Power Platform Blog.

]]>
What’s up Flow Fans!?

Our FOTW This week comes from Geetha Sivasailam.

Geetha is a Collaboration & Custom App Dev consultant with Artis Consulting (http://www.artisconsulting.com/ ) a Microsoft Partner, delivering business solutions leveraging O365, Microsoft Business Applications, Custom App Dev implementations and various emerging technologies.  She is a Power Platform enthusiast and is passionate about enabling others to expand their possibilities and act more effectively with emerging tools, trends and technologies. Follow her on twitter (https://twitter.com/GSiVed ) or on her Blog

With no further adieu, here is her post!

Enabling role based security in PowerApps controlled by SharePoint Security Groups has been a common customer ask. For example, can you make an Admin screen that is visible only to users who belong to a specific SharePoint Security Group? Yes, you can and this is where Microsoft Flow comes to the rescue!
This blog post is an attempt to share an approach for finding out the SharePoint Group membership of a signed in user and make certain features or screens of an app available to them.
Prerequisites
Create a SharePoint security group with members that you would want to use for role based security in your PowerApps App and navigate to the group settings .


And enable “Everyone” access to view the members of this group

We will be creating a Flow to check group membership using a SharePoint HTTP REST call. Users triggering the Flow from your app may not necessarily have admin privileges to read group membership details. To enable all users to read group membership it is necessary to allow “Everyone” to view members of the security group.
Steps

  • Create a blank flow using a Site Collection Admin/Flow owner account.
  • Add a PowerApps Trigger step so you can call this Flow from the app. Then add an Initialize variable step to store a boolean value (IsAdministrator). Next add another Initialize variable step with a string variable (UserGroupInfo) to store the user group information we will be retrieving in the next step.

  • Search for ‘Send an HTTP request to SharePoint’ action under SharePoint actions and add it. Now let’s configure this action to make a SharePoint REST call to determine user group membership.

Site Address: Select the site collection where your SharePoint Security group exists
Method: Get
Uri: api/web/sitegroups/getByName(‘SP Group Name’)/Users?$filter=Email eq ‘’
Replace ‘SP Group Name’ with your group name. Place cursor in between the single quotes after $filter=Email eq and select ‘Ask In PowerApps’ under manual content. This will auto generate a variable name that will be used as an input parameter for this Flow. The goal here is to pass the logged in user’s email id as a parameter from PowerApps to Flow.
Below is how the action looks after configuration. ‘RequestAdmins’ is the SharePoint User Group I used for this example.

This REST call will return an empty object if the user is not member of the group.

It will return an object with User properties in the following format if the user is a member of the group.

  • Now that we have an output from the REST call above, we can parse it to extract the results section. Add a ‘Set Variable’ action to set the variable ‘UserGroupInfo’ created earlier with the value set to expression body(‘CheckUserGroup’)[‘d’][‘results’]


Here ‘CheckUserGroup’is the name of the previous action. If your action name has spaces, replace the spaces with underscore (_) character. At this stage, we have extracted the results which can be used to determine if the User is a member of the group.

  • Add a ‘Condition’ step to evaluate the results value. If the results object is empty then the user is not a member.

Use the expression @not(equals(variables(‘UserGroupInfo’), ‘[]’)) to evaluate the object.
‘UserGroupInfo’ is the variable used to store the object value and ‘[]’ compares to an empty object.
Set the variable ‘IsAdministrator’ that was initialized earlier to true if the condition evaluated to be true. If not, set it to be false.

  • One final step in the flow would be to pass the results of our user group membership check back to PowerApps as an output parameter that can be used to enable certain features of the app for the logged in user. Add ‘Respond to PowerApps’ action and choose a text output. An output of type boolean would have been ideal but is not available at this time and we’ll stick to a text output. Provide a name for the text output parameter (I used ‘IsAdminUser’) and set the value to variable ‘IsAdministrator’.


Here’s how entire Flow looks like and it’s time to save it and see it in action.

  • Now that we have Flow ready, let’s implement and test it on the app. Navigate to your PowerApps app, create a new blank screen, click on Properties dropdown and select the ‘OnVisible’ event of the screen. Next click on the ‘Action’ tab and select ‘Flows’. Select the Flow you created to add it to the formula bar to associate the Flow to the ‘OnVisible’ event of the screen. Type the below functions on the ‘OnVisible’ formula bar.


First we are creating a variable (isAdmin) to store the user group membership status in Boolean format and setting the default value to be false. Next we are triggering the Flow ( ‘CheckUserPermission’ is the name of the Flow I created) and passing in an encoded format of the current logged in user’s email as the input parameter.
The output returned from Flow is being stored in a variable ‘UserGroupInfo’. Lastly, we are validating the value of the output parameter ‘isadminuser’ we configured earlier and setting the ‘isAdmin’ variable with Boolean equivalent.

  • Drop a button on the screen and set the “Visible’ property of the button to variable ‘isAdmin’. This will show/hide the button based on the value of the variable. You can set the ‘OnSelect’ event of the button to navigate to an Admin Only Screen.

And we are done! Publish the app and run. If all goes well, you should see that the flow ran successfully.
On the app side, Flow is triggered (when the screen is visible) with the current user’s encoded email id as the input parameter which in turns makes a SharePoint Rest Call to determine the user’s membership.It returns a Text output of value “True” or “False”. The app then validates the returned value and shows/hides the button based on the user’s group membership.
Here’s how my sample app looks like if the current user is an admin:

If the current user is not an admin then the admin button is hidden.

Resources
Here are some resources I found to be very useful to help design this solution:

  • Doctor Flow’s post how you can use SharePoint REST APIs in Flow
  • For those interested in the SharePoint REST/OData API, you can find the complete set of REST/OData APIs here.

 

The post Advanced | Flow of The Week: Role Based Security in PowerApps using Flow & SharePoint Groups appeared first on Microsoft Power Platform Blog.

]]>
Advanced | Flow of the Week: Sending Pull Request review reminders using MS Flows http://approjects.co.za/?big=en-us/power-platform/blog/power-automate/sending-pull-request-review-reminders-using-ms-flows/ Wed, 12 Sep 2018 14:06:44 +0000 Hey Flow Fans! Have you wanted to send automated PR Reminders out to your team? Look no further and follow along as Jyoti, one of the Microsoft Flow Engineers guides you through creating the Flow!

The post Advanced | Flow of the Week: Sending Pull Request review reminders using MS Flows appeared first on Microsoft Power Platform Blog.

]]>
Hello Flow Fans!

With the increasing number of code repositories it was getting difficult to keep track of Pull Requests (PRs) that need to be reviewed. As an effort to improve dev productivity and reduce PR wait times we created a simple flow using the Visual Studio Team Services (VSTS) connector to consolidate all PR links and send reminders to reviewers. Now, having a single email in their inbox every week with PRs to be reviewed saves everyone the hassle of navigating to each repository.

Overview of the flow

  1. Trigger the flow through Recurrence
  2. Get the desired PRs using VSTS REST APIs
  3. Parse response JSON
  4. Iterate over reviewers list for each PR and prepare a dictionary of reviewer-PRs
  5. Send emails to the reviewers with the list of PRs they need to review

The Flow in this article, sends emails to a filtered list of users to not spam members from other teams. This can be enhanced to send emails to users in an alias (not in scope of this article).

 

First choose your Trigger

A recurrence trigger can be used as the aim is to send an email at regular intervals. /you can set yours up like mine, or choose a schedule of your own.

 

Now add an action to get Pull Requests from VSTS

The VSTS connector supports multiple actions; the one we used is called ‘Send an HTTP request to VSTS’. VSTS exposes hundreds of REST APIs https://docs.microsoft.com/en-us/rest/api/vsts/?view=vsts-rest-4.1 at our disposal. We will leverage the Pull Requests APIs here.

We use HTTP GET method to retrieve all active PRs where a particular reviewer was added. Account name is the Azure DevOps organization name (e.g. for jorg.visualstudio.com account name is jorg). Here, the query gets all the active pull requests where a particular reviewer has been added.

 

Next we will add an action to Parse the JSON

The output is then parsed using the ‘Parse JSON’ connector. You can use a sample payload to generate schema as the response json structure could be complicated.

 

Iterate over PRs

After which we iterate over all the PRs and reviewers to prepare a dictionary of Users and PRs.

 

Iterate over reviewers for each PR

At this step, the reviewer list for each PR it iterated through and we prepare a Reviewer-PR map. E.g.

{
“reviewer1_alias”: [
“<tr>\n<td>PR Title 1 </td>\n<td>requester1</td>\n<td > Pending review</td>\n <td> https://url1\n</td>\n</tr>
],
“reviewer2_alias”: [
“<tr>\n<td>PR Title 2 </td>\n<td>requester2</td>\n<td > Waiting for author</td>\n <td> https://url2\n</td>\n</tr> “,
“<tr>\n<td>PR Title 3 </td>\n<td>requester2</td>\n<td > Pending review</td>\n <td> https://url3\n</td>\n</tr>
]
}


 

 

 

 

 

 

 

 

 

 

An extension here could be to check if the comments from the reviewer have been resolved or not.

 

Send email

To each of the above reviewers in the dictionary, we can use the  ‘Send an email’ action with the outlook connector and pass in our parsed items. The email looks as follows.

Thanks for reading! Hope this helps improve dev productivity in your team as well. Please leave comments for any improvements or enhancements or questions you may have!

 

The post Advanced | Flow of the Week: Sending Pull Request review reminders using MS Flows appeared first on Microsoft Power Platform Blog.

]]>
Advanced | Flow of The Week: Retrieving Office 365 Message Center and Service Health Notices using Microsoft Flow http://approjects.co.za/?big=en-us/power-platform/blog/power-automate/get-office365-health-notices-using-microsoft-flow/ Wed, 05 Sep 2018 12:02:11 +0000 To automate critical business processes in Office 365 using Microsoft Flow, we typically need to call cloud-based services in order to retrieve data. Calling these services often requires us to use the HTTP connector and action, and as a result, provide our TenantID, along with an App’s ClientID and SecretID in the Flow. This blog post will provide a detailed walkthrough of configuring these required parameters when calling cloud services using the HTTP connector. We’ll use a recently released Flow template as an example, which retrieves data from the Office 365 Message Center and Service Health dashboards.

The post Advanced | Flow of The Week: Retrieving Office 365 Message Center and Service Health Notices using Microsoft Flow appeared first on Microsoft Power Platform Blog.

]]>
Hello Flow Fans!

This weeks post comes from Antonio Maio from Protiviti, inc.

Antonio Maio is an enterprise architect with over 20 years of experience in enterprise application architecture, information security, cybersecurity practices and systems, software development and team leadership. Antonio is an Associate Director and Senior Enterprise Architect with Protiviti. Based in Canada, he has been awarded a Microsoft Most Valuable Professional (MVP) award for 7 consecutive years, from 2012 to 2018, specializing in Microsoft SharePoint Server, Office 365 and Office Services. His background includes implementing large scale SharePoint and Office 365 environments, information security technologies, and information governance best practices. His experience with Microsoft SharePoint and Office 365 extends over the last 12 years. Be sure to Follow him on Twitter and check out his blog www.trustsharepoint.com 

To automate critical business processes in Office 365 using Microsoft Flow, we typically need to call cloud-based services in order to retrieve data.  Calling these services often requires us to use the HTTP connector and action, and as a result, provide our TenantID, along with an App’s ClientID and SecretID in the Flow.  This blog post will provide a detailed walkthrough of configuring these required parameters when calling cloud services using the HTTP connector.  We’ll use a recently released Flow template as an example, which retrieves data from the Office 365 Message Center and Service Health dashboards.

Using the Office 365 Message Center

A common recommended strategy for managing and maintaining an enterprise-class Office 365 environment is to designate a “service owner” for your corporate Office 365 tenant.  The service owner’s role usually includes staying up to date with changes and new capabilities that are coming to Office 365, and being proactive about determining the best way to roll out those changes to the organization’s user community.  One of the best tools available to help service owners stay up to date with Office 365 features and changes is the Office 365 Message Center.  The Office 365 Message Center is a dashboard available in the Office 365 Admin Center (Health > Message Center) which hosts messages from Microsoft about new features, planned changes to features or service issues within the Office 365 environment.

There are several ways to stay up to date with messages posted to the Message Center.  For example, the Message Center allows you to get push notifications from the Office 365 Admin App, or in the Message Center you can select to have a weekly email with posted announcements sent to up to 2 users or to a group.

A great way to have Office 365 Message Center announcements sent directly to your inbox, in a weekly summary format, and to even customize the list that’s sent, is to use Microsoft Flow.  The Microsoft Flow team has recently released a new Flow template called “Email me a weekly summary of Office 365 Message Center notices” that gets you started.  Although this template works very similarly to the built in Message Center feature of sending a weekly digest email, using Flow has the advantage of allowing you to customize the weekly email to either send it to more than 2 people (without using a Group) or to highlighting updates or service outages related to only specific services you might be interested in.  For example, you could send emails that alert your Exchange team to Exchange Online specific updates, or your SharePoint team to SharePoint Online specific updates, and so on.  You could even automatically register service outages with your internal governance and security tools for alerting and auditing purposes.

 

This template will actually send a weekly summary email containing all Office 365 Message Center notices and all Service Health issues posted in the last week to your Office 365 tenant.

It relies on two connectors (Office 365 Outlook and Office 365 Users) and calls to the Office 365 Service Communications API.  So once those two connections are established, the template is actually fairly easy to setup and use.  It does however require the user to fill out three parameters that might be confusing to some, so we’ll walk through how those parameters are configured here so that you can quickly get up and running with this Flow template.

When you first create the template, it looks like this:

Notice, here are those three variables right out the gate that you need to provide: TenantID, ClientID, and SecretID. 

Provide the TenantID

First you need to provide your Office 365 TenantID.  This is not your tenant name or your domain.  This is a globally unique identifier (GUID) that uniquely identifies your Office 365 tenant.  There’s 2 ways to retrieve your Office 365 tenant ID:

  1. From the Azure Active Directory Admin Console
  • Log into the Office 365 Admin Center as a Global Administrator, click Admin Centers in the left-hand menu, and click Azure Active Directory; alternatively, you could log into http://portal.azure.com with your Office 365 global admin credentials.
  • In the Azure Administration Console, click Azure Active Directory, and under Manage click Properties
  • Find the value listed in the Directory ID field and that’s your TenantID.

  1. Using PowerShell
  • Launch Windows PowerShell as Administrator
  • Install Azure PowerShell Module by running the following cmdlet at the prompt:

Install-Module -Name AzureRM

  • Now run the following cmdlet at the prompt:

Login-AzureRmAccount

  • You will be asked to login to your Office 365 global administrator account, and then the TenantID will be displayed in the output to the PowerShell window.

Once you have your TenantID, enter it in the first variable card presented in the Flow, titled “Initialize TenantID variable”.

 

Provide your ClientID and SecretID

In order to provide a ClientID and SecretID, you’ll need to first register an App in the Azure Active Directory:

  • Log into the Office 365 Admin Center as a Global Administrator, click Admin Centers in the left-hand menu, and click Azure Active Directory; alternatively, you could log into http://portal.azure.com with your Office 365 global admin credentials.
  • In the Azure Administration Console, click Azure Active Directory, and under Manage click App Registrations
  • Click the +New Application Registration button
  • Enter any name for your App such as Office365ServiceCommunicationsAPI (must be a minimum of 4 characters)
  • Select Web App / API for the Application Type since this is a web application
  • Enter an arbitrary URL made up from your application name, such as http://Office365ServiceCommunicationsAPI
  • Click Create at the bottom of the panel

 

Once the App has been created, several IDs will be shown for your App.  The Application ID represents the ClientID we need.  Copy and save that value to use in our Flow.

Click the Settings button on this page, and then click the Keys menu item.

In the Passwords screen, enter any name for your key (maximum 16 characters) and select a Duration, after which it will expire (I typically select 1 or 2 years).  Then click Save.

Once saved, the key (or SecretID in our case) will be displayed in the value field. 

 

Note: The Azure portal will only display the Key value, or the SecretID, at the time when it is initially generated.  You cannot navigate back to this page and retrieve the SecretID again later.

Copy and save that value to use in our Flow. Be sure to keep your ClientID and SecretID saved privately and securely. 

Grant Required Permissions to Your App

Once you have created the App and saved the ClientID and SecretID, we need to grant permissions to our app so that our Flow can access the Service Communications API.  We do this in the Azure portal using the following steps:

  • In the Settings page for your App, click Required Permissions

  • In the Required Permissions page, click +Add then click 1 Select an API
  • Select Office 365 Management APIs and click Select
  • Click 2 Select Permissions and then select all Application Permissions and Delegated Permissions
  • Click Save

All of the permissions for the Office 365 Management APIs require an administrator to explicitly grant these permissions to the App.  This is done by entering a carefully constructed URL in the browser, logging in as an Office 365 global administrator and clicking Accept to grant the selected permissions to the App.

  • Enter the following URL into a new browser window:

https://login.windows.net/common/oauth2/authorize?response_type=code&resource=https%3A%2F%2Fmanage.office.com&client_id={ClientID}&redirect_uri={ReplyURL}

Note: the {ClientID} in the URL and the {ReplyURL} values in the URL must be replaced with the values configured in your App.

For example, your URL might look like this:

  • Login with the Office 365 global administrator credentials
  • Click Accept on the following screen which appears to grant the permissions listed to your App:

Complete and Run our Flow

Now that we have the ClientID and SecretID from our newly created app, and we’ve created required permissions to the App, let’s:

  • Copy the ClientID value into the Flow tile titled “Initialize ClientID variable”
  • Copy the SecretID value into the Flow tile titled “Initialize SecretID variable”

The template will then call Get Access Token to retrieve a bearer token, which will be used in a subsequent call to the services communication endpoint.

The template will then parse the token, and ultimately call a GET method in the Office 365 Service Communications API endpoint within the ‘Get Office 365 messages tile’. 

This is done using the HTTP connector and action, and the TenantID, ClientID, SecretID and permissions we configured were required in order to enable the Flow to securely make that call.  Calling cloud service endpoints typically follow a similar pattern to the process shown in this post.

Once those 3 values are provided, you can save your Flow and its ready to run and test!  All other parameters are set with appropriate defaults so that you can immediately receive an HTML formatted email with a digest of the recently issued Office 365 Message Center and Service Health notices. You can use the Flow as is, or make further modifications to it like filtering the output for specific services of interest, directing multiple emails to various service owners throughout your organization, or automatically raising alerts through internal security and governance tools when service health issues may affect critical business processes.  These types of Flows can help your Office 365 service owner or your internal security and governance teams to stay up to date with what’s new and what’s going on now in Office 365!

Thanks for reading! Please leave your comments below!

The post Advanced | Flow of The Week: Retrieving Office 365 Message Center and Service Health Notices using Microsoft Flow appeared first on Microsoft Power Platform Blog.

]]>
Advanced | Flow of The Week – Integrate Facebook Workplace with your SharePoint Intranet http://approjects.co.za/?big=en-us/power-platform/blog/power-automate/connect-facebook-workplace-to-sharepoint/ Fri, 20 Jul 2018 11:30:24 +0000 In this entry of the Flow of the Week - Community Member Tomasz Poszytek builds a Flow that connects Facebook Workplace to a SharePoint intranet site!
Come and find out how he did this and how you can build it too!

The post Advanced | Flow of The Week – Integrate Facebook Workplace with your SharePoint Intranet appeared first on Microsoft Power Platform Blog.

]]>
Facebook @workplace integration with SharePoint using Microsoft Flow

Hello Flow Fans! 

This weeks Flow of The Week comes from Tomasz Poszytek – Originaly posted on his Blog and re-posted with permission

This post will show how to connect your SharePoint intranet with a @workplace by Facebook community area dedicated for enterprises. The aim of the flow is to automatically gather and store every new post, comment and other sort of activities that can occur on a @workplace side in a dedicated list within SharePoint site.

Because there is yet no ootb solution to show @workplace activity feed, this approach will let you to have your data inside SharePoint and then to show it to your users using a built-in list web part or by creating a custom display web part. Choice is yours! Let’s begin.

 

Setting up @workplace and Flow

 

Step no 1 – create custom integration in @workplace

The integration is done via a webhook configured on a @workplace side. To be able to use the webhook, first it needs to be defined. To do that you need to go to “Integrations” page (being a @workplace administrator): https://[your-company].facebook.com/work/admin/?section=apps&ref=bookmarks and then to create new custom integration:

Then you need to define its name and optionally a description:

Now you need to select what permissions does the integration need (in my case this is only “Read group content”), then select groups, to which it will have access (in my cases this is “All groups”)

and finally configure the webhooks.

Remember, that you can only subscribe one URL per webhook topic, but you may use the same URL for multiple topics.

In my case I only configured webhooks for the “Groups”. How? Read below.

 

Step 2 – webhook configuration and verification

 

To configure and save a webhook it must have verified connection with the callback URL. The callback URL is in fact a URL of the Microsoft Flow, which is going to receive and parse data.

The tricky thing is, that the callback verification must be done using GET request, whereas further webhooks’ requests are done using POST calls.

To do that simply create a Flow with a “Request” action as the trigger.

Then parse the header parameters, using the “Parse JSON” action:

  1. Content: triggerOutputs()[‘queries’]
  2. Schema:
    { “type”: “object”, “properties”: { “hub.mode”: { “type”: “string” }, “hub.challenge”: { “type”: “string” }, “hub.verify_token”: { “type”: “string” } } }

Finally add the “Response” action, and use “hub.challenge” value as a Body:

Do not forget, to change how the Flow can be triggered – set the method to “GET” (1) in trigger action (it’s under the “advanced options”), publish your workflow and finally copy its URL (2):

Now paste that copied URL in a “Callback URL” field in webhook configuration and type any “Verify Token” value (it should be used to check, if the GET request really comes from your webhook) and hit “Save”:

Now you’re ready to go – you will notice in your Flow a new run, completed successfully and your new “Custom integration” will be saved. 

Whenever you decide to change ANYTHING in your Custom Integration configuration, you will need to verify Callback URL again – so again to send a GET request to your Flow.

Data structure

For saving comments I am using a single SharePoint list built from the following columns:

  1. Title – holds type of the information.
  2. Author – a text column to keep name and last name of an author.
  3. Date – when the event occurred (from webhook).
  4. Post/ Comment – a multiline text field, allowing HTML formatting, to keep body of the message.
  5. Image – again, a multiline text field, allowing HTML formatting, to store <img> tag with the URL of the image, attached to a message – this is because Flow does not support “Picture/ Hyperlink” fields having set type to “Picture”.
  6. SourceURL – a “Picture/ Hyperlink” field with a type set to “Hyperlink”.
  7. AuthorPPL – again, an author field, but this time as a “Person or group” field. My Flow is trying to map Author data to an existing SP User.
  8. ItemId – an identifier of the message: comment_id, post_id or a member_id.

The list, filled up with data, looks as below:

Building a Flow

Remember to keep the actions for GET response within your workflow. I did it by adding a condition action, with a condition: “1 is equal to 2”, so that Flow always goes the other way. I am changing its behavior manually, between receiving GET and POST requests, which is impossible to automate right now:

Whenever I modify my @workplace Custom integration settings, I change the method to “GET” and the condition to “1 is equal 1”. After verification passes, I am turning them back to “POST” and “1 is equal to 2”. Some kind of a lifehack ?

Step 1 – Request body schema

In my “POST” branch, the first action is “Parse JSON”, used to parse the request body. Before I made a valid schema, I did dozens of calls from @workplace to Flow, to see how specific actions are represented in JSON. I have named the following scenarios:

  1. Membership – when a new user joins a group
  2. Comment – when a new comment is created
  3. Post – when a new post is written
    1. Post with a single photo
    2. Post with multiple photos
    3. Post without photo (a status)
    4. Event
    5. all others

In the end the schema looks like below (it contains properties for all scenarios, set to not be mandatory):

{

    “type”: “object”,

    “properties”: {

        “entry”: {

            “type”: “array”,

            “items”: {

                “type”: “object”,

                “properties”: {

                    “changes”: {

                        “type”: “array”,

                        “items”: {

                            “type”: “object”,

                            “properties”: {

                                “field”: {

                                    “type”: “string”

                                },

                                “value”: {

                                    “type”: “object”,

                                    “properties”: {

                                        “from”: {

                                            “type”: “object”,

                                            “properties”: {

                                                “id”: {

                                                    “type”: “string”

                                                },

                                                “name”: {

                                                    “type”: “string”

                                                }

                                            }

                                        },

                                        “member”: {

                                            “type”: “object”,

                                            “properties”: {

                                                “id”: {

                                                    “type”: “string”

                                                },

                                                “name”: {

                                                    “type”: “string”

                                                }

                                            }

                                        },

                                        “update_time”: {

                                            “type”: “string”

                                        },

                                        “verb”: {

                                            “type”: “string”

                                        },

                                        “community”: {

                                            “type”: “object”,

                                            “properties”: {

                                                “id”: {

                                                    “type”: “string”

                                                }

                                            }

                                        },

                                        “actor”: {

                                            “type”: “object”,

                                            “properties”: {

                                                “id”: {

                                                    “type”: “string”

                                                },

                                                “name”: {

                                                    “type”: “string”

                                                }

                                            }

                                        },

                                        “attachments”: {

                                            “type”: “object”,

                                            “properties”: {

                                                “data”: {

                                                    “type”: “array”,

                                                    “items”: {

                                                        “type”: “object”,

                                                        “properties”: {

                                                            “url”: {

                                                                “type”: “string”

                                                            },

                                                            “subattachments”: {

                                                                “type”: “object”,

                                                                “properties”: {

                                                                    “data”: {

                                                                        “type”: “array”,

                                                                        “items”: {

                                                                            “type”: “object”,

                                                                            “properties”: {

                                                                                “url”: {

                                                                                    “type”: “string”

                                                                                },

                                                                                “media”: {

                                                                                    “type”: “object”,

                                                                                    “properties”: {

                                                                                        “image”: {

                                                                                            “type”: “object”,

                                                                                            “properties”: {

                                                                                                “src”: {

                                                                                                    “type”: “string”

                                                                                                },

                                                                                                “width”: {

                                                                                                    “type”: “number”

                                                                                                },

                                                                                                “height”: {

                                                                                                    “type”: “number”

                                                                                                }

                                                                                            }

                                                                                        }

                                                                                    }

                                                                                },

                                                                                “type”: {

                                                                                    “type”: “string”

                                                                                },

                                                                                “target”: {

                                                                                    “type”: “object”,

                                                                                    “properties”: {

                                                                                        “url”: {

                                                                                            “type”: “string”

                                                                                        },

                                                                                        “id”: {

                                                                                            “type”: “string”

                                                                                        }

                                                                                    }

                                                                                },

                                                                                “title”: {

                                                                                    “type”: “string”

                                                                                }

                                                                            }

                                                                        }

                                                                    }

                                                                }

                                                            },

                                                            “media”: {

                                                                “type”: “object”,

                                                                “properties”: {

                                                                    “image”: {

                                                                        “type”: “object”,

                                                                        “properties”: {

                                                                            “src”: {

                                                                                “type”: “string”

                                                                            },

                                                                            “width”: {

                                                                                “type”: “number”

                                                                            },

                                                                            “height”: {

                                                                                “type”: “number”

                                                                            }

                                                                        }

                                                                    }

                                                                }

                                                            },

                                                            “type”: {

                                                                “type”: “string”

                                                            },

                                                            “description”: {

                                                                “type”: “string”

                                                            },

                                                            “target”: {

                                                                “type”: “object”,

                                                                “properties”: {

                                                                    “url”: {

                                                                        “type”: “string”

                                                                    },

                                                                    “id”: {

                                                                        “type”: “string”

                                                                    }

                                                                }

                                                            },

                                                            “title”: {

                                                                “type”: “string”

                                                            }

                                                        }

                                                    }

                                                }

                                            }

                                        },

                                        “type”: {

                                            “type”: “string”

                                        },

                                        “target_type”: {

                                            “type”: “string”

                                        },

                                        “comment_id”: {

                                            “type”: “string”

                                        },

                                        “post_id”: {

                                            “type”: “string”

                                        },

                                        “created_time”: {

                                            “type”: “string”

                                        },

                                        “message”: {

                                            “type”: “string”

                                        },

                                        “permalink_url”: {

                                            “type”: “string”

                                        }

                                    }

                                }

                            }

                        }

                    },

                    “id”: {

                        “type”: “string”

                    },

                    “time”: {

                        “type”: “number”

                    }

                },

                “required”: [

                    “changes”,

                    “id”,

                    “time”

                ]

            }

        },

        “object”: {

            “type”: “string”

        }

    }

}

 

Step 2 – setting up actions

After parsing request body using the schema, Flow must do the following steps:

  1. Get operation field – whether post is a “Comment”, “Membership” or “Posts”
    I do it using the “Compose” action and the following expressions:
    body(‘Parse_request_body’)?[‘entry’]?[0]?[‘changes’]?[0]?[‘field’]
     
  2. Switch branches based on the operation type:

  1. For each type I am getting a proper ID (ex. comment_id for “Comments” or post_id for “Posts”)
  2. Then it must query SharePoint to check, whether there is already a record with that ID. If there is, then obviously workflow ends its execution:

  1. If this is a “Post” type, then I am looking an internal operation type property using the following expression:
    body(‘Parse_request_body’)?[‘entry’]?[0]?[‘changes’]?[0]?[‘field’]

  1. Based on the outcome, Flow switches between:
    1. Photo
    2. Status
    3. Event
    4. and other requests (haven’t seen anything “other” yet)
       
  2. Then for “Photo” type it also checks, whether there is only one or multiple photos (gallery) checking, or if the type is “album” by evaluating the below expression:
    body(‘Parse_request_body’)?[‘entry’]?[0]?[‘changes’]?[0]?[‘value’][‘attachments’][‘data’]?[0]?[‘type’]
     
  3. Finally, for each message type it is also trying to match user with an existing one, by using action “Office 365 Get user profile (V2)” and concatenating users first and last name together with company’s domain as a UPN:
    concat(trim(replace(trim(body(‘Parse_request_body’)?[‘entry’]?[0]?[‘changes’]?[0]?[‘value’][‘from’][‘name’]), ‘ ‘, ‘.’)), ‘@the-company.com’)
     
  4. Obviously, if user is not found, the action triggers error, so for that case the next action, which is “Create list item” has configured “run after” settings also to “has failed”, so that no matter what happens, Flow won’t fail for that reason:

  1. In the end Flow is creating new item on a list, combining all information together:

Structure of Flow’s actions, on a medium level of details, looks as below for the described solution:

Icons (i) visible next to arrows mark relations, in which the next action is executed even if the previous one ends up with failure.

Structure of a single block, used to save data from @workplace into a SharePoint list, looks as on the example below (it shows saving data for a new post):

Things to remember

During that project I learnt the following things. Please, keep them in mind when trying to follow my steps:

  1. @workplace will send GET request to FLOW every time a “Custom integration” is modified and saved.
  2. @workplace will be sending requests for a single event as long as it won’t receive a “200 OK” response – be prepared to verify if the content has already been added.
  3. @workplace is not always waiting for the response. I see dozens of failed flows just because
  4. @workplace abandoned waiting for the response. I have no idea why, it seems to be really random. Anyway – in case it fails waiting, it will try to send the same data again and again until receiving “200 OK”. Only the frequency will be lower and after couple of tries it will stop.
  5. Using the “run after” configuration in Flow’s actions can be really useful – both for overcoming missing information or actions which can end up with errors which we don’t really care about, as well as doing conditional blocks. In my Flow I was using this configuration very often.

Thanks for reaching this sentence. I hope you find it useful. Don’t hesitate to contact me in case you have any questions or leave your comment below!

 

The post Advanced | Flow of The Week – Integrate Facebook Workplace with your SharePoint Intranet appeared first on Microsoft Power Platform Blog.

]]>
Advanced | Flow of The Week: Creating Your Own Workplace Democracy With The Power of Approvals! http://approjects.co.za/?big=en-us/power-platform/blog/power-automate/approvals-by-majority/ Thu, 12 Jul 2018 13:59:48 +0000 For this Flow of the Week learn from one of the Microsoft Flow Software engineers, Taylor Cambre as he teaches you how to do APPROVALS BY MAJORITY which is not a native feature in Flow but something that is OFTEN asked for!
Come and check out his technique, learn a new skill and leave him a comment or question!

The post Advanced | Flow of The Week: Creating Your Own Workplace Democracy With The Power of Approvals! appeared first on Microsoft Power Platform Blog.

]]>
Sometimes it gets difficult to make decisions in the work place. Whether it be important documents that need review or even more essential rulings like deciding a time to get that sweet Starbucks, Flow has your back with Approvals. Right now, you can do a lot with our two current types of Approvals:

  1. Anyone from the assigned list can approve.
  2. All from the assigned list must approve.

But what if that’s not enough? I mean with “anyone can approve” you don’t want to give anyone all that power. On the other hand, with “all must approve”, you’re having flashbacks about last week when everyone wanted sushi except Jeff and he had to ruin it with a reject on your well-crafted approval. We demand democracy!

Or… maybe you just want to take your group decision making to the next level?

We’ve had lots of customers interested in more complex types of approvals such a quorums and multi-stage approvals. I assure you it’s on our minds too! Eventually we’ll have simpler built in approval types, but until then I’ll show you a way you can create your own little checks and balances system for your new team agreement accords.

I know it looks like a lot but really, it consists of two main approval steps to mimic a multi-stage approval:

Introducing: The Executive Approval. Pretty fancy sounding… because it is. At least, that’s what your local representative would say.

  1. the first stage is a majority vote approval assigned to many people (like congress).
  2. the second stage is a regular approval assigned to one person which can override the result of the first stage of the approval (like a veto).

Q: So how do we accomplish this?

A: The magic of bureaucracy of course Step by step.

Triggered

Now to the real stuff.

You can start out with any trigger you want, typically something involving an item or file works well for approvals.

Stage 1: Let’s get congress to agree on something

Since a “majority must approve” approval doesn’t exist we are going to create our own using a technique that can be modified to do all kinds of approvals.

The basic idea behind this is that we have our list of approvers that we want to send this “majority must approve” approval to, but instead of sending one approval assigned to everyone, we can break it up and assign each person a single approval in parallel, collect all the responses and then decide what to make of them.

Bonus: If you would like to know how to get a dynamic list of approvers for something like a SharePoint item check out this earlier flow of the week about sending parallel approval requests for a dynamic set of approvers.

For the sake of this tutorial I just initialized an array with a list of emails to assign as the approvers.

Next, we need a way to keep track of our responses. I found the easiest way to keep track of the responses by using two separate arrays:

  1. A list of “Approve” responses
  2. A list of “Reject” responses

The reasons why this approach is great is because we can use:

  1. union in an expression to combine the two lists into one
  2. length in an expression to get the count of responses for each list

Now that we have our approvers and can keep track of responses we can add a “Apply to each” on the list of approvers and create an approval and record the response in the proper list.

It’s very important not to forget to make your “Apple to each” execute in parallel by going to options and enabling “Concurrency control”.

Finally, to complete this approval stage now that we’ve recorded our responses, we can simply just compare the lengths of the array using expressions and a condition card:

So now to complete the Executive Approval we need our stage 2 approval if the result of the first stage ended up being a majority of approve.

Note: In the case of reject you could send an email notification listing out the results as a html table. (That’s what I did, this is where concat comes in handy with more variables)

Approval Stage 2: Electric Boogaloo

This approval is just a regular approval who is assigned to an Executive approver of your choosing. Someone who you can really depend on like Tom. Tom is really dependable…

You can just hook this approval up to another conditional and now the multi-stage approval is essentially done! Our Executive approver can now make decisions; Simple right? Well…

Q: How can a Flow certified public figure such as an Executive approver make a good decision without any context?

A: Magic We can pass the responses we recorded from Stage 1 into the details field of the Stage 2 approval. The details field for approval accepts markdown now so we can make the results look pretty.

Now we don’t just need to store whether someone approves or rejects the stage 1 approval, we also want to know who it was and their comments, which can be stored as JSON in the arrays. We can go back and edit our append variable actions to be something like:

In order to create a pretty markdown table using our newly stored information we have to add logic to convert the responses to markdown. First, we’ll initialize another variable to keep track of the converted markdown since we can have a dynamic number of responses:

(You can read up on approval details markdown capabilities here)

 
   

To finish the conversion, we can do a “Apply to each” on the union of our two response arrays to make a single one after we get all the responses. Inside the loop we can parse the JSON objects we added and use the values in a “Append to variable” action to convert the responses to markdown table rows to our variable like so:

Finally, we can just use the markdown table variable we created as part of the approval details in the Stage 2 approval. The markdown we added should look like this once the flow is working as intended:

That should finish out the Executive Approval! Everything else I added to my example flow is fluff such as adding a markdown list of all the approvers to each individual approval in stage 1. Now you are ready to impress all your coworkers with your consitutional rulings!

Bonus: Instead of initializing each variable in an individual action because they can quickly bloat the flow, you could create a single JSON object that represents the state to store every variable. You can then edit the properties of the object to update it.

I hope everyone enjoyed this and I’m interested to hear what other ideas people have building off of this! Leave a Comment Below!

The post Advanced | Flow of The Week: Creating Your Own Workplace Democracy With The Power of Approvals! appeared first on Microsoft Power Platform Blog.

]]>
We want to tell your story! http://approjects.co.za/?big=en-us/power-platform/blog/power-automate/share-your-story-with-the-flow-team/ Wed, 30 May 2018 15:15:54 +0000 The Microsoft Flow team wants to showcase your story!

Come and fill out our form and tell us YOUR Microsoft Flow story for a chance to be featured on the customers.microsoft.com page! We can't wait to share all of the cool things that you're doing!

The post We want to tell your story! appeared first on Microsoft Power Platform Blog.

]]>
What’s up Flow Fans!?

I want to reach out to all of you today, Flow of the week day, with something a bit different!

Instead of us showing you a Flow, why don’t YOU show us yours?!

What do I mean by that? I’m so glad you asked!

We on the Flow team want to help share your story of how your company has used Microsoft Flow to solve problems, automate common work, gain efficiency, and most importantly…work less while doing more!

So, the next logical question is, how do you participate?!

First, Fill out THIS FORM  << 

Next, Wait up to 3 weeks for our response.

Finally, anywhere from 3-10 stories will be selected to be turned into formal case studies. You will receive an email either way letting you know if you have been selected or not.

And that’s it! Just like that you can share your successes on the big stage of the Microsoft Flow blog, Social and the customers.microsoft.com page!

Cant wait to read all of your submissions!

If you have any questions, please contact me at Jolevesq@microsoft.com or contact your Community Manager Gabriel at v-gaholl@microsoft.com

Later, Flow Fans!

– Jon

The post We want to tell your story! appeared first on Microsoft Power Platform Blog.

]]>
Advanced | Flow of the Week: Send parallel approval requests to a dynamic set of approvers http://approjects.co.za/?big=en-us/power-platform/blog/power-automate/advanced-flow-of-the-week-send-parallel-approval-requests-to-a-dynamic-set-of-approvers/ Fri, 30 Mar 2018 12:59:36 +0000 In this advanced FOTW post, learn how to create dynamic parallel approval requests using the new concurrency control settings in for each loops and also get a flavor for other Flow capabilities like variables, expressions, and ODATA filter queries.

The post Advanced | Flow of the Week: Send parallel approval requests to a dynamic set of approvers appeared first on Microsoft Power Platform Blog.

]]>
Almost all business processes have some form or another of approvals. These approvals apply to things like requests for vacation, overtime, or travel plans or for documents like budgets, contracts, blog posts, or specifications. The business process itself may need a single approval, sequential approvals, an everyone must approve type approval, or parallel approvals.

We recently added the ability to make Apply to each loops run in parallel as opposed to in sequence. This capability allows you to set up a parallel approval where the list of approvers is dynamic and determined when the flow runs. In this advanced FOTW post, we’ll walk you through an example.

The scenario

Let’s imagine that you are a SharePoint administrator for the world’s greatest imaginary company, Contoso. At Contoso, you have a document library that hosts documents for each of your departments – Finance, Legal, and Marketing. Each department has its’ own folder.

You also have a SharePoint list (‘Department Approvers’) that has the approvers for each department. Notice how Approvers is a multi-value people field where Finance has 3 approvers, Legal has 2 approvers, and Marketing has a single approver.  

Now, you want to create a Flow such that for a selected document, based on the folder path of the document (e.g. Finance), you will send an approval request to each of the department’s approvers (e.g. Dan Holme, Patricia Hendricks, and Alyssa Danesh). As soon as approver reviews the document, you want to notify the requestor, with the approver’s comments.

Let’s look at the Flow in detail. You can download it from here.

The trigger

To allow your end-users to start the workflow manually whenever they want to seek approval on a given document and provide runtime inputs like a Message to approvers, use the For a selected item trigger.

When invoked in SharePoint, end-users can see details about the Flow and enter a message via the Flow launch panel. (Learn more about the Flow launch panel)

Identify the folder Name

The For a selected item trigger returns the ID of the selected item, any runtime inputs specified (such as Message to approvers), and information about the invoker (such as User email and the Timestamp at which the flow was invoked).

To get more details about the selected file, use the Get item action and pass it the ID of the selected file.

Once you have the selected file, you can identify the name of the folder with an expression like the below and set a string variable called folderName.  

first(skip(split(body(‘Get_item’)?[‘{Path}’],’/’),2))

Determine the approvers

Having established which folder the selected file is located in, find the relevant approvers for that folder/department. Call the Get items action on the Department Approvers list (labeled as Get approvers by department below) and use an ODATA filter query such as Title eq ‘[folderName]’ with Top Count of 1. Next, initialize an array variable called Approvers. This array will be populated with approver emails.  

 

Since the Get approvers by department action returns an array of values (albeit of size 1), you’ll need to add an apply to each loop and iterate over the array. For each item, first Get the item properties (Get department approvers). Then, create another apply to each loop to iterate over Approvers (recall that Approvers is a multi-value people field) and append it to the Approvers variable (using the Append to array variable action).

 

 

For each approver

Finally, iterate over the Approvers array with another Apply to each loop. This loop contains a Start an approval action and a condition that sends an approval or rejection notification based on whether the Response is “Approved” or “Rejected”. Note – you can reference the currently selected item (approver in this case) using Current item attribute.

Parallel approvals

In order to ensure that all of the approvers receive their request at the same time, the For each approver loop must run in parallel. Click on the ellipsis menu of the loop and choose Settings.

Now override the Default and bump the degree of parallelism to the maximum. Note – the text incorrectly states that for each loops execute in paralell by default. They run in sequence by default.

Recap

In this blog post, we showed you how to send out dynamic parallel approval requests using the new concurrency control settings in for each loops. We also got a flavor for other Flow capabilities like variables, expressions, and ODATA filter queries.

 

The post Advanced | Flow of the Week: Send parallel approval requests to a dynamic set of approvers appeared first on Microsoft Power Platform Blog.

]]>
Advanced | Flow of the Week: What interests my boss, fascinates me! http://approjects.co.za/?big=en-us/power-platform/blog/power-automate/flow-of-the-week-what-interests-my-boss-fascinates-me/ Thu, 01 Feb 2018 14:58:13 +0000 Wouldn’t it be great if there was a way for a cognitive engine to process your emails, pull out key phrases and then execute a search engine query and return the top 3 results? Well there is, and these steps can be orchestrated using Microsoft Flow which is the inspiration for this blog post.

The post Advanced | Flow of the Week: What interests my boss, fascinates me! appeared first on Microsoft Power Platform Blog.

]]>
Recently I spent some time at one of Microsoft Canada’s field offices and was talking with Mark Speaker, an Industry Solutions Executive in Calgary about Microsoft Flow use cases. Mark has many progressive ideas about how Flow can be used within the asset intensive industries (Oil & Gas, Mining, Utilities) that he focuses on but he also had some ideas about how he can leverage Flow for personal productivity. Being an Industry Solutions Executive requires Mark to be on top of many trends that impact his customers and the Canadian Microsoft subsidiary.

When I was chatting with Mark, he brought up Microsoft’s abilities in cognitive computing and felt there must be a way “to leverage this technology in order help him and customers scale.” One use case he identified was managing communication that he receives from his leader, Sarah Kennedy. There is an old saying, “What interests my boss fascinates me” and that is the inspiration for this blog post.

Naturally, Mark pays close attention to his leader’s email, but between customer meetings and traveling across the Canadian subsidiary, Mark wants to ensure he can stay on-top of the email that he receives. In the event, there are emails that require further research, Mark wants quick access to information without suffering from search engine fatigue. 

Wouldn’t it be great if there was a way for a cognitive engine to process your emails, pull out key phrases and then execute a search engine query and return the top 3 results? Well there is, and these steps can be orchestrated using Microsoft Flow. With this as our requirements, I set out to build such a flow.

There are a lot of steps in building this flow. In this blog post, I will focus on the high-level concepts, but you can download an exported version of this flow here.

Building the flow

  • We want to run this flow every day, so we will use the Recurrence trigger that will ensure to instantiate it each day.

  • The next step that we want to run is the Office 365 Outlook – Get emails action. This action will allow us to retrieve the last 10 emails. We can also provide a Search Query, much like we can in the Outlook client. This is where you can provide a from: parameter indicating the person whose emails you want to target.

  • To simplify our processing, we will create 3 variables that we can use to store information like the News articles returned by Bing, our Key Phrases returned from Cognitive Services and a variable that will allow us to count our Key Phrases result.

  • Next, we will loop through each of the emails that we have received.

  • Since most of the emails received these days tend to be in HTML format, we can use the Html to text action to perform a conversion as we don’t want to pass HTML markup to the Key Phrases Cognitive API.

  • We are now ready to send our cleansed email body to the Key Phrases API. Optionally, we can also provide a targeted Language.

Note: you can obtain a free trial API key for the Text Analytics API (which includes Key Phrases) here. Alternatively, you can also obtain an API key from the Azure Portal if you have an Azure Subscription.

  • As you can imagine, large emails may contain many key phrases and passing in a large number of phrases may result in an inaccurate search result. To mitigate this, we will cap our key phrases at 10 to have a more relevant result set. But, until our keyPhraseCount reaches 10, we will append these key phrases together which will make up our query for Bing.

  • There is an out of box Bing API connector, but for this scenario I have opted to use the HTTP action so I can control additional parameters including the cc query parameter which will localize the results. For example, if Mark is interested in more information about a carbon tax, it is important to return results in his locale as opposed to another jurisdiction which won’t have the same level of impact. We are also going to include a count parameter and assign a value of 3 to limit the result set to 3.

Note: The Bing Search API also requires an API Key. You can sign up for a free trial here.

  • Since we are not using the out of box Bing connector, we need to use the Parse JSON Response to have a typed message that we can use in downstream connectors. We also want to put a defensive check to see if there is a response. If there are no results from our web search, we want to prevent a failure from occurring. So when there are no results we will construct a “No-Results-Found” message and add it to our news array so that Mark knows there was no result for a specific email. If results are returned, we will iterate through them and append them to our news array.

  • We don’t want to include all of the data (attributes) from our Bing search results so we will use the Select Columns action to include only Subject, Name and URL.

  • Next, we want to use the Create HTML table action that will convert our array into an HTML table.

  • Lastly, we will use the Send an email action to send our digest our to our interested user. We can also include formatting by embedding CSS selectors.

Testing

To test this flow, I did what any flow user would do…automate it using Microsoft Flow! By clicking a button, I can send 10 different emails that represent the types of emails that a person expects to receive.

  • As an example, there is activity in the Western Canada recently about Shale Gas projects that would be of interest to both Sarah and Mark as they support this customer segment. Therefore, I have included an example of such a scenario. For American Football fans – I have you covered too!

  • To run our test harness, we simply click on the …More dropdown and then select Run now. Alternatively, we can also pull out our mobile device and open the Microsoft Flow mobile app and click our virtual button.

  • Within a few seconds, we will see our 10 emails show up in our inbox.

  • With our emails staged, we are now ready to launch our actual “What interests my boss fascinates me” flow. We can either wait for our schedule to be reached or can manually kick it off as well.

If we explore the run details of the flow we will discover a few interesting items:

  • For our quantum computing email, the Text Analytics API was able to detect the following as Key Phrases:

  • When we call Bing, we assemble a query string that resembles a useful query string.

  • Bing, in turn, will provide valid results.

  • The complete output by Microsoft Flow looks like the following:

Other Opportunities

I hope this blog post gave you some ideas about how you can leverage Microsoft Flow and Azure Cognitive Services to scale yourself, and your team. Here are some additional ideas that we came up with that may also be of interest:

1. “Keep me updated on my Interests” (without me explicitly telling you my Interests) 

2. Of all of the news being released today, what would most interest my specific customer?

3. What LinkedIn article should I post that would attract the most interest?

4. Show me something interesting I likely have never seen before.

5. Of all the people who have asked me for something, who should I get back to first? Send me a note when I’m really late.

6. When a customer posts something on LinkedIn, update their list of key interests in CRM for me.

7. Tell me if someone has sent me an email or text and they are angry.

8. Match the top trends to the interests of my customers based on their LinkedIn posts and profiles. Send me updates when trends that impact these customers have something interesting.

9. Who in my organization, of thousands of people, would be best matched to speak to certain people at my customers? Send me those names on demand and their relevant topics.

10. Find the internal PowerPoint presentations that match the interests of my customers by topic and industry. Send me links to the presentations on demand and when I request for certain customers. As new presentations are created on the topics I need to know that.

11. What are some current competitive threats for my customers?

  1. Who are my customers currently interacting with on social media?

Conclusion

I find that “Digital Transformation” is such a loaded term these days with many organizations abusing the term. For me I look at Digital Transformation as a way to change the way people work. One of these ways is through the democratization of technology that allows employees to scale through access to tools. This is a great example of both democratized access to technology and improving the way people work through the automation of tasks. Only 2 years ago, this scenario was infeasible as it would require a developer to write a lot of code. Using Microsoft Flow, we can take advantage of other Microsoft investments, such as Azure Cognitive Services and Bing in order to build cutting-edge applications on a coffee-cup budget.

I want to thank Mark for bringing this scenario forward and identifying some very cool use cases for Microsoft Flow. I also want to thank his leader, Sarah for being a good sport about including her in this blog post as part of our scenario. I look forward to continuing to work with Mark in order to unlock more really innovative ideas using Microsoft Flow.

P.S. To never miss another blog post from the Flow blog – Use This Flow

The post Advanced | Flow of the Week: What interests my boss, fascinates me! appeared first on Microsoft Power Platform Blog.

]]>