Latest Posts

  • Build seamless automations to boost productivity with Microsoft Graph, Azure Event Hubs and Functions

    Every day millions of people spend their precious time in productivity tools. What if you use data and intelligence behind the Microsoft applications (Microsoft Teams, Outlook, and many other Office apps) to build seemsless automations and custom apps to boost productivity? In this post, we’ll build a seamsless onboarding experience to new employees joining a company with the power of Microsoft Graph.

    📝 What We’ll Cover

    • ✨ The power of Microsoft Graph
    • 🖇️ How do Microsoft Graph and Event Hubs work together?
    • ⚒️ Exercise: Setup Azure Event Hubs and Key Vault
    • 🪡 Exercise: Subscribe to users resource to receive change notifications by using Azure Functions
    • ♾️ Exercise: Create Onboarding Function
    • 🚀 Debug your onboarding experience
    • 📚 Resources

    Following pre-requisites are recommended:

    ✨ The power of Microsoft Graph

    Microsoft Graph is the gateway to data and intelligence in Microsoft 365 platform. Microsoft Graph exploses Rest APIs and client libraries to access data across Microsoft 365 core services such as Calendar, Teams, To Do, Outlook, People, Planner, OneDrive, OneNote and more.

    Microsoft Graph Overview

    You can build custom experiences by using Microsoft Graph such as automating the onboarding process for new employees. When new employees are created in the Azure Active Directory, they will be automatically added in the Onboarding team on Microsoft Teams.

    Solutions Architecture

    🖇️ How do Microsoft Graph and Event Hubs work together?

    Microsoft Graph uses webhook mechanism to track changes in resources and deliver change notifications to the clients. As an example to the Microsoft Graph Change Notifications, you can receive change notifications when:

    • a new task is added in the to-do list
    • a user changes the presence status from busy to available
    • an event is deleted/cancelled from the calendar

    If you’d like to track a large set of resources in a high frequency, you can use Azure Events Hubs instead of traditional webhooks to receive change notifications. Azure Event Hubs is a popular real-time events ingestion and distribution service built for scale.

    Microsoft Graph Change Notifications can be also received by using Azure Event Grid that is currently available for Microsoft Partners. Please review the documentation for more information: Partner Events overview for customers – Azure Event Grid

    ⚒️ Exercise: Setup Azure Event Hubs and Key Vault

    To get Microsoft Graph Change Notifications delivered to Azure Event Hubs, we’ll have to setup Azure Event Hubs and Azure Key Vault. We’ll use Azure Key Vault to access to Event Hubs connection string.

    1️⃣ Create Azure Event Hubs

    1. Go to Azure Portal and select Create a resource, type Event Hubs and select click Create.
    2. Fill in the Event Hubs namespace creation details, and then click Create.
    3. Go to the newly created Event Hubs namespace page, select Event Hubs tab from the left pane and + Event Hub:
      • Name your Event Hub as Event Hub
      • Click Create.
    4. Click the name of the Event Hub, and then select Shared access policies and + Add to add a new policy:
      • Give a name to the policy
      • Check Send and Listen
      • Click Create.
    5. After the policy has been created, click the name of the policy to open the details panel, and then copy the Connection string-primary key value. Write it down; you’ll need it for the next step.
    6. Go to Consumer groups tab in the left pane and select + Consumer group, give a name for your consumer group as onboarding and select Create.

    2️⃣ Create Azure Key Vault

    1. Go to Azure Portal and select Create a resource, type Key Vault and select Create.
    2. Fill in the Key Vault creation details, and then click Review + Create.
    3. Go to newly created Key Vault and select Secrets tab from the left pane and click + Generate/Import:
      • Give a name to the secret
      • For the value, paste in the connection string you generated at the Event Hubs step
      • Click Create
      • Copy the name of the secret.
    4. Select Access Policies from the left pane and + Add Access Policy:
      • For Secret permissions, select Get
      • For Principal, select Microsoft Graph Change Tracking
      • Click Add.
    5. Select Overview tab from the left pane and copy the Vault URI.

    🪡 Exercise: Subscribe to users resource to receive change notifications by using Azure Functions

    To start receiving Microsoft Graph Change Notifications, we’ll need to create subscription to the resource that we’d like to track. We’ll use Azure Functions to create subscription.

    To create subscription for Microsoft Graph Change Notifications, we’ll need to make a http post request to https://graph.microsoft.com/v1.0/subscriptions. Microsoft Graph requires Azure Active Directory authentication make API calls. First, we’ll need to register an app to Azure Active Directory, and then we will make the Microsoft Graph Subscription API call with Azure Functions.

    1️⃣ Create an app in Azure Active Directory

    1. In the Azure Portal, go to Azure Active Directory and select App registrations from the left pane and select + New registration. Fill in the details for the new App registration form as below:
      • Name: Graph Subscription Auth
      • Supported account types: Accounts in any organizational directory (Any Azure AD directory – Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)
      • Select Register.
    2. Go to newly registered app in Azure Active Directory, select API permissions:
      • Select + Add a permission and Microsoft Graph
      • Select Application permissions and add User.Read.All and TeamMember.ReadWrite.All.
      • Select Grant admin consent for the organization
    3. Select Certificates & secrets tab from the left pane, select + New client secret:
      • Choose desired expiry duration
      • Select Add
      • Copy the value of the secret.
    4. Go to Overview from the left pane, copy Application (client) ID and Directory (tenant) ID.

    2️⃣ Create subscription with Azure Functions

    1. Open Visual Studio Code, open the pallete by clicking CTRL + SHIFT + P on Windows or CMD + SHIFT + P on Mac, search for “create function” and choose Azure Functions: Create Function:

      • A window will pop-up with a message “you must have a project open to create function”, select Create new project. Create a new folder and select the folder for your project
      • Select JavaScript as a project language
      • Select Timer Trigger as a template for your project’s first function.
      • Name your Timer Trigger as SubscriptionFunction and press enter.
      • Specify schedule as 0 */61 * * * * and press enter
      • Select Open in current window and press enter.
    2. Select Terminal from the menu bar on top and select New Terminal. Run the following commands in the terminal to install the dependencies:

      npm install @azure/identity @microsoft/microsoft-graph-client isomorphic-fetch readline-sync
      
    3. Create a folder under the project and name as Shared.

    4. Create a new file inside the Shared folder, name as dateTimeFormat.js, copy the entire code in dateTimeFormat.js inside your file to define the expiration date of the subscription.

    5. Create a new file inside the Shared folder, name as Graph.js. Add the following authentication code snippet inside the Graph.js:

      const expiry = require('./dateTimeFormat');
      require('isomorphic-fetch');
      const azure = require('@azure/identity');
      const graph = require('@microsoft/microsoft-graph-client');
      const authProviders = require('@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials');
      let _clientSecretCredential = undefined;
      let _appClient = undefined;
      let _expiry = undefined;
      
      function ensureGraphForAppOnlyAuth() {
      if (!_clientSecretCredential) {
          _clientSecretCredential = new azure.ClientSecretCredential(
          '',
          '',
          ''
          );
      }
      
      if (!_appClient) {
          const authProvider = new authProviders.TokenCredentialAuthenticationProvider(
          _clientSecretCredential, {
              scopes: [ 'https://graph.microsoft.com/.default' ]
          });
      
          _appClient = graph.Client.initWithMiddleware({
          authProvider: authProvider
          });
      }
      }
      

      Replace , and with the registered app details in the previous step

    6. Add the following function inside Graph.js to make a REST API request to Microsoft Graph /subscriptions endpoint and create a subscription to track new users:

      async function postSubscriptionAsync() {
      ensureGraphForAppOnlyAuth();
      if(!_expiry){
          _expiry = await expiry.getDateTimeAsync();
          }
          const subscription = {
              changeType: 'created, updated',
              notificationUrl: 'EventHub:https:///secrets/?tenantId=',
              resource: 'users',
              expirationDateTime: _expiry,
              clientState: 'secretClientValue',
              };
          
          return _appClient?.api('/subscriptions')
              .post(subscription);
      }
      module.exports.postSubscriptionAsync = postSubscriptionAsync;
      

      In notificationUrl, make sure to replace with the vault uri, with the secret name and with the tenant id that you copied from the Key Vault.

    7. Go to SubscriptionFunction > index.js and copy the following references on top of the page:

      require('isomorphic-fetch');
      const graph = require('../Shared/graph');
      
    8. In the index.js, copy the following code snippet inside the function to trigger the subscription every 61 minutes:

          const subscription = await graph.postSubscriptionAsync();
      
    9. Go to local.settings.json, replace the existing code with the code snippet below:

      {
      "IsEncrypted": false,
      "Values": {
          "AzureWebJobsStorage": "UseDevelopmentStorage=true",
          "FUNCTIONS_WORKER_RUNTIME": "node"
      },
      "watchDirectories": [ "Shared" ]
      }
      
    10. For the testing purposes only, go to SubscriptionFunction > function.json and add the following parameter inside the binding:

      "runOnStartup": true
      

      Make sure to remove this parameter for the production.

    11. Run the Microsoft Azure Storage Emulator and run the following command on the Visual Studio Code terminal to test your function:

      func host start
      

    When subscription function runs successfully, it will create a subscription for users resource. Azure Event Hubs will receive notifications whenever there is a new user created in Azure Active Directory.

    ♾️ Exercise: Create Onboarding Function

    We’ll create a second function in the project to receive change notifications from Event Hubs when there is a new user created in the Azure Active Directory and add new user in Onboarding team on Microsoft Teams.

    1. Open the patlete on Visual Studio by clicking CTRL + SHIFT + P on Windows or CMD + SHIFT + P on Mac, search for “create function” and choose Azure Functions: Create Function:

      • Select Azure Event Hub trigger as a template for your function
      • Name your Event Hub trigger as OnboardingFunction and press enter
      • Select + Create new local app setting
      • Select your Event Hub settings that you created in the previous steps:
        • Azure subscription
        • Event Hub Namespace
        • Event Hub
        • Event Hub policy
        • Consumer group
      • Press enter.
    2. Go to Shared > Graph.js, add the following parameter on top of the page:

      let _memberId = undefined;
      
    3. Inside Graph.js, copy the following code to automatically add the new user to the Onboarding team on Microsoft Teams:

      async function postTeamsMemberAsync(memberId) {
          ensureGraphForAppOnlyAuth();
          _memberId = memberId;
          const user = 'https://graph.microsoft.com/v1.0/users(\'' + _memberId +'\')';
          const conversationMember = {
              '@odata.type': '#microsoft.graph.aadUserConversationMember',
              roles: ['owner'],
              'user@odata.bind': user
          };
          
          return _appClient?.api('/teams//members')
              .post(conversationMember);       
      }
      module.exports.postTeamsMemberAsync = postTeamsMemberAsync;
      

      Make sure to replace with the team id that you’d like to add your users as a member. You can login to Microsoft Graph Explorer and run my joined teams sample query to view available team ids.

    4. Go to OnboardingFunction > index.js and copy the following references on top of the page:

      const graph = require('../Shared/graph');
      
    5. In the index.js, and replace the code inside the function with the following code snippet:

       eventHubMessages.forEach(async (message, index) => {
          var jsonMessage = JSON.parse(message);
          
          for (let i in jsonMessage.value) {
              var resourceData = jsonMessage.value[i].resourceData;
              const newMemberId = resourceData.id;
              await graph.postTeamsMemberAsync(newMemberId);
          }
      });
      

    🚀 Debug your onboarding experience

    To debug our onboarding experience, we’ll need run our functions locally and create a new user in Azure Active Directory to see if the new user is added automatically in Microsoft Teams Onboarding team.

    1. Open the terminal in Visual Studio Code and run your functions with the following command:

      func host start
      

      Make sure that Microsoft Azure Storage Emulator is running in the background.

    2. Go to Azure Portal and select Azure Active Directory from the left pane and go to Users. Select + New user and Create new user. Fill in the details as below:

      • User name: JaneDoe
      • Name: Jane Doe

    Add new user in Azure Active Directory

    1. When you added Jane Doe as a new user, it should trigger the OnboardingFunction to run.

    Once the OnboardingFunction runs successfully, you should be able to see Jane Doe as a member of the Onboarding team on Microsoft Teams! 🥳 New member in the onboarding team

    Source code for this solution can be found in the following GitHub Repository: Onboarding-Functions

    📚 Resources

  • No time to manage your calendar? Let Power Automate assist your response to calendar invites using Microsoft Graph connectors

    Hi there! I would like to share a solution about a scenario/challenge that I personally experienced in the past when I was a consultant.

    Consultants or anyone who works with customers day to day bases may know that we spend the entire day with our customers to plan/work together on our projects.

    Meetings after meetings -recurring everyday-, we almost never have time to check our e-mails. Most of us also miss the new meeting invites for the next day and never get a chance to say “I have a conflict in my calendar”.

    So, we may end up having meetings conflicting in the calendar and unable to attend half of it. Sounds familiar?

    What if we build a flow in Power Automate using out of the box Microsoft Graph connectors to check calendar availability, every time when there is a new calendar event received? May our flow be able to send a accept/tentative/decline response automatically according to user’s calendar status? Yes, of course it can!

    Power Automate has hundreds of Microsoft Graph powered out of the box connectors to get e-mails, post messages to Teams, send a calendar invite and many more. However, not all M365 datasets are available in this collection of built-in connectors. If you are interested in using any M365 dataset in your project, Microsoft Graph Power Automate Tutorial shows how to build a custom connector and consume it in the Power Automate flow.

    For this example, We have the right out of the box connectors to design the scenario. Process will be similar to the flow shown below:

    Let’s build our flow in Power Automate

    Go to https://flow.microsoft.com and select Create on the left hand side menu and choose Automated flow.

    Give a name to your flow and choose your flow trigger as When a new event is created (V3). Select Create.

    In the flow, add the following connectors and fill the fields as follows:

    • When a new event is created (V3)
    • *Calendar id: [Calendar]
    • Get Event (V3)
    • *Calendar id: Calendar
    • *Item id: [Id] (Dynamic content/When new event is created (V3))
    • Get calendar view of events (V3)
    • *Calendar id: Calendar
    • *Start time: [Start time] (Dynamic content/Get Event (V3))
    • *End time: [End time] (Dynamic content/Get Event (V3))

    • Filter array
      *From: [value] (Dynamic content/Get calendar view of events (V3))
    • *Choose a value: [Id] (Dynamic content/Get calendar view of events (V3))
    • *Filter: is not equal to
    • *Choose a value: [Id] (Dynamic content/Get Event (V3))
    • Condition
      *Choose a value: length(body(‘Filter_array’))
      (Expression)
    • *Condition: is less than or equal to
    • *Choose a value: 0

    • IF YES
    • Respond to an event invite (V2)
      *Event Id: [Id] (Dynamic content/Get Event (V3))
    • *Response: Accept
    • *Comment: Looking forward to talk to you soon!
    • *Send Response: Yes
    • Post a message as the Flow bot to a user (Preview)
    • *Recipient: { your recipient e-mail here }
    • *Message: [Subject] (Dynamic content/Get Event (V3)) organized by [Organizer] (Dynamic content/Get Event (V3)) is accepted and added in your calendar.
    • *Headline: Meeting accepted!
    • IF NO
    • Get calendar view of events (V3)
      *Calendar Id: Calendar
    • *Start Time: [End time] (Dynamic content/Get Event (V3))
    • *End Time: addDays(body(‘Get_event_(V3)’)?[‘end’],1)
      (Expression)
    • Condition
    • *Choose a value: length(body(‘Get_calendar_view_of_events_(V3)_2’)?[‘value’])
    • (Expression)
    • *Condition: is greater than or equal to
    • *Choose a value: 5
    • IF YES
    • Respond to an event invite (V2)
      *Event Id: [Id] (Dynamic content/Get Event (V3))
    • *Response: Decline
    • *Comment: Hi, unfortunately there is a conflict in my calendar. So, I won’t be able to join this meeting today. Can we meet any other day?
    • *Send Response: Yes
    • Post a message as the Flow bot to a user (Preview)
    • *Recipient: { your recipient e-mail here }
    • *Message: [Subject] (Dynamic content/Get Event (V3)) organized by [Organizer] (Dynamic content/Get Event (V3)) is declined.
    • *Headline: Meeting declined!
    • IF NO
    • Send email with options
      *To: Organizer (Dynamic content/Get Event (V3))
    • *Subject: Tentative: Can we reschedule?
    • *User Options: Yes, No
    • Post a message as the Flow bot to a user (Preview)
    • *Recipient: { your recipient e-mail here }
    • *Message: [Subject] (Dynamic content/Get Event (V3)) organized by [Organizer] (Dynamic content/Get Event (V3)) is conflicting with other meetings. We realized you have some availabilities in your calendar and asked [Organizer] (Dynamic content/Get Event (V3)) to reschedule.
    • *Headline: Reschedule requested!

    Test the scenarios!

    Select Save and Test on the right hand side bar and choose I’ll perform the trigger action to test your flow.

    The flow is tracking the following account’s calendar: Mod Administrator (admin@M365x716122.onmicrosoft.com)
    The user who sends the calendar invites: Ayca Bas (aycabas@M365x716122.onmicrosoft.com)

    Scenario 1: No Conflict

    Ayca Bas sends a calendar invite to the Mod Administrator. If there is no conflict in Mod Administrators’ calendar, Ayca Bas will receive an Accepted response, and Flow bot will notify Mod Administrator about the taken action.

    Ayca Bas receives:

    Mod Administrator receives:

    Scenario 2: Conflict, calendar is not busy for the day

    Ayca Bas sends a calendar invite to the Mod Administrator. If there is a conflict in Mod Administrators’ calendar but there are less than 5 events for the day, Ayca Bas will receive a Tentative response, requesting to reschedule the meeting. Flow bot will notify Mod Administrator about the taken action.

    Ayca Bas receives:

    Mod Administrator receives:

    Scenario 3: Conflict, calendar is busy for the day

    Ayca Bas sends a calendar invite to the Mod Administrator. If there is a conflict in Mod Administrators’ calendar and there are more than 5 events for the day, Ayca Bas will receive a Decline response. Flow bot will notify Mod Administrator about the taken action.

    Ayca Bas receives:

    Mod Administrator receives:

    Solution package.zip file can be found under the following repository: My Calendar Manager.

  • Get your To-Do tasks every morning on Microsoft Teams using Azure Logic Apps

    I am super excited since Microsoft Graph To Do APIs are introduced at Microsoft Build 2020. We finally have APIs available in public preview on the beta endpoint of Graph.

    Just a brief introduction, Microsoft To Do and Planner are the essence of tasks in Microsoft 365. To-Do helps you create a list for anything, from work assignments to school projects to groceries. It is a great tool for your personal use. On the other hand, Planner is the best place to collaborate as a team and keep your team tasks. Tasks come from everywhere, you can keep track of deadlines by adding reminders, due dates, and notes.

    Wouldn’t it be nice to receive your list of assigned tasks every morning on Microsoft Teams?

    Today, we will build a flow using Azure Logic Apps to automate Microsoft Teams Flow bot for sending To-Do tasks every morning at 9 AM. Here is the steps we will follow:

    Logic Apps Flow

    Microsoft Graph To-Do APIs in Graph Explorer

    To be able to review Microsoft Graph To-Do API queries and responses with your own data, go to Microsoft Graph Explorer and login with your account from the top left corner by clicking Sign in to Graph Explorer.

    Then, search for “to do” under Sample queries and select Get my to do task list. This will run the query https://graph.microsoft.com/beta/me/todo/lists and will get all the task lists as a response. Copy one of your preferred task list Id from the response.

    To-Do in Graph Explorer

    Let’s try to get all the tasks under your preferred task list. Change the query with the following: https://graph.microsoft.com/beta/me/todo/lists/{taskListId}/tasks. Make sure the request is GET and hit Run query. You should be able to see all tasks under the selected list as a response.

    Copy this query and save somewhere, we will use this later while creating a custom connector.

    To-Do in Graph Explorer

    Register your app in Azure Active Directory

    Go to Azure Active Directory in Azure Portal. Select App Registrations and choose New registation.

    Azure Active Directory App Registration

    Enter To-do-flow-app in the Name field. In the Supported account types section, select Accounts in any organizational directory and personal Microsoft accounts. Leave Redirect URI blank and choose Register to continue.

    Azure Active Directory App Registration

    Go to API permissions from the left hand side menu and select add a permission. Choose Microsoft Graph and Delegated Permissions. Select Task.ReadWrite and click Add permission button.

    Azure Active Directory App Registration

    Go to Certificates & secrets from the left hand side menu and select New client secret under the Client secrets. Choose expiry time and Add.

    Azure Active Directory App Registration

    Copy the secret you created and Application Id under the Overview page. Save them somewhere, we will use them while creating a custom connector.

    Build Azure Logic Apps Custom Connector to consume To-Do APIs in a flow

    Go to Azure Portal and create Logic Apps Custom Connector.

    Logic Apps Custom Connector

    On the connector configuration, fill the fields as follows:

    • Subscription: Select an Azure subscription
    • Resource Group: Create new resource group
    • Custom connector name: give a name for your custom connector
    • Select the location: Region
    • Location: Select the preferred location

    Choose Review + create button to continue.

    Logic Apps Custom Connector

    When your custom connector is successfully created, select Edit to configure your connector.

    Logic Apps Custom Connector

    On the connector configuration General page, fill in the fields as follows.

    • Scheme: HTTPS
    • Host: graph.microsoft.com
    • Base URL: /

    Choose Security button to continue.

    Logic Apps Custom Connector

    On the Security page, fill in the fields as follows.

    • Choose what authentication is implemented by your API: OAuth 2.0
    • Identity Provider: Azure Active Directory
    • Client id: the application ID you created in the previous exercise
    • Client secret: the key you created in the previous exercise
    • Login url: https://login.windows.net
    • Tenant ID: common
    • Resource URL: https://graph.microsoft.com (no trailing /)
    • Scope: Leave blank

    Choose Definition button to continue.

    Logic Apps Custom Connector

    On the Definition page, select New Action and fill in the fields as follows.

    • Summary: Get To-Do Tasks
    • Description: Get To-Do Tasks
    • Operation ID: ToDo
    • Visibility: important

    Create Request by selecting Import from Sample and fill in the fields as follows.

    Select Import.

    Logic Apps Custom Connector

    Choose Create Connector on the top-right. After the connector has been created, copy the generated Redirect URL from Security page.

    Logic Apps Custom Connector

    Go back to Azure Active Directory registered app, go to Authentication tab and select Add platform, choose Web.

    Logic Apps Custom Connector

    Paste the Redirect URI you copied from the custom connector under the Redirect URIs. Select Access tokens and Id tokens. Click Configure to continue.

    Logic Apps Custom Connector

    Create Logic Apps flow to automate receiving To-Do tasks

    Go to Azure Portal and create Logic App.

    Logic Apps Flow

    On the configuration page, fill the fields as follows:

    • Subscription: Select an Azure subscription
    • Resource Group: Create new resource group
    • Custom connector name: give a name for your logic app
    • Select the location: Region
    • Location: Select the preferred location

    Choose Review + create button to continue.

    Logic Apps Flow

    When your Logic app is successfully created, go to your Logic app and choose Logic app designer. Select Recurrence as a trigger.

    Logic Apps Flow

    Configure the recurrence as follows:

    • Interval: 1
    • Frequecy: Day
    • Timezone: Select the timezone you prefer
    • Start time: YYYY-MM-DDTHH:MM:SSZ
    • At these hours: 9
    Logic Apps Flow

    Click plus button, go to Custom and choose To-Do Connector as a next step and select Get To-Do Tasks as an action.

    Logic Apps Flow

    Sign in with the same account you practiced To-Do APIs in the Graph Explorer.

    Logic Apps Flow

    Run the flow and see if you successfully get to-do tasks by using your Get To-Do Tasks. Copy the outputs body, we will use it in the next step.

    Logic Apps Flow Results

    Add Parse JSON as a next step. Place Get To-Do Tasks body under the Context. Select generate schema, paste the response body you are receiving from the Get To-Do Tasks and save.

    Logic Apps Flow

    Add Initialize variable as a next step. Fill the field as follows:

    • Name: Tasks
    • Type: Array
    • Value: leave blank

    Add For each as a next step and fill the fields as follows:

    • Output from previous steps: value from the Parse JSON step

    Add Compose in For each and fill the fields as follows:

    • Inputs: title from the Parse JSON step

    Add Append to array variable in For each, and fill the fields as follows:

    • Name: Tasks
    • Value: Outputs from the Compose step.
    Logic Apps Flow

    Run the flow and see if To-Do Json response is successfully parsed and all task titles are added in the Tasks array.

    Logic Apps Flow Results
    Logic Apps Flow Results

    As a next step after For each, add Post a choice of options as the Flow bot to a user and fill the fields as follows:

    • Options: Tasks from the Variables step
    • Headline: Good morning!
    • Receipent: The same account you consumed the custom connector
    • Message: Here is your tasks, have a great day! :)
    • IsAlert: Yes
    Logic Apps Flow

    Run the flow and see check Microsoft Teams for the related account if Flow bot is sending a message. Select one of the tasks to see the results in the Logic app flow.

    Note: If you didn't add Flow in your Microsoft Teams yet, here is the steps to enable Flow in your Teams account: https://cda.ms/1BB

    Teams Flow Bot Results
    Logic Apps Flow Results

    Finally, after user selected any of the tasks to see more details, we will post another card to share more details about the selected option.

    Add For each after Post a choice of options as the Flow bot to a user and fill the fields as follows:

    • Output from previous steps: value from Parse JSON step

    Add Condition in For each and fill the fields as follows:

    • Condition: And
    • Choose a value: SelectedOption from the Post a choice of options as the Flow bot to a user step
    • Operation: equal to
    • Choose a value: title from Parse JSON step
      • If true: Add Post message as a Flow bot to a user in true
        • Headline: title from Parse JSON step
        • Receipent: The same account you consumed the custom connector
        • Message: importancestatuscreatedDateTime from ParseJSON step
        • IsAlert: Yes
      • If false: leave blank
    Logic Apps Flow

    Here is the complete flow. Run the entire flow for testing.

    Logic Apps Flow

    And, the following is going to be the results after selecting one of the tasks to see the details:

    Teams Flow Bot Results
    Logic Apps Flow Results

    Our flow is completed! You can find the source code below:

  • Authentication in Teams tabs using Microsoft Graph Toolkit

    If you are looking for ways to build easy authentication for Microsoft Teams custom tab developmentMicrosoft Graph Toolkit Login component provides a button and flyout control to facilitate Microsoft identity platform authentication with couple of lines of code.

    How to build a tab with straightforward authentication flow?

    1. Enable Microsoft Teams Toolkit extension for Visual Studio Code
    2. Build Microsoft Teams tab
    3. Implement Microsoft Graph Toolkit:
    4. Setup ngrok for tunneling
    5. Register your app in Azure Active Directory
    6. Import your app manifest to Microsoft Teams App Studio for testing

    Enable Microsoft Teams Toolkit extension for Visual Studio Code

    Install Microsoft Teams Toolkit from the Extensions tab on the left side bar in Visual Studio Code. For more information, Microsoft Teams Toolkit: Setup and Overview.

    Microsoft Teams Toolkit Extension for Visual Studio Code

    Build Microsoft Teams tab

    • Select Microsoft Teams icon on the left side bar in Visual Studio Code and Sign in.
    Microsoft Teams Toolkit Extension for Visual Studio Code
    • Select Create a new Teams app,
      • Give a name for the app
      • Choose Tab for the capability
      • Select Next
    Microsoft Teams Toolkit Extension for Visual Studio Code
    • Select Personal tab
    • Select Finish
    Microsoft Teams Toolkit Extension for Visual Studio Code
    • Open Terminal and run:
      npm install
      npm start

    Implement Microsoft Graph Toolkit

    Add a new file under src folder and name it as Auth.js.

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './components/App';
    import { Provider, themes } from '@fluentui/react-northstar' //https://fluentsite.z22.web.core.windows.net/quick-start
    
    ReactDOM.render(
        
            
        , document.getElementById('auth')
    );
    

    Add a new file under public folder and name as auth.htmlCTRL+SPACE for adding HTML Sample. Add below code in 

    https://unpkg.com/@microsoft/teams-js/dist/MicrosoftTeams.min.js https://unpkg.com/@microsoft/mgt/dist/bundle/mgt-loader.js mgt.TeamsProvider.handleAuth();

    Add below code in index.html 

     https://unpkg.com/@microsoft/teams-js/dist/MicrosoftTeams.min.js
     https://unpkg.com/@microsoft/mgt/dist/bundle/mgt-loader.js
      
     
     
    

    Setup ngrok for tunneling

    npm start

    • Go to ngrok website and login.
    • Complete the setup and installation guide.
    • Save Authtoken in the default configuration file C:\Users\[user name]\.ngrok:

    ngrok authtoken

    ngrok http https://localhost:3000

    Ngrok Setup
    Ngrok Setup
    Ngrok Setup
    • Go to your project public > index.html, replace YOUR-NGROK-URL with ngrok url https://xxxxxxxxxxxx.ngrok.io in mgt-teams-provider > auth-popup-url.
    Ngrok Setup

    Register your app in Azure Active Directory

    • Go to Azure Portal, then Azure Active Directory > App Registration and select New Registration.
    Ngrok Setup
    • Fill the details to register an app:
      • give a name to your application
      • select Accounts in any organizational directory as an access level
      • place auth-popup-url as the redirect url https://xxxxxxxxxxxx.ngrok.io/auth.html
      • select Register
    Ngrok Setup
    • Go to Authentication tab and enable Implicit grant by selecting Access tokens and ID tokens
    Ngrok Setup
    • Go to API permissions tab, select Add a permission > Microsoft Graph > Delegated permissions and add Calendar.ReadCalendar.ReadWrite.
    • Then, select Grant admin consent.
    Ngrok Setup
    • Go to Overview tab and copy Application (client) ID
    • Then go to your project public > index.html, replace YOUR-CLIENT-ID with Application (client) ID in mgt-teams-provider > auth-popup-url.
    Ngrok Setup
    Ngrok Setup

    Import your app manifest to Microsoft Teams App Studio for testing

    • Go to Microsoft Teams, open App Studio > Manifest Editor and select Import an existing app.
    Ngrok Setup
    • Select Development.zip under your project folder > .publish.
    Ngrok Setup
    • Scroll down and select Test and distribute, then click Install and Add your app.
    Ngrok Setup
    Ngrok Setup
    • Click on Sign in for the authentication and give consent to AAD registered app you created.
    Ngrok Setup
    • Your profile information e-mailname and calendar should appear in your tab after the successful authentication.
    Ngrok Setup
    Solution repository is available here: https://github.com/aycabas/TeamsApp
  • Let people try your query in Microsoft Graph Explorer

    Microsoft Graph Explorer is a wonderful learning space for the ones who are looking for testing Microsoft Graph APIs and reviewing the responses quickly. It provides the simple authentication where you can login, then see the response preview with your own tenant data. The best part of Microsoft Graph Explorer is its user-friendly design that makes it practical and easy to understand how to benefit the most out of it. Even better, it continues evolving with new releases all the time!

    Today, we will explore one of the most practical features of Graph Explorer: “Share Query“. Let’s say that you are working with advanced queries ($filter, $search, $orderby etc.) in the Graph Explorer. After getting the required results, you would like to let people try your current query. We can easily do that in 2 steps:

    • Step 1: Click on Share button on the right side of the Response preview section.
    • Step 2: Copy your query and share with other people.
    • Result: Others can paste this shared link to any browser, then they will be directed to your pre-populated query in Microsoft Graph Explorer. They can click on Run Query button to see the response preview.

    Here is a sample query, feel free to copy and paste it in any browser to see the results in the Graph Explorer:

    https://developer.microsoft.com/en-us/graph/graph-explorer?request=groups?$filter=startswith(displayName,’all’)&method=GET&version=v1.0&GraphUrl=https://graph.microsoft.com&requestBody=IiI=

    Feel free to ask you questions and share your experience in the comment window.

    Cheers.

  • Microsoft Graph + Power Automate = M365 data with no code!

    Microsoft Graph provides a single endpoint to get connected with M365 data. We know that Power Automate has many built-in MS Graph components to access Outlook, Planner, Calendar and more. But, think about calling Microsoft Graph API with custom filters from Power Automate directly! It is even more exciting and gives us more flexibility and numerous automation possibilities with no-code. Today, our scenario is to get “members” of a particular group in 3 quick steps.


    Step 1: Register an application in Azure Active Directory

    • Go to Azure Portal.
    • Under Azure Active Directory, go to App Registration and click on New Registration.
    • Give a name to your app, choose the access level and hit Register button.
    • Go to API permissions tab, click on Add a permission, select Microsoft Graph and then Application permissions, add the following permissions: “Group.Read.All”, “Group.ReadWrite.All”, “User.Read.All”, “GroupMember.ReadWrite.All”, “User.ReadWrite.All”, “Directory.ReadWrite.All”.
    • After creating the permissions, we need to grant consent to the application to allow the application to access Graph API.
    • Go to Certificates & secrets and create a new client secret and copy in a notepad.
    • Finally, go to Overview tab, copy Application (client) ID and Directory (tenant) ID to a notepad, we will need it later.

    Step 2: Build Power Automate Flow

    • Go to Microsoft Power Automate Portal.
    • Click on Create tab and choose Instant flow.
    • Give a flow name and choose When an HTTP request is received as a trigger of the flow, then click Create.
    • Extend When a When an HTTP request is received block and click on Use sample payload to generate schema, then add the following schema:
    {
        "type" : "object",
        "properties" : {
           "groupId" : {
              "type" : "string"
           }
         }
    }
    • Then click Save.
    • Click New Step and add Initialize variable with the following details:
      • Name: application_id
      • Type: string
      • Value: AAD App – Application (Client) Id
    • Click New Step and add Initialize variable with the following details:
      • Name: directory_id
      • Type: string
      • Value: AAD App – Directory (Tenant) Id
    • Click New Step and add Initialize variable with the following details:
      • Name: secret
      • Type: string
      • Value: AAD App secret
    • Click New Step and add HTTP with the below details:

    Step 3: Test the Flow with Microsoft Graph Explorer and Postman

    • Go to Microsoft Graph Explorer.
    • Sign-in with your account.
    • Find all groups under my organization under Sample queries and click on it.
    • Copy one of the group ids for the testing purposes, we will use it in.
    • You may use Postman for testing purposes, and specify the following details:
      • Method: Post
      • Endpoint: copy it from the first step of your flow (When a HTTP request is received)
      • Header:
        • Key: Content-type
        • Value: application/json
      • Body: { “groupId” : “copied-groupid-from-GraphExplorer“}
    • Run test from Power Automate and send the post request from Postman.

    After the successful flow, we should receive the output with all the members’ information in Json format under HTTP block.

    Cheers.

    – Ayca

  • The Journey

    My big journey started in 2012 when I was at university. I was so passionate about many things and doing all of them at the same time: studying in a double major program (Electrical&Electronics Engineering and Software Engineering), working on Electric Car project funded by Scientific and Technological Research Council and getting ready for the “Electric Vehicle Race”, having internships at e-commerce, gaming companies and most importantly being a Microsoft Student Partner.

    As a Microsoft Student Partner, I was developing games for Microsoft Store, joining/organizing events, giving tech speeches at the student conferences, meeting new MSP friends from different universities, different countries. We (MSPs) became the experts of new cloud technologies before our graduation even though there was no cloud lecture at universities back then. MSP Program was another school for us, where we get a chance to learn the new stuff, cool stuff! When I look back today, I feel so lucky to be a part of it.

    I was so excited, interested in learning everything new. Sky was the limit, why would I focus on one thing if I could do it all!

    Note to young self: being an expert on a specific thing requires A LOT of attention and work.

    The Internship: a year in DX

    I remember the day I got accepted to the internship program at Microsoft, my heart was racing when I was reading the “congratulations!” e-mail. I was joining the Developer Experience (DX) team as an intern for a year. It was my last year at university and as you can imagine, I was half time at school, half time at Microsoft Office in Istanbul. I can confidently say that there was no other time I learned as much, worked as hard and felt fulfilled.

    A note about being an intern at Microsoft: according to my experience, there is not much difference between an intern and a full-time employee at Microsoft. First of all, you get the same blue badge with the full-time employees. You cannot recognize if the person presenting in the meeting is an intern or an FTE. Second of all, you are expected to join the team meetings, share your insights, take actions and be responsible.

    I was responsible of Microsoft Student Partner Program and luckily surrounded by the amazing people in Developer Experience (DX) team. There is one thing about DX team that I can never forget: their passion. I respected the way they think, the way they work and I learned a lot from them. In fact, they were the ones who encouraged me to drive the conversations, organize/lead various student related projects and pointed me as a lead of those everywhere in the communications. In the end, we achieved great success stories such as Student Partner Roadshow, Microsoft Summer School and Imagine Cup.

    None of this would have been real and I wouldn’t be the person I am today without DX team…

    “Believing me as a passionate kid and helping me become a professional engineer, from my first day, till today… I can’t thank them enough…”

    The first job: Microsoft Services (MACH)

    I gained a great technical muscle about the cloud technologies during my internship, so It was a very smooth transition from the internship to FTE for me. Right after I earned my degrees, I joined the MACH (Microsoft College Hire) Program in Microsoft Services as a Premier Field Engineer.

    Being a MACH hire at Microsoft gives you a lot of privileges and support. To begin with, you get to be hired with many college graduates at the same time. So, you figure out many things all together. Also, you get great friendships during the program and you always stay connected with them over the years! Another benefit of the program was the specialized onboarding process for MACHs. Since we were the fresh graduates, we got many technical and soft-skill trainings before starting to our actual roles. After having fun, learning a lot of new things and gaining many friendships, we were ready to start working in real life.

    I should admit, working onsite with the customers as a fresh graduate is not easy. You should put a lot of effort to become a trusted engineer. I was already trained about Azure App Services, Bot Framework, Cognitive Services and IoT during my internship, so after my onboarding I directly started working with the customers onsite.

    Becoming a Senior

    During my Premier Field Engineer role, I worked onsite with more than 100 customers, delivered thousands of sessions (projects, workshops) and traveled more than 30 different countries in the process. This is the time I continuously learned, developed, shared, grown and became expert on what I’m doing. It’s a great feeling to be accepted as a mature developer.

    A new journey: Cloud Advocates

    Today is a new start for me. After being a part of MSP community, an intern in DX team and working onsite with many customers as a PFE, I am proudly joining Cloud Advocates team at Microsoft, focusing on Microsoft Graph and Microsoft Teams.

    Highlights
    • People
      • Advocacy team is full of passionate people about technology. I watch them in MS Build, read their articles and realized how much they touched my life and helped me as a developer over the years. Even before I decided to join the team, I pinged some of the advocates and chat with them. They were so welcoming, happy to get to know me and got excited with me that I might be joining the team. They made me feel like “I should be part of it!”.
      • Microsoft Graph team was a team whom I followed their work from Channel9 since my MSP days. During my interview process, I got so excited to meet them in person. I have been collaborating with some colleagues from Microsoft Graph team due to my customer projects (Bots, web apps, mobile apps etc.). So, the idea of working with them was the biggest excitement!
    • Collaboration
      • Being a part of the developer community is the greatest feeling for me. Sharing my stories, projects, collaborating with the community, learning from them and supporting each other are the things I will continue doing regardless of my job. My admiration to the Advocacy team is that they are active members of the dev community and supporting the community with their day to day work. I am so excited to be part of this!
    • Learning
      • I am a passionate person about learning new things. It is like having breakfast every morning for me. Without it, I don’t feel complete. There were times that I was so busy working, didn’t have much time for learning anything new. Maybe, I couldn’t prioritize it, or I was so focused on being an expert on one particular area. But lesson learned.
      • Today, with this new journey, I am given a great opportunity to learn, create and share with the community. I know, it will be an amazing experience!

    Note to young self:
    If you believe in yourself, people will believe in you.

    Never hesitate.

    -Ayça

  • Microsoft Teams Toolkit: Setup and Overview

    Recently, an amazing Visual Studio Code extension Microsoft Teams Toolkit has been released for developers who are willing to build apps for Microsoft Teams. It is easier and faster to build bots, tabs or messaging extensions with Microsoft Teams Toolkit that provides developers to create, debug and deploy Teams apps directly from Visual Studio Code.

    Microsoft Teams Toolkit Extension

    If you are interested in building apps for Microsoft Teams, simply you can go to Visual Studio Code Extensions tab, and install Microsoft Teams Toolkit extension.

    After a successful installation of Microsoft Teams Toolkit extension, Microsoft Teams icon will appear in the activity bar.

    When you click on Microsoft Teams icon in the activity bar, you can direct to Open Microsoft Teams Toolkit for getting a guidance and documentation about setting up your environment, building an app or publishing your app to Microsoft Teams. Each step redirects to the related official documentation.

    To create a new Teams app, click on Create a new Teams app, give a name to your project and choose the capability you wish to create.

    Microsoft Teams Toolkit provides Tabs, Bots and Messaging Extensions as types of Teams apps.

    After creating any type of Teams app, our project is ready for development, debugging and publishing. ( .publish folder will be generated automatically under the project folder and manifest.json will be available for testing on Microsoft Teams App Studio. )

    In addition to creating Teams apps from scratch, we can also import a current app package and edit app package from Visual Studio Code.

    Microsoft Teams Toolkit is a very practical extension that helps us avoiding multiple manual steps while building applications for Microsoft Teams. Next, we will be exploring how to build Teams apps and run it on Microsoft Teams.

    Feel free to share your thoughts about Microsoft Teams Toolkit extension in the comment window.

    Cheers!

  • Microsoft Graph Toolkit: where to get started?

    If you are a starter and willing to learn more about Microsoft Graph Toolkit, you are in the right place! Before we jump into a long run project, we will discover Microsoft Graph Toolkit and find answers to the following questions:

    • What is Microsoft Graph Toolkit?
    • What is in Microsoft Graph Toolkit?
    • Where to get started?

    Today, our focus will be understanding the basics. But, If you are interested in building an overall solution, check out this post: Microsoft Graph Toolkit: gather together your Office 365 in one app.

    What is Microsoft Graph Toolkit?

    It is a powerful collection of reusable web components and providers that enables accessing Microsoft 365 data. It makes Microsoft Graph easy to use in your application. For instance, we can implement login and tasks with just two lines of code by using Login and Tasks components.

    Microsoft Graph Toolkit Playground: mgt.dev

    The Microsoft Graph Toolkit is great for developers of all experience levels. All components work fluently with all modern browsers and web frameworks (React, Angular, Vue, etc.).

    What is in Microsoft Graph Toolkit?

    Components: a collection of web components powered by Microsoft Graph APIs

    Note: The components work best when used with a provider.

    ComponentHTML
    Login
    Person
    People
    Agenda
    Tasks
    People picker
    Person card
      

        (Hover on person to view Person Card)
      
    Get
        ….
     
    Channel picker
    Providers: enable authentication and provide the implementation to get the access tokens for consuming Microsoft Graph APIs
    ProvidersHTML
    MsalSign in users and acquire tokens to use with Microsoft Graph.
    SharePointAuthenticates and provides Microsoft Graph access to components inside of SharePoint web parts.
    TeamsAuthenticates and provides Microsoft Graph access to components inside of Microsoft Teams tabs.
    ProxyAllows the use of backend authentication by routing all calls to Microsoft Graph through your backend.
    CustomCreate a custom provider to enable authentication and access to Microsoft Graph with your application’s existing authentication code.

    Where to get started?

    1. The Playground

    Microsoft Graph Toolkit Playground is definitely a great tool for starters who wants to try out components and learn more about the capabilities of each component. It is quite helpful for discovering the components edge to edge before trying them out in a custom application. Highlights of the Playground:

    • Canvas is the place for testing the components, checking the visual results and customizing UI as our wishes.
    • Docs is the place where we can check the attributes, properties, events, css and stories for each component.
    • Finally, don’t forget to check Samples in the Playground, there are many templates available and ready to use!
    2. Repository

    Microsoft Graph Toolkit provides a rich repository with Angular, ASP.NET Core, React and many more other samples available. If you are looking for some sample solutions, Microsoft Graph Toolkit Repository is the great place to start exploring.

    3. Docs

    Here is the official documentation of the Microsoft Graph Toolkit.

    Let me know about your experience with Microsoft Graph Toolkit. Furthermore, If you would like to build a solution from scratch with the power of Microsoft Graph Toolkit, check out this post: Microsoft Graph Toolkit: gather together your Office 365 in one app.

    Cheers!

  • Microsoft Graph Toolkit: gather together your Office 365 in one app

    Hey there! Today, we will work on an ASP.NET Core MVC web app with the power of Microsoft Graph Toolkit. Our purpose is to enable:

    • Microsoft identity platform authentication
    • the agenda from Outlook Calendar
    • the tasks from Planner
    • e-mails from Outlook

    If you never heard of Microsoft Graph Toolkit before, it is a powerful collection of reusable web components that enables accessing Microsoft 365 data with just couple lines of code! Believe it or not, Microsoft identity platform authentication can be implemented in seconds.

    This web app will be a quick scenario to try out Microsoft Graph Toolkit!

    You can get the source code from here .


    Create ASP.NET Core MVC web app in Visual Studio Code

    • Open the Terminal in Visual Studio Code (Ctrl+Shift+`)
    • Then, create a new folder for the project
    PS C:\Users\user> cd Desktop
    PS C:\Users\user\Desktop> mkdir GraphToolkitNetCore
    • Create ASP.NET Core MVC app
    PS C:\Users\user\Desktop> dotnet new mvc
    PS C:\Users\user\Desktop> cd GraphToolkitNetCore
    • The app is created successfully! Now, click on “Open Folder” to open your project folder.
    • Press F5 to run the project
    • Our project is working fine. Before we start building our app with Microsoft Graph Toolkit, let’s go to Properties > launchSettings.json and set http://localhost:8080to applicationUrl

    Register an app in Azure Active Directory

    • First thing first, go to Azure Portal
    • Under Azure Active Directory, go to App Registration and click on New Registration
    • Give a name to your app
    • Choose the access level
    • Choose Web and place http://localhost:8080 as a Redirect URI
    • Go to Authentication tab
    • Then, check Access tokens and ID tokens
    • Finally, go to Overview tab
    • Copy Application (client) ID to a notepad, we will need it later

    Setup Index.cshtml

    • Go to Index.cshtml and add a row and three columns inside the row
    • Copy below additional css to site.css under wwwroot>site.scs
    /* Main content */
    #content, html, body {
      height: 98%;
    }
    #one {
      float: left;
      width: 33%;
      background:transparent;
      height:500px;
      overflow: hidden;
    }
    #one:hover {
      overflow-y: auto;
    }
    #two {
      float: middle;
      width: 33%;
      background: transparent;
      height: 500px;
      overflow: hidden;
    }
    #two:hover {
      overflow-y: auto;
    }
    #three {
      float: left;
      width: 33%;
      background: transparent;
      height: 500px;
      overflow: hidden;
    }
    #three:hover {
      overflow-y: auto;
    }
    /*Email*/
    .email {
      box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
      padding: 10px;
      margin: 8px 4px;
      font-family: Segoe UI, Frutiger, Frutiger Linotype, Dejavu Sans, Helvetica Neue, Arial, sans-serif;
    }
    .email:hover {
      box-shadow: 0 3px 14px rgba(0, 0, 0, 0.3);
      padding: 10px;
      margin: 8px 4px;
    }
    .email h3 {
      font-size: 12px;
      margin-top: 4px;
    }
    .email h4 {
      font-size: 10px;
      margin-top: 0px;
      margin-bottom: 0px;
    }
    .email mgt-person {
      --font-size: 10px;
      --avatar-size-s: 12px;
    }
    .email .preview {
      font-size: 13px;
      text-overflow: ellipsis;
      word-wrap: break-word;
      overflow: hidden;
      max-height: 2.8em;
      line-height: 1.4em;
    }
    a.navbar-brand {
      white-space: normal;
      text-align: center;
      word-break: break-all;
    }
    

    Let’s start working with Microsoft Graph Toolkit

    Login

    • Go to Home>Index.cshtml
    • Implement MSAL provider in Index.cshtml
    • Make sure it is placed under the welcome message
    https://unpkg.com/@@microsoft/mgt/dist/bundle/mgt-loader.js
    
    
    • Paste Application (client) ID that you copied earlier from Azure Active Directory
    • Press F5 to run your application
    • Click on sign in button and login with your account
    • Accept to permission request
    • When the authentication is completed, you should see your details in the page

    Get E-mails

    • Use mgt-get to get user’s e-mails. Implement below code as column 1 in Index.cshtml
           
    
         
            
          
          loading
          {{ this }} 
      
    
    • Press F5 to run the app, you should be able to see the emails

    Agenda

    • Use mgt-agenda to get a user or group calendar. Implement below code as column 2 in Index.cshtml
    
    
    
    
    
    • Then, press F5 to run the app. You should be able to see the agenda on the right side of the e-mails

    Tasks

    • Use mgt-tasks to get a user or group calendar. Implement below code as column 3 in Index.cshtml
    
    
    
    
    
    • Press F5 to run the app, you should be able to see the tasks on the right side of the agenda

    Final version of Index.cshtml will look like below:

    @{
        ViewData["Title"] = "Home Page";
    }
    
    
    loading {{ this }}

    Our app is ready! As a result, we have our e-mails, agenda and tasks in one place. I hope you enjoyed using Microsoft Graph Toolkit. You can get the source code from here.

    Let me know about your experience or if you have any feedback!

    If you are interested in learning more about Microsoft Graph, check out the related posts.

  • Build PowerApps in a couple of minutes to impress friends and family!

    Yesterday, my friends were coming over for dinner. I wanted to make it very special for them, so I planned to cook amazing Turkish dishes that they have never tried before. Let me be very honest with you, cooking 5 different dishes was not easy at all. Then, why not go one step further and create a dinner menu for them, so they taste the complete Turkish Restaurant vibe 🙂 (Such a great excuse to deep dive into PowerApps!)

    If you are searching for quick ways to build a mobile/tablet app, PowerApps is the answer! I spent only couple of minutes to build this dinner menu app and everyone was so surprised, loved it, felt very special! I shared all the details about how to build a Power App in couple of minutes to impress friends and family. Try and let me know about the results.

    Build PowerApps with no code

    Go to PowerApps website and create Canvas app from blank.

    Give a name to your app and choose Phone as a format.

    Welcome Page

    Let’s rename Screen1 as Welcome Page.

    Start designing the page by choosing required properties under Insert tab. I will insert below items:

    • Text Label: Welcome message
    • Text Label: Description for the guests
    • Button: Navigation to the Menu Page
    • Text Label: My name as a footer

    Click on the first Text Label and edit settings from the panel on the right side. You can rename Label1 as Welcome Label by clicking edit icon on the right side.

    • Text (Double-click to edit on the panel): Hoşgeldiniz (Welcome in Turkish)
    • Font: Dancing Script
    • Font size: 50
    • Font wight: Bold
    • Text alignment: Align Center
    • Size Width: 560
    • Size Height: 90
    • Color: Custom (Hex: D4AF37)

    Then, the second Text Label and edit settings from the panel on the right side. You can rename Label2 as Description Label by clicking edit icon on the right side.

    • Text (Double-click to edit on the panel): Welcome my lovely friends! :)Get ready for a wonderful …..
    • Font: Open Sans
    • Font size: 26
    • Font weight: Normal
    • Text alignment: Align Center
    • Position X: 40
    • Position Y: 160
    • Size Width: 560
    • Size Height: 775
    • Color: Dark Grey
    • Border style: Solid
    • Border thickness: 2
    • Border Color: Custom (Hex: D4AF37)

    Next, go to Button and edit settings from the panel on the right side. You can rename Button1 as Menu Button by clicking edit icon on the right side.

    • Text: View Menu
    • Position X: 180
    • Position Y: 895
    • Size Width: 280
    • Size Height: 70
    • Color: White
    • Color Fill: Custom (Hex: D4AF37)

    Finally, the third Text Label and edit settings from the panel on the right side. You can rename Label3 as Footer Label by clicking edit icon on the right side.

    • Text: Chef: Ayça Baş
    • Font: Dancing Script
    • Font size: 30
    • Font weight: Bold
    • Text alignment: Align Center
    • Position X: 40
    • Position Y: 995
    • Size Width: 560
    • Size Height: 125
    • Color: Custom (Hex: D4AF37)
    Menu Page

    Let’s create a new screen for the menu. Choose Blank template and rename it as Menu Page.

    Before we start designing the Menu Page, let’s create the navigation from Welcome Page Menu Button.

    Click on View Menu button and go to Advanced tab. To enable navigation, insert below script under OnSelect action:
    Navigate(‘Menu Page’)

    Design the page by choosing required properties under Insert tab. I will insert below items.

    • Back Arrow: Navigation to the Welcome Page
    • Text Label: Title
    • Text Label: Header
    • Text Label: Description

    First of all, click on Back arrow and edit properties from the panel on the right side. You can rename Arrow1 as Back Button by clicking edit icon on the right side.

    • Position X: 40
    • Position Y: 25
    • Size Width: 65
    • Size Height: 65

    For the navigation, go to Advanced tab and insert below script under OnSelect action:
    Navigate(‘Welcome Page’)

    Secondly, click on the first Text Label and edit settings from the panel on the right side. You can rename Label4 as Menu Title Label by clicking edit icon on the right side.

    • Text: Menu
    • Font: Dancing Script
    • Font size: 50
    • Font wight: Bold
    • Text alignment: Align Center
    • Position X: 0
    • Position Y: 0
    • Size Width: 640
    • Size Height: 120
    • Color: White
    • Color Fill: Custom (Hex: D4AF37)

    Then, the second Text Label and edit settings from the panel on the right side. You can rename Label5 as Header Label by clicking edit icon on the right side.

    • Text: Appetizers
    • Font: Dancing Script
    • Font Size: 40
    • Font Weight: Bold
    • Font Style: Underline
    • Text alignment: Align Center
    • Position X: 0
    • Position Y: 195
    • Size Width: 640
    • Size Height: 65
    • Color: Dark Grey

    Finally, the third Text Label and edit settings from the panel on the right side. You can rename Label6 as Dish Description Label by clicking edit icon on the right side.

    • Text: Zeytinyağlı Biber Dolması
    • Font: Open Sans
    • Font Size: 25
    • Font weight: Normal
    • Text alignment: Align Center
    • Position X: 0
    • Position Y: 270
    • Size Width: 640
    • Size Height: 45
    • Color: Dark Grey

    Go to Advanced tab and insert below script under OnSelect action to enable redirect link: Launch(“https://en.wikipedia.org/wiki/Dolma”)

    Add couple of more header labels and dish description labels. Repeat the same steps on above until you build the complete menu.

    For both pages, click on any empty space of the page and go to Properties tab on the right side. You can either change the background color or add a background image. I will choose one of images on my desktop for the final look of my app and choose Image Position as Fill.

    Don’t forget to save and publish your app. You can also share your app with friends, family and colleagues via e-mail. Let me know if your guests like it! 🙂

    Finally, our app is ready! PowerApps is always the quick solution for such scenarios. If you are interested in learning more about Power Platform, check out the related posts.

    Cheers!

  • Microsoft Graph API Custom Connector for Power BI

    Hello there, developers! Today, we will build Microsoft Graph API custom connector for Power BI by using M Language. For those who have never heard M Language before, here is a quick ramp-up video:

    Deep Dive into the M Language

    In this scenario, our purpose is to build a custom connector to get Office 365 data via Graph API and use it as a data model in Power BI. So, we will be focusing on getting Microsoft Teams’ all provisioned team list with members through the connector.

    Lets start with pre-requisites

    Create AAD Registered Graph Application

    Login Azure Portal and go to Azure Active Directory on the left side of the menu, then select App registrations and create New registration.

    Give a name to your app, select preferred supported account type for your organization.
    Make sure to select Public client/native (mobile/desktop) for Redirect URI and place the following redirect URL: “https://oauth.powerbi.com/views/oauthredirect.html“, then click register.

    Once our app is registered, go to API Permissions > Add a permission and choose Microsoft Graph.

    Select below permissions below for both Delegated Permissions and Application Permissions:

    User.Read
    User.Read.All
    User.ReadWrite.All
    Group.Read.All
    Group.ReadWrite.All

    Then, click Grant Admin Content for -your organization-.

    Finally, go to Overview from the left side of the menu and copy Application (client) ID to a notepad. We will need this id later.

    Build the connector

    After successfully registering the app in Azure Active Directory, we are ready to create a Data Connector Project in Visual Studio.

    • Add Registered App Client ID in MyGraphConnector project

      As you already copied your Application (Client) ID to a notepad, go ahead and save it as client_id.txt file.
      Add your existing client_id.txt file in MyGraphConnector project, rename and remove txt extension from the file name.
      Finally, click on client_id and change the Build Action setting from Properties as Compile.

    • Configure OAuth for Graph API in MyGraphConnector.pq

      Let’s set the variables first:
    section MyGraphConnector;
    // TODO: make sure to set AAD client ID value in the client_id file
    client_id = Text.FromBinary(Extension.Contents("client_id")); 
    redirect_uri = "https://oauth.powerbi.com/views/oauthredirect.html";
    token_uri = "https://login.microsoftonline.com/organizations/oauth2/v2.0/token";
    authorize_uri = "https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize";
    logout_uri = "https://login.microsoftonline.com/logout.srf";
    windowWidth = 720;
    windowHeight = 1024;

    Define Registered App scope:

    scope_prefix = "https://graph.microsoft.com/";
    scopes = {
       
        "Group.Read.All",
        "Group.ReadWrite.All",
        "User.Read",
        "User.Read.All",
        "User.ReadWrite.All"
      
    };
    Value.IfNull = (a, b) => if a  null then a else b;
    GetScopeString = (scopes as list, optional scopePrefix as text) as text =>
        let
            prefix = Value.IfNull(scopePrefix, ""),
            addPrefix = List.Transform(scopes, each prefix & _),
            asText = Text.Combine(addPrefix, " ")
        in
            asText;

    OAuth Implementation:

    // StartLogin builds a record containing the information needed for the client
    StartLogin = (resourceUrl, state, display) =>
        let
            authorizeUrl = authorize_uri & "?" & Uri.BuildQueryString([
                client_id = client_id,  
                redirect_uri = redirect_uri,
                state = state,
                scope = "offline_access " & GetScopeString(scopes, scope_prefix),
                response_type = "code",
                response_mode = "query",
                login = "login"
            ])
        in
            [
                LoginUri = authorizeUrl,
                CallbackUri = redirect_uri,
                WindowHeight = 720,
                WindowWidth = 1024,
                Context = null
            ];
    // FinishLogin is called when the OAuth flow reaches the specified redirect_uri. 
    FinishLogin = (context, callbackUri, state) =>
        let
            // parse the full callbackUri, and extract the Query string
            parts = Uri.Parts(callbackUri)[Query],
            // if the query string contains an "error" field, raise an error
            // otherwise call TokenMethod to exchange our code for an access_token
            result = if (Record.HasFields(parts, {"error", "error_description"})) then 
                        error Error.Record(parts[error], parts[error_description], parts)
                     else
                        TokenMethod("authorization_code", "code", parts[code])
        in
            result;
    // Called when the access_token has expired, and a refresh_token is available.
    Refresh = (resourceUrl, refresh_token) => TokenMethod("refresh_token", "refresh_token", refresh_token);
    Logout = (token) => logout_uri;
    // code:       Is the actual code (authorization_code or refresh_token) to send to the service.
    TokenMethod = (grantType, tokenField, code) =>
        let
            queryString = [
                client_id = client_id,
                scope = "offline_access " & GetScopeString(scopes, scope_prefix),
                grant_type = grantType,
                redirect_uri = redirect_uri
            ],
            queryWithCode = Record.AddField(queryString, tokenField, code),
            tokenResponse = Web.Contents(token_uri, [
                Content = Text.ToBinary(Uri.BuildQueryString(queryWithCode)),
                Headers = [
                    #"Content-type" = "application/x-www-form-urlencoded",
                    #"Accept" = "application/json"
                ],
                ManualStatusHandling = {400} 
            ]),
            body = Json.Document(tokenResponse),
            result = if (Record.HasFields(body, {"error", "error_description"})) then 
                        error Error.Record(body[error], body[error_description], body)
                     else
                        body
        in
            result;

    Graph API Connector Implementation:

    //Graph API URL to get all provisioned team list with members 
    url= "https://graph.microsoft.com/beta/groups?$expand=members&$filter=resourceProvisioningOptions/Any(x:x eq 'Team')";
    //
    // Exported function(s)
    //
    [DataSource.Kind="MyGraphConnector", Publish="MyGraphConnector.UI"]
    shared MyGraphConnector.Feed = () =>
        let
            source = OData.Feed(url, null, [ ODataVersion = 4, MoreColumns = true ])
          
          in
            source;
      
    //
    // Data Source definition
    //
    MyGraphConnector = [
        TestConnection = (dataSourcePath) => { "MyGraphConnector.Feed" },
        Authentication = [
            OAuth = [
                StartLogin=StartLogin,
                FinishLogin=FinishLogin,
                Refresh=Refresh,
                Logout=Logout
            ]
        ],
        Label = "My Graph Connector"
    ];
    //
    // UI Export definition
    //
    MyGraphConnector.UI = [
        Beta = true,
        ButtonText = { "MyGraphConnector.Feed", "Connect to Graph" },
        SourceImage = MyGraphConnector.Icons,
        SourceTypeImage = MyGraphConnector.Icons
    ];
    MyGraphConnector.Icons = [
        Icon16 = { Extension.Contents("MyGraphConnector16.png"), Extension.Contents("MyGraphConnector20.png"), Extension.Contents("MyGraphConnector24.png"), Extension.Contents("MyGraphConnector32.png") },
        Icon32 = { Extension.Contents("MyGraphConnector32.png"), Extension.Contents("MyGraphConnector40.png"), Extension.Contents("MyGraphConnector48.png"), Extension.Contents("MyGraphConnector64.png") }
    ];
    

    • Update MyGraphConnector.query.pq
    MyGraphConnector.Feed()

    • Run the project

    Run the application in Debug mode. You should be able to receive below app:

    Select your Credential Type as OAuth2, and paste your accessToken for the login url https://login.microsoftonline.com/organizations/oauth2/v2.0/token. (To learn how to get accessToken: https://docs.microsoft.com/en-us/graph/auth-v2-user)

    Click Login, then type your credentials. After the successful login, click on Set Credential. You can go to Credentials tab to check if your credentials set properly.

    Finally, press CTRL + F5 to get the data with connector.

    • Create MyGraphConnector.mez package

      If your app is successfully getting the data as above, let’s run the project in Release mode to create release package.

    Copy your MyGraphConnector.mez from
    [Your Project Folder]\MyGraphConnector\MyGraphConnector\bin\Release.

    Paste it under
    C:\Users\[Your User Name]\Documents\Power BI Desktop\Custom Connectors.

    Test your connector in Power BI Desktop

    Open your Power BI Desktop and select Get Data, click More. MyGraphConnector.Feed (Beta) should appear under Online Services. Select and connect.

    Sign in with your credentials and connect.

    All provisioned teams list with members should appear in Power BI as data table.


    Below is the list of all properties we are able to get with the following Graph API:

    graph.microsoft.com/beta/groups?$expand=members&$filter=resourceProvisioningOptions/Any(x:x eq ‘Team’)


    You can get the source code from here: https://github.com/aycabas/Graph-API-Custom-Connector. I hope you find the post useful. Let me know about your experience, share your questions and comments below.

    Cheers!

  • How to get Microsoft Teams call quality data from Power BI?

    I often get this question these days during Covid-19. We all have the same situation, whatever is our job, we are at home trying to work as efficient as possible to make sure that everything is on track. Business continues virtually, so is the education! The new way of things work brought us new kind of challenges such as auditing and monitoring the meetings. Most of our workspace activities (chatting, meeting, screen sharing, file sharing etc.) are running on Microsoft Teams now, often company’s departments responsible of auditing are looking for solutions to get more data from Microsoft Teams.

    To help addressing many of the questions, Microsoft released Call Analytics and Call Quality Dashboards (CQD).

    Call Analytics is available in the Microsoft Teams admin center to see detailed information about the devices, networks, and connectivity related to the calls and meetings for each user in a Microsoft Teams tenant account.
    Call Quality Dashboard data is available with many dimensions and measurements to analyze and customize on Power BI with a provided connector and templates. All we need to do is:

    1. Download Power BI query templates for Microsoft CQD from GitHub here.
    2. Create a new folder called “Power BI Desktop under Documents folder.
    3. Create a new folder called “Custom Connectors” under Power BI Desktop folder. Final destination should be Documents\Power BI Desktop\Custom Connectors.
    4. Extract CQD-Power-BI-query-templates.zip and copy MicrosoftCallQuality.pqx under Documents\Power BI Desktop\Custom Connectors.

    Now, it’s time to enable custom connector extensibility settings in Power BI Desktop and run Call Quality Dashboards.

    Developers like us can enable new data sources with custom data extensions called custom connectors.  To be able to use non-certified custom connector, Data Extensions settings should be enabled to allow any extension to load.

    In Power BI Desktop, select File > Options and settings > Options > Security.

    Under Data Extensions, select (Not Recommended) Allow any extension to load without validation or warning

    Select OK, and then restart Power BI Desktop.

    When Power BI Desktop restarted, click on “Get Data” and Select “More.”

    Microsoft Call Quality Connector should appear under Online Services.

    Select “Microsoft Call Quality (Beta)” and click Connect.

    Microsoft Call Quality Connector requires Azure Active Directory Global Admin Consent to retrieve the data from tenant.

    Login with a Global Admin account and admit the consent.

    After the login, click connect and select connection settings as DirectQuery.

    As a result, you will see long list of data under the fields. Select any field, drag and drop to the page to test the data. Feel free to build your own dashboard by adding some visualizations.

    You may also leverage from the built-in dashboards available under CQD-Power-BI-query-templates.zip.

    Feel free to test any of the dashboards listed above.

    Make sure to edit permissions by clicking Data source settings under Transform Data and sign in with your global admin account.

    CQD Teams Utilization Report is shown below as an example.

    Call Quality Dashboards are quite useful for tracking call counts per month/day, even drilling down by conference or user for more information. Also, it is easy to customize if you are looking for something different.

    Keep in mind that CQD is to get more insights about the calls, so it doesn’t contain Microsoft Teams details for tenant such as team names, member/owner names, policy information etc. To get Microsoft Teams tenant data and use it in Power BI, we will need to build our own custom connector by using Microsoft Graph API. I will create a separate post to walk you through on that.

    I hope you enjoy reading the post. Looking forward to get your comments.

    Cheers!

  • Build AI-powered virtual assistant for healthcare with almost no code!

    Have you ever heard about the Microsoft Healthcare Bot service that provides AI-based virtual assistance to support healthcare organizations? If yes, you already knew how easy it is to build and deploy the service with minor customization to adapt in your organization. In fact there is no doubt, it was the rescue for many scenarios during Covid-19 outbreak where many of us still benefit from it when we need quick answers to our questions about our health conditions. Well, If you never heard of Microsoft Healthcare Bot service before, I am here to take you through the hints that you would take a look before you go ahead and try the service.

    1. What is the Microsoft Healthcare Bot service exactly?
      It’s a chatbot which has built-in healthcare intelligence with a language understanding model based in medical terminology. Let’s drill down a little bit! It means that we don’t need to build the entire medical content in AI service, it comes with an industry knowledge which can serve millions of users at once.
    2. How can I build the conversation flow the way I want?
      Healthcare Bot Service provides a Management Portal where you can build your conversations with “no code”. You can create new dialogs, drag and drop to the editor to build the dialog flow and customize it however you want!

      undefined
    3. Where can I start?
      Visit Azure Portal and Create your first the Healthcare Bot.

      undefined

      Check out Healthcare Bot Service Management Portal and build your first scenario by using drag and drop scenario editor.

      undefined

    Go ahead and try the service in couple of minutes and share your experience with the community! Feel free to ask your questions under the post. Let’s discuss what went well, what didn’t go well.