Power Apps – Express Design (Build an app in seconds) – Figma to app

figma to app

In continuation with our first series – Power Apps – Express Design (Build an app in seconds) – Image to app, let us see how Figma app works.

Figma is a vector graphics editor and prototyping tool which is primarily web-based, with additional offline features enabled by desktop applications for macOS and Windows. The Figma mobile app for Android and iOS allows viewing and interacting with Figma prototypes on real-time mobile devices.

Figma to App bridges that gap between design and development, with Figma to App designers and developers can collaborate together to build an optimal experience for the end-users.

As a designer, you will simply create your design using Figma and then you upload that Figma file to Power Apps which will be taking care of converting your design into a working app.

Without further ado, let’s jump into the action.

Design in Figma

1. Go to the www.figma.com and create an account, then on the left navigation menu click on Community and look for a template named NETFLIX (first prototype)


2. Click on Duplicate to load in the Designer tool – this is the place for all the customizations

3. Copy the URL from the URL Bar (see red circle in step 2 image).

4. Create a Figma personal access token using the following steps

  • On the Figma home page, click settings
  • Look for Personal access tokens, add a token description and create a new one
  • An important point to note is to copy the token
Figma settings
Personal access tokens

5. Go to Power Apps and create a Figma (preview) app

Figma (preview) app

And voila, once more – Power Apps has provisioned from Figma in a few minutes

Netflix by Power Apps

This is a huge productivity (design) saver that will allow businesses to roll out user-friendly, great-looking apps to their users in a short amount of time and effort.

API to app

At the time of writing this blog, the App-from-API feature is to be released in early July 2022.

Coming soon…

Power Apps – Express Design (Build an app in seconds) – Image to app

turn images and designs into apps using AI-powered express design

The need for Digitization is constantly growing and there are never enough resources (Cost-Scope-Schedule) to fulfil all the requirements, therefore Microsoft on 25th May during the recent Microsoft Build event, has introduced the “Express Design – Build an app in seconds” which is a new Power Apps features that accelerate the process for getting started by taking existing content (e.g.: a picture of your paper form, a screenshot of a design, a PPT, a PDF or a Figma design file) and converting them in working Power App with UI and data without requiring the maker to learn how to build an app.

This magic is done using Azure Cognitive Vision OCR model to recognize the text from your image as well as the Azure Computer Vision Object Detection model to recognize the controls on the image whether it’s a text input, a label or radio button, etc.

Azure Cognitive Vision OCR & Azure Computer Vision Object Detection model

After that, even though it’s optional, however, it’s recommended for you to set up the data through dataverse, so you will have your data stored in dataverse.

We have got three different options and we are going to see each one of them

  • Image to app
  • Figma to app
  • API to app

Image to app

Image to app

Let’s get started by building an Image to app

1. On Power Apps, click Create and select Image (preview)

Image (preview)

2. The Upload an image screen appears, where either you upload an image of your own or start with some sample images – in our case, let us upload the following Car Details Application Wireframe

Upload an image

Car Details Wireframe

3. After Azure identifies the component, tag and assign each component as per the requirements

Assign components

4. Next the system allows you to create a new table in Dataverse (recommended), or simply skip it for now.

5. In this step, map the column as per the required data type, review then create.

Columns mapping

And voila, in a few minutes – Power Apps has provisioned the app as per the given input!!!

Car details application

This is a whole new world of possibilities for the citizen developers, those architects or building technicians who are looking for a genuine alternative to building an app – truly it is Empowering every person and every business on the planet to achieve more.

Now, we are going to see how Figma to app works.

Team Collaboration on PowerApps


The much-awaited feature has finally come in Power Apps which allows a team to work simultaneously in one Power Apps application.

Forget now locked for editing message now – this sounds exciting, isn’t 😊

locked for editing

Together, we are going to create a sample app in Power Apps and enable the collaboration with Azure DevOps.

Without further ado, let’s get started with step-by-step instructions.

1. Create a Help Desk application

Let’s assume our organization is in need of a Help Desk application.

To make our life easier Microsoft has come with a plethora of templates ready to be provisioned, so let us build the application.

  • In Power Apps left navigation Menu, click on + Create
  • Locate Start from template, and look for Help Desk
  • Provide a meaningful name and click create
  • and voila, in less than a minute our app is ready to use
Help Desk

Now let’s say our Help Desk Admin needs to have a customized report for the respective technology stream in the organization – for example SAP Report, Microsoft Dynamics Report, etc – (please note that we will not be implementing any report in this blog, this would be out of scope).

To make it simpler, we will have 2 screens so each developer can work simultaneously on the same application.

Power Apps Developer Screen

2. Connect with Azure DevOps

2.1 What is DevOps?

It is a compound of development (Dev) and operations (Ops), DevOps is the union of people, processes and technology to continually provide value to customers.

2.2 What does DevOps mean for teams?

DevOps enables formerly siloed roles—development, IT operations, quality engineering and security—to coordinate and collaborate to produce better, more reliable products. By adopting a DevOps culture along with DevOps practices and tools, teams gain the ability to better respond to customer needs, increase confidence in the applications they build and achieve business goals faster.

2.3 The benefits of DevOps

Teams that adopt DevOps culture, practices and tools become high-performing, building better products faster for greater customer satisfaction. This improved collaboration and productivity are also integral to achieving business goals like these:

The benefits of DevOps

2.4 Login or Sign Up For A Free Azure DevOps Account

Login to dev.azure.com or sign up for a free account, we need it to setup a repository which we are going to see in the next steps.

Once logged in, create a New DevOps Project.

Create a New DevOps Project

Provide a Project Name.

Create a New DevOps Project

Click on Repos, then Initialize the repository.

Initialize the repository

2.5 Keep a note of the Azure DevOps Git Repository URL and Branch

It should be as follows:


for our case, it would be:


the branch name would be:


2.6 Create a DevOps Project Personal Access Token

A personal access token (PAT) as an alternate password to authenticate into Azure DevOps, it contains your security credentials for Azure DevOps. A PAT identifies you, your accessible organizations, and scopes of access. As such, they’re as critical as passwords, so you should treat them the same way.

In the DevOps Project, under the User Settings (top-right corner), click on Personal access tokens

Personal access tokens

Create a new personal access token

Personal access tokens

Make sure you copy the token and keep it securely

Personal access tokens

3. Connect Azure DevOps Git with Power Apps

It is time now to connect our application with the repository:

3.1 Enable the Git version control setting

In Power Apps, Go to File > Settings > Upcoming features and enable the Git version control setting:

Git version control setting

Once connected, click on the Git version control then connect.

Enter the value previously taken from the above step 2.5

Git version control setting

3.2 Sign in to your DevOps repository

Sign in to your DevOps repository using your DevOps username and your Personal Access Token – see step 2.6

Sign in to your DevOps repository

It creates a Directory for you if not found.

It creates a Directory for you if not found.

4 Collaborate with your team

4.1 Share the Help Desk app with your developer

It is time now to share and collaborate, for that we need to first share the app as co-owner

Share the Help Desk app with your developer

4.2 Login simultaneously to the app

Important note 1: we recommend closing and re-opening the main browser as it may result in an unwanted experience.

Important note 2: The second developer must login using his Active Directory Username and for the password use the Personal Token Access – see step 2.6

Share the Help Desk app with your developer

and voila, the second developer sees the same application and its artifacts.

Login simultaneously to the app

5 Commit changes and check for Git updates

Let’s say that the second developer (right screen) has to work on a Jira Report, therefore he adds the screen

Login simultaneously to the app

As his work is completed, he needs to commit so other developers can see his changes – this is done using the Sync button.

Commit changes and check for Git updates

Once committed, the other developers use the same button to sync the application and here is how it looks:

Login simultaneously to the app

5. Summary

This is a powerful and much-needed feature to deploy applications more quickly and seamlessly.

Additionally, Azure DevOps provide improved collaboration and productivity which lead to building better products faster for greater customer satisfaction.

Furthermore, this process allows the team to have complete code control such as code review, editing the code itself in a different application such as Visual Studio Code Editor, etc

Lastly, if you find this article useful, please share it with your friends. Every little bit helps. Thank you!

Convert Microsoft Office Documents into PDF using Microsoft Graph & Azure Functions

One of my recent task was to translate a word document into a pdf from a web application hosted in Azure Web App – therefore the code has to process at the Azure side.

Initially, I thought a traditional approach would work such as Interop or some free Api easily available on the net, however to my great surprise the code was throwing the following exception A generic error occurred in GDI+.

Exception handling in Net: Advanced exceptions | Hexacta

What I learned from this is that all Azure Web Apps (as well as Mobile App/Services, WebJobs, and Functions) run in a secure environment called a sandbox. Each app runs inside its own sandbox, isolating its execution from other instances on the same machine as well as providing an additional degree of security and privacy that would otherwise not be available. The sandbox mechanism aims to ensure that each app running on a machine will have a minimum guaranteed level of service; furthermore, the runtime limits enforced by the sandbox protect apps from being adversely affected by other resource-intensive apps which may be running on the same machine.

The sandbox generally aims to restrict access to shared components of Windows. Unfortunately, many core components of Windows have been designed as shared components: the registry, cryptography, and graphics subsystems, among others. For the sake of radical attack surface area reduction, the sandbox prevents almost all of the Win32k.sys APIs from being called, which practically means that most of User32/GDI32 system calls are blocked. For most applications, this is not an issue since most Azure Web Apps do not require access to Windows UI functionality (they are web applications after all). Since all the major libraries use a lot of GDI calls during the PDF conversion, the default rendering engine does not work on Azure Web Apps. You can find more information about those sandbox restrictions on https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox#win32ksys-user32gdi32-restrictions.

So now the solution is to find an approach to convert the PDF within Azure – luckily I came across a blog from Philipp Bauknecht which is leveraging Microsoft Graph to convert a document to PDF – let us see how.

There are several steps, which you have to perform in the correct order:

  1. Create an App registration in Azure AD and assign the required permissions
  2. Create a new Azure Functions app using Visual Studio 2019
  3. Create an OAuth2 authentication service to request an access token to call the Microsoft Graph
  4. Create a File Service to upload, convert and delete files using the Microsoft Graph
  5. Setup Dependency Injection
  6. Create a new function as the Main entry point
  7. Create a Function App in Azure to host the code and make it available globally
  8. Import the publish profile & deploy using Visual Studio 2019
  9. Test using a Console Application c#
  10. Test using Postman

Step 1: Create an App registration in Azure AD and assign the required permissions

1.1 Go to https://portal.azure.com, then Azure Active Directory and select App Registrations; Click on New registration, provide a name then click on Register

1.2 Once the app is provisioned, on the left navigation blade click on Certificates & secrets; Click on New client secret to create one, then save the value of the secret for later use.

1.3 Go to API permissions, then click on Add a permission then Microsoft Graph, then choose Application permissions to add the following permissions (Admin consent is a must):

1.4 Go to Overview and save the values of Application (client) Id and Directory (tenant) Id for later use.

Step 2: Create a new Azure Functions app using Visual Studio 2019

Open Visual Studio 2019 and Create a new project in which choose Azure Functions

Step 3: Create an OAuth2 authentication service to request an access token to call the Microsoft Graph

This class is responsible to get the access token.

using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;

namespace PdfConversionFunctionApp
    public class AuthenticationService
        public static async Task<string> GetAccessTokenAsync(ApiConfig _apiConfig)
            var values = new List<KeyValuePair<string, string>>
                new KeyValuePair<string, string>("client_id", _apiConfig.ClientId),
                new KeyValuePair<string, string>("client_secret", _apiConfig.ClientSecret),
                new KeyValuePair<string, string>("scope", _apiConfig.Scope),
                new KeyValuePair<string, string>("grant_type", _apiConfig.GrantType),
                new KeyValuePair<string, string>("resource", _apiConfig.Resource)
            var client = new HttpClient();
            var requestUrl = $"{_apiConfig.Endpoint}{_apiConfig.TenantId}/oauth2/token";
            var requestContent = new FormUrlEncodedContent(values);
            var response = await client.PostAsync(requestUrl, requestContent);
            var responseBody = await response.Content.ReadAsStringAsync();
            dynamic tokenResponse = JsonConvert.DeserializeObject(responseBody);
            return tokenResponse?.access_token;

Step 4: Create a File Service to upload, convert and delete files using the Microsoft Graph

This class is responsible to upload, convert and delete the file.

using Newtonsoft.Json;
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace PdfConversionFunctionApp
    public class FileService
        private readonly ApiConfig _apiConfig;
        private HttpClient _httpClient;

        public FileService(ApiConfig apiConfig)
            _apiConfig = apiConfig;

        private async Task<HttpClient> CreateAuthorizedHttpClient()
            if (_httpClient != null)
                return _httpClient;

            var token = await AuthenticationService.GetAccessTokenAsync(_apiConfig); 
            _httpClient = new HttpClient();
            _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");

            return _httpClient;

        public async Task<string> UploadStreamAsync(string path, Stream content, string contentType)
            var httpClient = await CreateAuthorizedHttpClient();

            string tmpFileName = $"{Guid.NewGuid().ToString()}{MimeTypes.MimeTypeMap.GetExtension(contentType)}";
            string requestUrl = $"{path}root:/{tmpFileName}:/content";
            var requestContent = new StreamContent(content);
            requestContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
            var response = await httpClient.PutAsync(requestUrl, requestContent);
            if (response.IsSuccessStatusCode)
                dynamic file = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
                return file?.id;
                var message = await response.Content.ReadAsStringAsync();
                throw new Exception($"Upload file failed with status {response.StatusCode} and message {message}");

        public async Task<byte[]> DownloadConvertedFileAsync(string path, string fileId, string targetFormat)
            var httpClient = await CreateAuthorizedHttpClient();

            var requestUrl = $"{path}{fileId}/content?format={targetFormat}";
            var response = await httpClient.GetAsync(requestUrl);
            if (response.IsSuccessStatusCode)
                var fileContent = await response.Content.ReadAsByteArrayAsync();
                return fileContent;
                var message = await response.Content.ReadAsStringAsync();
                throw new Exception($"Download of converted file failed with status {response.StatusCode} and message {message}");

        public async Task DeleteFileAsync(string path, string fileId)
            var httpClient = await CreateAuthorizedHttpClient();

            var requestUrl = $"{path}{fileId}";
            var response = await httpClient.DeleteAsync(requestUrl);
            if (!response.IsSuccessStatusCode)
                var message = await response.Content.ReadAsStringAsync();
                throw new Exception($"Delete file failed with status {response.StatusCode} and message {message}");

Step 5: Setup Dependency Injection

5.1 In order to use the FileService and the Configuration properties (local & in Azure), we need to set dependency injection. To use dependency injection in Azure Function app we need to add the package Microsoft.Azure.Functions.Extensions to our app using Nuget.

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using System.Reflection;

[assembly: FunctionsStartup(typeof(PdfConversionFunctionApp.Startup))]
namespace PdfConversionFunctionApp
    class Startup : FunctionsStartup
        public override void Configure(IFunctionsHostBuilder builder)
            var fileInfo = new FileInfo(Assembly.GetExecutingAssembly().Location);
            string path = fileInfo.Directory.Parent.FullName;
            var config = new ConfigurationBuilder()
                .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)

            var apiConfig = new ApiConfig();
            config.Bind(nameof(ApiConfig), apiConfig);


The above code – from line 15 to 25 – takes care of getting the configuration values, if the app runs locally then it loads the local.settings.json, otherwise, it takes the values from the Azure Function Application settings (see Step 7.2)

5.2 Now set the values of TenantId, ClientId & ClientSecret from Step 1; The SiteId correspond to the Document Library where the file will get temporarily uploaded, we will have to GET it using Microsoft Graph Explorer with the following formula:

This is how the local.settings.json looks:

GET => https://graph.microsoft.com/v1.0/sites/myorganization.sharepoint.com?$select=id
GET => https://graph.microsoft.com/v1.0/sites/myorganization.sharepoint.com:/sites/Contoso/Operations/Manufacturing?$select=id
Response => 
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites(id)/$entity",
    "id": "myorganization.sharepoint.com,74796aa9-17f6-4c09-9b20-1d78bfdcbac4,98f692fe-ea45-423b-8001-0b9c6bb2b50f"
What you get back in the id is in this format: {hostname},{spsite.id},{spweb.id}. 
What we need is then the {spsite.id} which is 74796aa9-17f6-4c09-9b20-1d78bfdcbac4
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "graph:Endpoint": "https://login.microsoftonline.com/",
    "graph:GrantType": "client_credentials",
    "graph:Scope": "Files.ReadWrite.All",
    "graph:Resource": "https://graph.microsoft.com",
    "graph:TenantId": "",
    "graph:ClientId": "",
    "graph:ClientSecret": "",
    "pdf:GraphEndpoint": "https://graph.microsoft.com/v1.0/",
    "pdf:SiteId": ""
  "ApiConfig": {
    "Endpoint": "https://login.microsoftonline.com/",
    "GrantType": "client_credentials",
    "Scope": "Files.ReadWrite.All",
    "Resource": "https://graph.microsoft.com",
    "TenantId": "",
    "ClientId": "",
    "ClientSecret": "",
    "GraphEndpoint": "https://graph.microsoft.com/v1.0/",
    "SiteId": ""

Step 6: Create a new function as the Main entry point

Add a new function to your project and name it ConvertToPdf. Select the Http trigger so our function can be called via a http request and pick Authorization level Anonymous so we don’t need to provide any credentials when calling this function; Replace the below code

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace PdfConversionFunctionApp
    public class ConvertToPdf
        private readonly FileService _fileService;
        private readonly ApiConfig _apiConfig;

        public ConvertToPdf(FileService fileService, ApiConfig apiConfig)
            _fileService = fileService;
            _apiConfig = apiConfig;

        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, ILogger log)
            if (req.Headers.ContentLength == 0)
                log.LogInformation("Please provide a file.");
                return new BadRequestObjectResult("Please provide a file.");

            var path = $"{_apiConfig.GraphEndpoint}sites/{_apiConfig.SiteId}/drive/items/";

            var fileId = await _fileService.UploadStreamAsync(path, req.Body, req.ContentType);

            var pdf = await _fileService.DownloadConvertedFileAsync(path, fileId, "pdf");

            await _fileService.DeleteFileAsync(path, fileId);

            return new FileContentResult(pdf, "application/pdf");

Step 7: Create a Function App in Azure to host the code and make it available globally

7.1 Go to https://portal.azure.com, then click on Create Function App

7.2 Once the app is provisioned, on the left navigation blade click on Configuration, then New application setting – we will have to add the below application settings which are needed when the app runs from Azure (the values as the same as step 5.2)

7.3 On the Overview section, download the publish profile while clicking on Get publish profile

Step 8: Import the publish profile & deploy using Visual Studio 2019

8.1 Right-click on Visual Studio, then choose Publish, import your publish settings to deploy your app from the file downloaded in the previous step – then deploy.

8.2 If Debugging is needed then we can use the Azure Function App Log Stream Monitoring features.

Step 9: Test using a Console Application c#

9.1 Create a console application and replace the following code.

using System;
using System.IO;
using System.Net;
using PdfConversionFunctionApp;

namespace PdfConversionConsoleApp
    class Program
        static void Main(string[] args)
            string filePathWord = @"C:\Temp\TestDocument.docx";
            string filePathOutWord = @"C:\Temp\TestDocument.pdf";

            string filePathExcel = @"C:\Temp\TestExcel.xlsx";
            string filePathOutExcel = @"C:\Temp\TestExcel.pdf";

            bool IsSuccessWord = ConverToPdf(filePathWord, filePathOutWord);
            bool IsSuccessExcel = ConverToPdf(filePathExcel, filePathOutExcel);

        private static bool ConverToPdf(String filePath, String filePathOut)
                //string urlLocal = "http://localhost:7071/api/ConvertToPdf";
                string urlAzure = "https://graphpdfconverter.azurewebsites.net/api/ConvertToPdf";

                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(urlAzure);
                req.Method = "POST";

                string fileExtension = Path.GetExtension(filePath);
                switch (fileExtension)
                    case ".doc":
                        req.ContentType = "application/msword";
                    case ".docx":
                        req.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
                    case ".xls":
                        req.ContentType = "application/vnd.ms-excel";
                    case ".xlsx":
                        req.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; ;
                        throw new Exception("Only Word & Excel documents are supported by the Converter");

                Stream fileStream = System.IO.File.Open(filePath, FileMode.Open);
                MemoryStream inputStream = new MemoryStream();
                Stream stream = req.GetRequestStream();
                stream.Write(inputStream.ToArray(), 0, inputStream.ToArray().Length);
                HttpWebResponse res = (HttpWebResponse)req.GetResponse();

                //Create file stream to save the output PDF file
                FileStream outStream = System.IO.File.Create(filePathOut);
                //Copy the responce stream into file stream
                //Dispose the input stream
                //Dispose the file stream

                return true;
            catch (Exception ex)
            return false;


9.2 To test and debug locally, Click F5 on the Function App – Visual Studio will provide a POST URL which you can use in the console to run & debug the code.

9.3 To run it from Azure, go to Azure Portal, then open your Azure Function App, on the left navigation blade click on Functions, click on the function name then Get Function Url. Use this URL in the console to convert the document to pdf.

It is important to mention that the Content Type will define the type of docunent to be converted – find the complete list of Common MIME types.

Step 10: Test using Postman

10.1 In Postman, add the Azure Function App Url (see step 9.3).

10.2 On the Header section, add the appropriate MIME Types

10.3 On the Body section, click on Binary and upload a file then click the Send button.

10.4 On successfull request, we can save the converted pdf file.


As we can see Microsoft Graph allows us to convert easily documents to pdf, that up to 1 million free calls, along with Azure Function it provides the flexibility to use these features anywhere anytime your users want.

Download the code from Github

The road ahead

Recently I came across Bill Gates’s first book – The Road Ahead – which he published twenty-five years ago, I was interested to read about the predictions which he made in this book such as:

  • The internet transformation – travelling back in time people were still navigating with paper maps, listened to music on CDs, watched movies on VHS tapes – today the adoption of digital technology to transform services or businesses has engaged billions of people – anytime, anywhere – with smarter experiences.
  • Digital agents or Virtual assistants – Alexa, Cortana, and Siri have already given birth, however, the visionary has envisioned a more powerful technology capable of learning human requirements and preferences in much the way that a human assistant does – grab this opportunity, it’s the equivalent of the goose that lays the golden egg.

It is great to see how technology is helping us in unprecedented progress on COVID-19 – for instance of the innovation on rapid tests, a British company LumiraDx has created a device that’s roughly the size of a thick cell phone, with a card reader at one end. A health care worker takes a sample from a patient, inserts it into the machine, and gets results within 15 minutes.

According to Schumpeter, the process of technological change in a free market consists of three parts: invention (conceiving a new idea or process), innovation (arranging the economic requirements for implementing an invention), and diffusion (whereby people observing the new discovery adopt or imitate it) – in layman’s terms, this means Schumpeter argued that anyone seeking profits must innovate.

Knowledge must be used because it multiplies by spending!