cancel
Showing results for 
Search instead for 
Did you mean: 
yashag2255

Microsoft Flow as a Service

In this blog, I will show how to create a flow that can be used as a service. We will create a customer request management service using Flow, SharePoint and a Web app. A user can create a new request through the page by entering the details and upload an attachment. A unique code is generated once the request is processed and the customer can track their request by entering this code and their email address.

The idea here is, a user is navigated to the contacts page to file/ get status of a request. The page has two tabs:

First: where they can create a new request by entering the name, email address, comments and attach an image file. There is a submit button that takes all these inputs and then sends a POST request to the Flow with all the inputs as a JSON body. These inputs are then parsed in Flow and an item is created in SharePoint. An acknowledgement email is sent to the user and an email with these details is sent to the concerned customer support department in the company. A unique code is generated and sent as a response that the user can view on the Contact page.

Second: takes the unique code and the email address of the user as inputs to get the request status from SharePoint through the Flow. These inputs are parsed in Flow and the relevant item is extracted from SharePoint and if the details match, the status is sent as a response to the web app and displayed to the user. If there is a mismatch, an error notification to enter correct details is displayed to the user.

Let’s get started.

Web App:

The web application is a simple app hosted in Azure. I created a basic ASP.NET application using Visual Studio and made some modifications to the Contacts.cshtml page.

I added a few input tags, buttons and added some javascript code to invoke the flows when the buttons are pressed.APiB1.PNG

Tab1: 

<div>You have reached the request page. If you have already placed a request, try the request tracker. If not create one here.</div>
<br />
<fieldset>
    <legend>Create a new request</legend>
    <br />
    Name :
    <input id="nameEntry" type="text" value="" style="Width:20%" />
    <br />
    Email :
    <input id="email" type="text" value="" style="Width:20%" />
    <br />
    Comments :
    <input id="comments" type="text" value="" style="Width:20%" />
    <br />
    Upload Image :
    <input id="file" type="file" name="pic" accept="image/*">
    <br />
    <button id="sub" name="temp" value="temp" onclick="userAction()">Submit Request</button>
    <br />
    <br />
    <span id="newReq"></span>
</fieldset>

Script to add an image file as an input to the first flow: Source

var tempFile
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        document.getElementById('file').addEventListener('change', handleFileSelect, false);
    }
    function handleFileSelect(evt) {
        var f = evt.target.files[0]; // FileList object
        var reader = new FileReader();
        // Closure to capture the file information.
        reader.onload = (function (theFile) {
            return function (e) {
                var binaryData = e.target.result;
                //Converting Binary Data to base 64
               tempFile = window.btoa(binaryData);
                //showing file converted to base64
            };
        })(f);
        // Read in the image file as a data URL.
        reader.readAsBinaryString(f);
    }

Script to invoke the first flow:

const userAction = async () => {
        var data = { name: document.getElementById('nameEntry').value, email: document.getElementById('email').value, comments: document.getElementById('comments').value, file: tempFile };
            const response = await fetch('https://prod-03.westus.logic.azure.com:443/workflows/keyinfo/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=keyinfo', {
                method: 'POST',
                body: JSON.stringify(data),
                headers: {
                    'Content-Type': 'application/json'
                }
            });
            const myJson = await response.text();
            document.getElementById("newReq").innerHTML = myJson;
        }

Tab 2:

<fieldset>
    <legend>Track a request</legend>
    <br />
    Email :
    <input id="emailReq" type="text" value="" style="Width:20%" />
    <br />
    Request Id :
    <input id="requestCode" type="text" value="" style="Width:20%" />
    <br />
    <button id="getreq" name="getRegq" value="GetReq" onclick="getreqs()">Get Status</button>
    <br />
    <span id="oldReq"></span>
</fieldset>

Scrip to invoke second flow:

const getreqs = async () => {
        var data = { emailID: document.getElementById('emailReq').value, reqNo: document.getElementById('requestCode').value };
            const response = await fetch('https://prod-11.westus.logic.azure.com:443/workflows/keyinfo/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=keyinfo', {
                method: 'POST',
                body: JSON.stringify(data),
                headers: {
                    'Content-Type': 'application/json'
            }
                });
            const myJson = await response.text();
            document.getElementById("oldReq").innerHTML = myJson;
        }

Flow:

There are two flows that we will be using here:

1. For new Requests:APiB2.PNG

Step-1: Trigger- When an HTTP request is received: Schema:

{
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        },
        "email": {
            "type": "string"
        },
        "comments": {
            "type": "string"
        },
        "file": {
            "type": "string"
        }
    }
}

To get the details from the requestor.

Step-2: Create item in the SharePoint List based on inputs received from the user. 

Step-3: Create the attachment received on the item created in the previous step.APiB3.PNG

Step-4: Send an email: send an email notification to the concerned department regarding the request that was created.

Step-5: Send an email: send an email notification to the user acknowledging the receipt of the request.

Step-6: Send a response: Send response to the app with the details of the request ID and successful filing of the request.

2. For existing Requests:APiB4.PNG

Step-1: Trigger: When an HTTP request is received: Schema:

{
    "type": "object",
    "properties": {
        "emailID": {
            "type": "string"
        },
        "reqNo": {
            "type": "string"
        }
    }
}

Step-2: Initialize a string variable: This gets the ID in string format from the request received. Expression:

last(split(tolower(triggerBody()?['reqNo']),'req'))

Step-3: Get Item from SharePoint: To get the request details from SharePoint. Expression:

int(variables('id'))

 

APiB5.PNG

Step-4: Condition Control: To check if the user has input the correct email address. 

//Yes Branch

Send response along with the request details.

//No Branch

Send error notification.

//End condition

In this blog, we saw how to create simple low code no code end to end processes using Flow and invoke them as an API with custom inputs. As long as the action control can trigger an API request this configuration can be used across web apps and such services (including bots etc.) with minimal coding involved.

I hope you found this interesting and it helped you. Thank you for reading!

Comments

Hi @yashag2255 ,

 

Thanks for sharing this helpful blog.

I have tried to implement the same tutorial but there is a problem that occurs on the attachments because it's not sending the file content with type base 64 in the request. So after checking for the attachments in the items,the images are not displaying.

Any solution for this issue ?

Thanks again!

Hi @Julien2 

 

Can you share a screenshot of what you are getting for the file part? Based on that we should be able to convert to binary or base 64 and create the attachment file. 

 

Hope this Helps!

Hi @yashag2255 ,

Here is a demo on how i am filling the form,uploading the image and showing the results after those actions:

Demo.gif

Here is the flow result of the file content:

Capture.PNG

I am using .NET Core 3.0,I've changed the design only on index.cshtml,and i don't think this will affect to upload images anyway here is the html code:

<h5><span class="badge badge-dark">Upload Image</span></h5>
    <div class="custom-file p-4">
        <input id="file" type="file" name="pic" class="custom-file-input" style="margin-top:25px;" accept="image/*">
        <label class="custom-file-label" for="file" style="margin-right:850px;">Choose file</label>
    </div>
    <br />
    <button id="sub" name="temp" value="temp" onclick="userAction()" class="btn btn-dark">Submit Request</button>
    <br />
    <br />
    <span id="newReq"></span>

JS code:

  <script>
var tempFile
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        document.getElementById('file').addEventListener('change', handleFileSelect, false);
    }
    function handleFileSelect(evt) {
        var f = evt.target.files[0]; // FileList object
        var reader = new FileReader();
        // Closure to capture the file information.
        reader.onload = (function (theFile) {
            return function (e) {
                var binaryData = e.target.result;
                //Converting Binary Data to base 64
               tempFile = window.btoa(binaryData);
                //showing file converted to base64
            };
        })(f);
        // Read in the image file as a data URL.
        reader.readAsBinaryString(f);
    }
        const userAction = async () => {
            var data = { name: document.getElementById('nameEntry').value, email: document.getElementById('email').value, comments: document.getElementById('comments').value, file: tempFile };
            const response = await fetch('URL', {
                method: 'POST',
                body: JSON.stringify(data),
                headers: {
                    'Content-Type': 'application/json'
                }
            });
            const myJson = await response.text();
            document.getElementById("newReq").innerHTML = myJson;
        }
    </script>

It shows that the file is converted to base 64 but why it's not displaying the image in the attachment ?

Looking to hear from you.

 

Thank you!

Hey @Julien2 

 

So after a deeper dive into this, here is what I found: 

1. If you are uploading an image of extension PNG, then it will directly give you the appropriate base64 that you can directly upload and get the image. 

 

2. If you are uploading a JPEG/ JPG type images then there is that issue that you are seeing. So here is how you can resolve it: 

 

ee22.PNG

 

And if this resolves the issue, please mark the thread that you have created as solved as it might help other folks who face similar issues resolve soon. 

 

Note: Use this compose action for PNG type images too. It works for both.

 

Hope this Helps! 

Hi @yashag2255 

 

Hi

Thank you very much for your support, now it works like charm.I'll post this solution in the thread that i have created.
I just want to understand about "Using this compose action for PNG type", because I've uploaded an image of PNG type using the compose you mentioned and the image display like the others, while the File-Name in the "Add attachments action" is "Title".jpg:
cap1.PNG

Thanks again!

Hi @Julien2 

 

The file format shouldn't matter much while creating as we are providing the MIME type of image/JPEG that includes PNG, JPG and JPEG. 

 

Hope this Helps!

How can I access the generated post URL(HTTP trigger URL generated), from an infopath form? Any suggestions?

What is the bare minimum license type for Power Automate that is required to be able to be able to use triggering from the outside world? 

 

By that I mean I'm currently using a free trial version and I'm not given the screen that shows me the HTTP Post to this URL. 

 

Any tips are greatly appreciated. 

About the Author
  • Experienced Consultant with a demonstrated history of working in the information technology and services industry. Skilled in Office 365, Azure, SharePoint Online, PowerShell, Nintex, K2, SharePoint Designer workflow automation, PowerApps, Microsoft Flow, PowerShell, Active Directory, Operating Systems, Networking, and JavaScript. Strong consulting professional with a Bachelor of Engineering (B.E.) focused in Information Technology from Mumbai University.
  • I am a Microsoft Business Applications MVP and a Senior Manager at EY. I am a technology enthusiast and problem solver. I work/speak/blog/Vlog on Microsoft technology, including Office 365, Power Apps, Power Automate, SharePoint, and Teams Etc. I am helping global clients on Power Platform adoption and empowering them with Power Platform possibilities, capabilities, and easiness. I am a leader of the Houston Power Platform User Group and Power Automate community superuser. I love traveling , exploring new places, and meeting people from different cultures.
  • Read more about me and my achievements at: https://ganeshsanapblogs.wordpress.com/about MCT | SharePoint, Microsoft 365 and Power Platform Consultant | Contributor on SharePoint StackExchange, MSFT Techcommunity
  • Encodian Owner / Founder - Ex Microsoft Consulting Services - Architect / Developer - 20 years in SharePoint - PowerPlatform Fan
  • Founder of SKILLFUL SARDINE, a company focused on productivity and the Power Platform. You can find me on LinkedIn: https://linkedin.com/in/manueltgomes and twitter http://twitter.com/manueltgomes. I also write at https://www.manueltgomes.com, so if you want some Power Automate, SharePoint or Power Apps content I'm your guy 🙂
  • I am the Owner/Principal Architect at Don't Pa..Panic Consulting. I've been working in the information technology industry for over 30 years, and have played key roles in several enterprise SharePoint architectural design review, Intranet deployment, application development, and migration projects. I've been a Microsoft Most Valuable Professional (MVP) 15 consecutive years and am also a Microsoft Certified SharePoint Masters (MCSM) since 2013.
  • Big fan of Power Platform technologies and implemented many solutions.
  • Passionate #Programmer #SharePoint #SPFx #M365 #Power Platform| Microsoft MVP | SharePoint StackOverflow, Github, PnP contributor
  • Web site – https://kamdaryash.wordpress.com Youtube channel - https://www.youtube.com/channel/UCM149rFkLNgerSvgDVeYTZQ/