Recently customer approached me to build “Microsoft Teams” approval workflow. Their IT support was overwhelmed with requests to create new Microsoft Teams and decided to automate the process. Here’s the breakdown of requirements
- To get Microsoft Teams created for User, they need to fill basic form with questions like Teams name, owner etc and submit the request.
- Admin will receive the request and can approve/reject it.
- Admin could also override some of the user provided information before approving the request.
- If request is approved Microsoft Teams instance will be created automatically and user will be notified.
- Admin needs to provide valid reason if they choose to reject and user will be notified with reason.
I decided to build workflow using Azure Logic Apps and Azure Function. While most part is simple to automate, the challenge was to create an HTML form that could be served via Logic Apps.
Please note: Since the purpose of this blog is to show how HTML forms can be served via Logic Apps, I will only be discussing the high level approach and will not go into details of other parts.
Microsoft Forms
First of all I decided to use Microsoft Forms to collect user input.
Azure Logic Apps
Azure Logic Apps is a great way to automate business workflows. You get 100s of connectors to integrate with external services and services within Azure. Taking user input on Microsoft Forms and kicking Logic Apps workflow was simple but creating custom HTML form served via logic app where Admins could approve/reject or override the request was a challenge. Here’s what I did to achieve this. I created 2 Logic Apps to complete this workflow. Lets call them Logic App “A” & “B”.
Logic App A
Logic App A is triggered as soon as user submits Microsoft Form as you can see below. You can consider this main workflow.
This workflow has important task to trigger Logic App B (discussed below) using webhook action. This workflow will pass following parameters to Logic App B.
- “formid” – user submitted form Id
- “url” – “callback” url for this webhook action
- “sendemail” – To notify second logic app to send email to admin.
When Logic App A is triggered this workflow stops at webhook action and awaits until Logic App B will callback.
Logic App B
Logic App B is Http triggered and is used to accomplish 2 tasks (only one at a time)
- To Notify Admin of new request via email . This flow is triggered by Logic App A as discussed above. [Parameter is set “sendemail=yes”]
- This Logic App will also be used to serve HTML form when Admin clicks the hyperlink sent in email. [Parameter is set “sendemail=no”]
Logic App B receives parameters (“formid” , “sendemail” and “url”) and save them into variables. Callback url is very important and represents the webhook action from Logic App A.
Since query string parameter “sendemail=yes” (as mentioned above),this workflow notify Admin that new request is submitted and Logic App B workflow completes.
If you notice in image above there is hyper link in Email “Click here to approve or reject”. Clicking this link will drop admin on HTML page. This HTML page is served by Logic App B. Basically clicking the hyperlink runs the workflow again but this time “SendEmail=no” so no email is sent , and workflow only displays the HTML form as shown below. This form will display answers from user who originally submitted the request.
Construct HTML form in Logic App B
Serving the HTML form via Logic App is the meat of this whole workflow. At the very last step on Logic App B I have HTTP response action that contains HTML form. Whenever Logic App B is triggered via email link (or simply copy pasting HTTP url of this logic app in browser) this form is served to the browser.
I copied the HTML in Notepad and you can see this is a standard HTML form. If you remember in the query string parameters we received “formId” from Logic App A, I used this “formId” in earlier steps to extract user answers (from Microsoft Forms) and filled the variables . In the last step I am using same variables to display user input for admin to view (highlighted below)
In the same HTML page I am using jQuery to validate HTML input fields and using Ajax to submit the request. Now you would be wondering where do we submit this request ? If you remember we received webhook url (callback) from Logic App A in the query string parameters, it’s the same callback url that I am using in ajax request.
As soon as the admin approve/reject the form , the form is submitted to webhook action in Logic App A which is still in awaiting state. Logic App A will continue with the data it received via form and will do either one of the following :
- If admin Approved the request , new Microsoft Teams instance is created and user is notified.
- If admin Rejected the request , User will be notified with rejection comments.
Below are some of the images from Logic App A when it continues after receiving Form data from Logic App B.