Here we write a Power Automate Flow to pull a list of meetings from Meetup.com into our Teams app.
This article is the second in a series exploring combining Teams + Power Apps to create a helpful app for business users. In the first article, we created a simple event information Power App in Teams and connected it to a table with manually inputted data.
In this article, we’ll modify the table and use a flow to populate the list of meetings, automatically bringing in relevant information to help our users coordinate events.
Creating a Power App Flow
One way to get data into your Power App is to use a predefined connector. Standard Power Apps enable you to use a vast array of existing connectors. Using full Office Power Automate, you can create custom connectors. Currently, Power Apps in Teams doesn’t allow you to create these connectors.
First, we ensure we’re in the correct Power Automate environment to access the MeetingList table in our Teams environment. Doing this from the proper environment is crucial. Check whether you’re in the right environment by looking at the upper right-hand corner of Power Automate. You should see the name of your team.
We’ll use data from Meetup.com to explore .NET Foundation’s Virtual User Group events. We use a simple API call that doesn’t require authentication and returns a JSON meeting list.
Let’s start by opening our app from the previous article:
In the previous article, we created a table called MeetingList with fields to represent information from what would be an API call. Now, we’ll create a Power Automate flow to populate this table with data from Meetup.
After we open the Power App, we click the ellipses menu to the right of Settings and see that one of the options is Power Automate.
We select Power Automate to display a popout on the right side with an option + to create a new flow. We click +.
Note: If you have existing flows, they aren’t listed at first. If you want to see your current flows, click New. Then, when Power Automate appears in a new web instance, click My Flows in the left menu. This experience may change with future updates.
When we click + to create a new flow, a blank flow displays, ready to add a step. In this tutorial, we’ll make a simple, manually-triggered app to fetch all the current (that is, future) meetings each time we run the flow.
The flow doesn’t look blank, but it’s waiting for us to create the first step. We add a manual trigger here, but we could also trigger the flow on a schedule.
A manual trigger is the first step, so we go ahead and click Manually trigger a flow. We’re not going to do anything with this, but we see that we now have the first step.
Note: To follow this demonstration, you need a paid subscription ($40 per month for a single license to Power Automate or Power Apps, $10 per app, or a free 30-day trial). You need this paid subscription to access the premium HTTP and DATAVERSE actions.
As well, your default Office 365 environment is different from the Teams Dataverse. Each Teams team has a separate and private Dataverse that doesn’t easily communicate with others. You can upgrade your Teams environment to Dataverse, visible with your regular Office 365 Power Automate dashboard. The upgrade requires Dataverse capacity ($40 per gigabyte per month).
After selecting Manually trigger a flow, we click + New step, search for HTTP, and choose it. We then fill in the required information. We choose GET for our Method and set the URI to be the Meetup URL:
https://api.meetup.com/dotnet-virtual-user-group/events
Now, we name our flow, for example, CheckForNewMeetings, and click Save. We ignore the parameters from the previous step.
Next, we need to take the output from the API call and parse the JSON to access the individual fields. First, we add a new Action step and search for "JSON." We see "Parse JSON" in the list of actions and click it. The Content will be from the Body of the HTTP step.
We could manually create a schema, but it’s much easier to use sample data. We isolate one record of the JSON data and replace the closing "," with a "]". We also remove much of the description to shorten it, but it still works for schema generation. We paste this into the sample data:
[{"created":1625058549000,"duration":3600000,"id":"279169076","name":"Building dynamic applications with blazor","date_in_series_pattern":false,"status":"upcoming","time":1625920200000,"local_date":"2021-07-10","local_time":"05:30","updated":1625652672000,"utc_offset":-25200000,"waitlist_count":0,"yes_rsvp_count":45,"venue":{"id":26906060,"name":"Online event","repinned":false,"country":"","localized_country_name":""},"is_online_event":true,"group":{"created":1588792976000,"name":".NET Virtual User Group","id":33695761,"join_mode":"open","lat":47.61000061035156,"lon":-122.33000183105469,"urlname":"dotnet-virtual-user-group","who":"Members","localized_location":"Seattle, WA","state":"WA","country":"us","region":"en_US","timezone":"US/Pacific"},"link":"https://www.meetup.com/dotnet-virtual-user group/events/279169076/","description":"
About the session the Chairman of the Advisory Council for Microsoft's .NET Foundation.
","visibility":"public","member_pay_fee":false}]
The resulting generated schema is:
{
"type": "array",
"items": {
"type": "object",
"properties": {
"created": {
"type": "integer"
},
"duration": {
"type": "integer"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"date_in_series_pattern": {
"type": "boolean"
},
"status": {
"type": "string"
},
"time": {
"type": "integer"
},
"local_date": {
"type": "string"
},
"local_time": {
"type": "string"
},
"updated": {
"type": "integer"
},
"utc_offset": {
"type": "integer"
},
"waitlist_count": {
"type": "integer"
},
"yes_rsvp_count": {
"type": "integer"
},
"venue": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"repinned": {
"type": "boolean"
},
"country": {
"type": "string"
},
"localized_country_name": {
"type": "string"
}
}
},
"is_online_event": {
"type": "boolean"
},
"group": {
"type": "object",
"properties": {
"created": {
"type": "integer"
},
"name": {
"type": "string"
},
"id": {
"type": "integer"
},
"join_mode": {
"type": "string"
},
"lat": {
"type": "number"
},
"lon": {
"type": "number"
},
"urlname": {
"type": "string"
},
"who": {
"type": "string"
},
"localized_location": {
"type": "string"
},
"state": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"timezone": {
"type": "string"
}
}
},
"link": {
"type": "string"
},
"description": {
"type": "string"
},
"visibility": {
"type": "string"
},
"member_pay_fee": {
"type": "boolean"
}
},
"required": [
"created",
"duration",
"id",
"name",
"date_in_series_pattern",
"status",
"time",
"local_date",
"local_time",
"updated",
"utc_offset",
"waitlist_count",
"yes_rsvp_count",
"venue",
"is_online_event",
"group",
"link",
"description",
"visibility",
"member_pay_fee"
]
}
}
This output matches nicely with the MeetingList table we made!
The last step to create our flow is to take the parsed JSON and insert all the records into our database table MeetingList. Again, we click + New Step. This time, we search for "Dataverse" and select Add a new row.
To configure our row, we select the table name MeetingLists. Then, we click Show advanced options and fill in the blanks to map the fields from JSON to the table. Note that there are multiple ID fields, and we must determine which one to choose. With a bit of investigation, we discover the second field from the parsed JSON contains the meeting ID. To verify, we make sure they are all different.
After renaming and saving the step, we get the following:
Now we can save our flow, which automatically runs the Flow checker. If there are no errors, we click Test and select Manually. Next, we click Test at the bottom, then Run Flow. Our flow starts to execute and display the results. If we see all green checkmarks, our flow has succeeded. The Flow checker tags and displays errors on the right side window. We can carefully read the error to determine possible problems.
Note: We have added additional actions, List rows and Delete all rows, to clear the table each time. Better logic might be to only import new rows, for example, but you can determine what works best for you.
Finally, we can return to the Teams Power App and examine the inserted rows.
Next Steps
Power Apps in Teams is a powerful tool to boost productivity, integrating helpful functions into the communications hub your organization already uses. Using hundreds of preconfigured connectors and populating your custom table with external data using flows opens up endless possibilities for customization.
Here, we have used powerful built-in actions to bring data into our custom app without using any code. As Power Apps in Teams continues to improve and expand its capabilities, its functions are limited only by your imagination.
Continue to the third and final article of this series to learn how to edit data in your Power App and write it back to the app, helping your organization’s teams quickly and easily manage events with consistent information.