This sample code demonstrates how to create a real world line of business application with Office 365 services and the Microsoft Graph API. The application in this sample includes components that run in Microsoft Teams, Outlook, and inside SharePoint Framework web parts.
The sample application makes setting up, attending, and following up on meetings easy and productive.
To see an end to end demonstration of the functionality in this sample, watch this video.
We've automated as much of the installation process as possible with PowerShell and an ARM template. At a high level, here are the steps. To install the sample, follow the steps in the next section, Deployment Steps.
Register for the Actionable Email Developer Dashboard
Item | Description |
---|---|
Friendly Name | Feel free to fill in whatever you want here. |
Sender email address | Office 365 email account used to send Actionable Messages |
Target URLs | SharePoint site for storing documents in the Office 365 account |
Scope of submission | Select Organization |
Item | Key |
---|---|
Provider Id (originator) | originatorId |
Sender email address from which Actionable Emails will originate | EmailSender |
Clone the code in this repository to your local environment.
Create the AAD Application
Use the following format and replace the
api://<YOUR.CUSTOM.DOMAIN>/<GUID GENERATED BY AZURE>
access_as_user
.Teams can access the user's profile.
.Allows Teamsto call the app web APIs as the current user.
.Teams can access your user profile and make requests on your behalf.
.Enable Teams to call this app's APIs with the same rights that you have.
.Click Add a client application.
In the Client ID textbox, enter 1fec8e78-bce4-4aaf-ab1b-5451cc387264
.
Check the Authorized scopes checkbox.
Click Add application.
Click Add a client application.
In the Client ID textbox, enter 5e3ce6c0-2b1f-4285-8d4b-75ee78787346
.
Check the Authorized scopes checkbox.
Click Add application.
Click API permissions.
Click Microsoft Graph.
In the search box, enter the name of each permission in the list below, then check the checkbox next to it, and finally click Update permissions.
Note: Here is an example of doing this with the Calendars.Read permission.
Repeat the process until all of the permissions in this list are added.
When you are finished, the screen will indicate all permissions have been granted.
Deploy the ARM Template with PowerShell
ARMParameters.json
file and update following values.Key | Description |
---|---|
webAppName | Free, but must be globally unique, 2-60 characters, valid characters include 0-9, a-z, A-Z, and _. If you enter the name fy19demo, the default web site url will be https://fy19demo.azurewebsites.net |
customHostname | This parameter is the custom domain name you created in the prerequisites section. For example, if you created a custom host named mygreatdemo.tk then you would enter mygreatdemo.tk for this parameter. Note: Before deploying the ARM template, you need to create a CNAME record in DNS to map the custom domain name to the webAppName name parameter (listed above). For example, if you use fy19demo for the webAppName parameter then the default web site name will be fy19demo.azurewebsites.net. Therefore, you need to create a CNAME in DNS to map the customHostname parameter to fy19demo.azurewebsites.net. |
sqlAdministratorLogin | SQL Server administrator account name. |
sqlAdministratorLoginPassword | SQL Server administrator password. |
sqlDatabaseName | SQL Server database name |
actionMessageOriginatorId | originatorId generated in step Register for Actionable Email Developer Dashboard |
clientId | Client Id generated in the Create the AAD Application step. |
clientSecret | Client Secret generated in the Create the AAD Application step. |
tenantId | Tenant Id recorded in the Create the AAD Application step. |
Connect-AzAccount
..\DeployTemplate.ps1
. When prompted, enter the name of the resource group to create.Compile and deploy the server code
.\PublishWebapp.ps1
. When prompted, enter the same resource group name and webAppName you entered in previous steps.Create the Teams App
In the command line, change to the .\Source\FY19GraphShowcaseDemo\MeetingCaptureWebApp\Manifest directory.
Open the manifest.json
file with a text editor.
Update following values.
Key | Value | Description |
---|---|---|
configurationUrl | https://{customHostname}/configure/ | Replace {customHostname} with your customHostname value. |
validDomains | customHostname | The same customHostname value used in previous steps. |
webApplicationInfo.id | Client Id | This value is generated in step Create the AAD Application. |
webApplicationInfo.resource | App IdentifierUri | This value is generated in step Create the AAD Application. |
Save the file.
Run the script PublishTeamApp.ps1
to package the Microsoft Teams App in the manifest.zip file.
Open the Microsoft Team App, click Apps, then click Upload a custom app and finally Upload for {your company}.
Upload the manifest.zip file.
Add the Apps to Microsoft Teams Tabs
In this section you create a Teams Tab and add the web app to the tab.
First, deploy the Meeting Capture web app.
Next, deploy the Pending Meetings SPFx web part.
Compile and deploy SharePoint SPFx web part
In this section you will configure, compile, package, and deploy the SPFx web part to the App Catalog, add it to a SharePoint Site, approve the API permissions for it, then add it to a Teams Tab and configure it.
Note: You can use the Microsoft Graph Explorer to quickly find Planner Ids and Bucket Ids with this query.
https://graph.microsoft.com/v1.0/planner/plans/{plan-id}/buckets
Save the file.
In the command line, change to the .\Source\SPFX\PendingMeetings directory.
Run following commands to restore, build, and package the solution.
npm install
gulp build
gulp bundle --ship
gulp package-solution --ship
Then run the following command to publish web part to Microsoft Teams.
.\PublishWebpart.ps1
Please refer to the below table to enter the parameters:
Name | Value | Description |
---|---|---|
orgName | \<orgName> | The name of the tenant. If your SharePoint URL is http://contoso.sharepoint.com then your orgName is contoso. |
adminUPN | \user\>@\<orgName\.onmicrosoft.com | The site administrator account. For example: admin@contoso.onmicrosoft.com |
Add the SharePoint App to the SharePoint site associated with the Team where you are adding the Pending Meetings Teams Tab SPFx app.
Approve the API requests in the SharePoint Admin Center.
In Teams, click the + button to add a new Tab, select PendingMeetings, click Save.
Enter the Id for the Team and the Id for the Channel that you would like to query tasks from.
Note: You can use the Microsoft Graph Explorer to quickly find Teams Ids and Channel Ids with these queries.
https://graph.microsoft.com/v1.0/me/joinedTeams https://graph.microsoft.com/v1.0/teams/{team-id}/channels
The deployment is now complete! You are now ready to run the demo.
Follow these steps to demonstrate how to use the sample and all of the features and functionality it provides.
We use the Office365 service to get attendees photos, so please use Office365 to open emails and see the profile pictures.
This demo can be performed with 1 or more user accounts. It's really up to the presenter. In this demo script, user 1 is the person who sets up and attends the meeting and user 2 is a person who attends the meeting.
User 1 fills out a custom form in the web application to make the first meeting.
Enter a title for the meeting.
The form allows the creator to assign attendees to the meeting.
By default, the people User 1 most frequently works with, who are members of the Team, are added as attendees.
Select a date and time for the meeting that works for all attendees.
Any or all the Team’s members can be removed before the form is submitted.
User 1 attaches documents that are considered pre-reads. Each time a document is attached a task is created to read it before the meeting starts. This is known as a pre-read task. Pre-read tasks are assigned to all meeting attendees, one task per document that is uploaded.
Note: Do not upload files larger than 4MB. See the Known Limitations section in this document for more information.
User 1 adds meeting agenda items in a structured list.
The system automatically reminds people to complete their pre-read tasks.
Users can easily access pre read tasks to prepare for the meeting.
Once the meeting begins, users can capture notes and assign tasks related to the meeting.
The system publishes the notes and tasks to OneNote and Planner.
To delete demo data open the menu for the Meeting Capture tab and select Settings.
In the dropdown list, select Delete Events.
The page will refresh and show you a list of all the meetings. Click the delete button next to a meeting to delete it. When you delete a meeting EVERYTHING associated with it in the demo is deleted (Outlook, Planner, Files, SQL).
You can also add another tab with the Delete Events option selected if you want one tab for the Meeting Capture app and another tab to delete events.
In this sample we use the Graph Toolkit Controls wherever possible. You will see them in both the ASP.NET MVC Web Site and in the SPFX web part. By default, Graph Toolkit Controls make client side Graph API calls. In this sample, the Graph Toolkit controls use the Proxy Provider that allows it to use the .NET SDK to make server side calls to Graph. We took this approach because we did not want to have some of the application's calls to Graph client side and some of them server side. This pattern makes the Graph API access pattern consistent. You do not have to use the same approach we used in this sample, it is OK to skip the proxy and instead have both client side and server side calls to the Graph API in your code. It's up to you.
Learn more about the Graph Toolkit Controls and the Proxy.
The SQL Server Database supplements the application and stores information about meeting agenda items, attendees, meetings, files associated with tasks, and channels.
If you would like to browse the data in the database, follow these steps.
In the resource group, locate the SQL database and click it.
Click Query editor(preview) and login to the SQL server with the sqlAdministratorLogin and sqlAdministratorLoginPassword parameters you set in the ARMParameters.json
file.
Expand the Tables node to see the different tables in the database.
TeamChannels
In the Meeting Capture web application, on the new meeting creation page, we implemented some custom business logic to add the default meeting attendees. Essentially, we wanted to invite the people who the meeting organizer works with the most, but only if they are a member of the Team. We also wanted to ensure no duplicates were added. To implement this we used the Microsoft Graph API. Here's what the logic looks like at a high level.