• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Tachytelic.net

  • Get in Touch
  • About Me

Power Automate

Posts related to Microsoft Power Automate (aka Microsoft Flow).

How to Print from PowerApps to on-premise printers

April 7, 2020 by Paulie Leave a Comment

PowerApps is a marvellous product, but printing support is quite weak. I am currently in the process of developing a PowerApp and printing support to on-premise printers is a must. YouTube video that demos the functionality:

PrintNode works really well with Microsoft Power Automate and Power Apps. After only a few minutes of setup, I was able to print PDF files directly from PowerApps to my on-premise printers. In my case the PDF files were stored in a SharePoint list.

The printing is performed with a HTTP interaction between Power Automate and PrintNode, so these instructions would work equally well from any flow, but my use case was PowerApps.

The high level steps are as follows:

  • Register on PrintNode and setup the client.
  • Select which Printers you want to print to and gather their unique ids.
  • Create a flow which uses the HTTP Connector to send print jobs to Printnode.

Setup PrintNode Client

After you have registered on printnode.com, install the client on a machine that has local access to the printers you want to print. Then take a note of the printers that you want to print to. Mine look like this:

From the screenshot above, you can see I have two printers enabled with the unique IDs of 69363024 and 68663025.

Setup Printer Definitions in a SharePoint list

A simple SharePoint list with four fields works well to drive a printer selection drop down in PowerApps. My list looks like this:

Image showing list of printers in SharePoint

And the resulting drop down looks like this:

Image of printer selection screen from PowerApps

Or you could set up the printer definitions directly in your PowerApp by using the Table Function. This code would produce the same result as the SharePoint list:

Table(
{printNodeID:"69363025", Description:"HP Laserjet M506", Location: "Pauls Office", Image: "https://www.tachytelic.net/wp-content/uploads/HP-LaserJet-Enterprise-M506-Printer.jpg" },
{printNodeID:"69363024", Description:"HP PageWide Pro 477DW", Location: "Merrians Office", Image: "https://www.tachytelic.net/wp-content/uploads/HP-PageWide-Pro-477dn-web.jpg" }
)

Create a flow to receive print request from PowerApps and submit to PrintNode

The flow is simple to create. Here is a high level image of my flow:

An Image showing the steps of a Flow in Microsoft Power Automate used to print from PowerApps to On-Premise printers.

Define the required variables for the Flow from PowerApps

The flow starts with the creation of the three variables that are needed to complete the flow. The three variables are

  • printNodeID
  • pdfPath
  • documentName

This step isn’t strictly required, you can simply use “Ask in PowerApps” to fill the required values further down the flow. I prefer to do it this way as it makes the flow easier to comprehend when you are calling it from PowerApps. Each variable is initialized like this:

Image of a flow variable being initialized to be a parameter for a PowerApp

Retrieve the PDF that you want to print

In my case, the document I want to print is already in PDF format, if your’s is not, then you will need to add some steps to your flow to get it into PDF format.

I am using the flow action “Get file content using path” to get the PDF file from a SharePoint list.

Compose your JSON and submit to PrintNode

The PrintNode API is extensive and I have only scratched the surface. The code I am using simply submits a PDF for printing to a particular printer. I am using the “Compose” action to create the required JSON.

{
  "printerId": "@{variables('printNodeID')}",
  "title": "@{variables('documentName')}",
  "contentType": "pdf_base64",
  "content": "@{base64(body('Get_file_content_using_path'))}",
  "source": "PowerApps"
}

Note that the PDF file needs to be Base64 encoded, otherwise the submission to PrintNode will fail.

Image of the compose action in Power Automate being used to generate JSON for submission to PrintNode

The final step is to use the HTTP action to submit the job to PrintNode:

This step is simple. You need the URI, which is: https://api.printnode.com/printjobs

The Authorization header. I used a concat expression for the value of:

concat('Basic ', base64('apiKeyFromPrintNode:'))  

and the body of the HTTP request is the output of the compose step.

Connect your new PrintNode flow to your PowerApp

The final step is to connect your PowerApp to your newly created PrintNode flow. I have connected mine to a button control which initiates the flow with the following code:

printViaPrintNode.Run(dropDownSelectPrinter.Selected.printerID, pdfURL, pdfName)

Obviously I named the flow “printViaPrintNode” and the values being passed in are associated to the variables assigned in the flow.

Image showing expression used to execute a flow from PowerApps to print a PDF to an on-premise printer.

This is the Print screen withing my PowerApp. PDF Preview on the right hand side with the printer options on the left and an image of the printer that is going to process the job.

Image of a screen from PowerApps which is used to preview a PDF document and then print it to an on-premise printer.

It’s also interesting to note that PrintNode do have a “Raw” printing option which can be used to drive Label printers, but I can think of some other uses for that option to, which I am going to play with.

So overall, although PowerApps does not have great native printing support, PrintNode goes a long way to solving the problem!

Filed Under: Power Platform Tagged With: Power Automate, PowerApps

How to trigger a Power Automate Flow with a HTTP Request

March 12, 2020 by Paulie Leave a Comment

Being able to trigger a flow in Power Automate with a simple HTTP request opens the door to so many possibilities. I love it! With some imagination you can integrate anything with Power Automate.

If you want an in-depth explanation of how to call Flow via HTTP take a look at this blog post on the Power Automate blog.

This post provide examples of some of the different ways that the trigger “When a HTTP request is received” can be executed:

  • PowerShell
  • curl on Windows
  • curl on Linux or Unix
  • vbscript
  • vba
  • jquery

The same flow will be executed with different tools or languages and each of them will submit this JSON:

{
	"MessageSubject": "Testing HTTP",
	"MessageBody": "Flow execution has been triggered"
}

The flow only has two steps, it receives the JSON payload and then sends me a message on Teams from the Flow bot:

Image of Flow in Microsoft Power Automate which will be triggered by the event "When a HTTP request is received"
Image of Flow Bot sending a Teams message using a flow Microsoft Power Automate

Invoke a Flow with PowerShell

It’s super easy to invoke a flow with PowerShell. Example:

$flowURI = "https://prod-118.westeurope.logic.azure.com:443/workflows/..."
$messageSubject = "Testing HTTP"
$messageBody = "Execution test from Powershell"
$params = @{"messageSubject"="$messageSubject";"messageBody"="$messageBody"}
Invoke-WebRequest -Uri $flowURI -Method POST -ContentType "application/json" -Body ($params|ConvertTo-Json)

Invoke a HTTP Flow Trigger with curl on Windows Command Line

Because of the way Windows command line interprets double quotes, they need to be escaped. So if you want to include the JSON data on the command line it gets ugly:

curl -H "Content-Type: application/json" -d "{\"messageSubject\": \"Test\",\"messageBody\": \"Executing Flow from curl in Windows Command Line\"}" "https://prod-118.westeurope.logic.azure.com:443/workflows/..."

It’s much easier to work with if you put the contents of the JSON in a file and use the following syntax:

curl -H "Content-Type: application/json" -d @c:\temp\data.json "https://prod-118.westeurope.logic.azure.com:443/workflows/..."

Invoke a HTTP Flow Trigger with curl on Linux or Unix

Things are a bit easier in Linux because there is no need to escape double quotes. So you can simply execute a flow like this:

curl -H "Content-Type: application/json" -d '{ "MessageSubject": "Testing HTTP", "MessageBody": "Flow execution has been triggered from Linux" }' 'https://prod-118.westeurope.logic.azure.com:443/workflows/...'

Invoke a HTTP Flow using VBScript

You can use this code to invoke a HTTP flow in a VBScript:

Option Explicit

Dim FlowURI, JSON, objHTTP, httpCode
FlowURI = "https://prod-118.westeurope.logic.azure.com:443/workflows/..."
JSON = Quote("{ `MessageSubject`: `Testing HTTP`, `MessageBody`: `Flow executed from VBScript` }")

set objHttp = wscript.Createobject("Msxml2.ServerXMLHTTP")
objHTTP.Open "POST",FlowURI,false
objHTTP.setRequestHeader "Content-Type", "application/json; charset=UTF-8"
objHTTP.setRequestHeader "CharSet", "charset=UTF-8"
objHTTP.setRequestHeader "Accept", "application/json"
objHTTP.setRequestHeader "Content-Length", Len(JSON)
objHTTP.send JSON
httpCode = objHTTP.Status
Set objHTTP = nothing

Function Quote(stringToQuote)
	'Small Function to replace backticks with Double Quotes
	Quote=Replace(stringToQuote, "`", chr(34))
End Function

Invoke a HTTP flow using VBA

Almost the same as the VBScript above, you can easily execute a flow using VBA from any of the Microsoft Office Suite:

Option Explicit
Sub ExecuteFlow()

    Dim FlowURI As String, JSON As String, objHTTP As Object, httpCode As String
    FlowURI = "https://prod-118.westeurope.logic.azure.com:443/workflows/..."
    JSON = Quote("{ `MessageSubject`: `Testing HTTP`, `MessageBody`: `Flow executed from VBA` }")
    
    Set objHTTP = CreateObject("Msxml2.ServerXMLHTTP")
    objHTTP.Open "POST", FlowURI, False
    objHTTP.setRequestHeader "Content-Type", "application/json; charset=UTF-8"
    objHTTP.setRequestHeader "CharSet", "charset=UTF-8"
    objHTTP.setRequestHeader "Accept", "application/json"
    objHTTP.setRequestHeader "Content-Length", Len(JSON)
    objHTTP.send JSON
    httpCode = objHTTP.Status
    Set objHTTP = Nothing

End Sub

Function Quote(stringToQuote)
    'Small Function to replace backticks with Double Quotes
    Quote = Replace(stringToQuote, "`", Chr(34))
End Function

Invoke a HTTP flow with jQuery

This is an example of how to execute the same flow with jQuery. I’ve also included the required HTML. Full source code on this page, send me a message!

<!DOCTYPE html>
<head>
<title>Execute Flow</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
flowURI = "https://prod-118.westeurope.logic.azure.com:443/workflows/..."
$(document).ready(function(){
    $("button").click(function(){
        flowData = {
           MessageSubject: "Testing HTTP",
           MessageBody: $("#teamsMessage").val()
        }
        $.ajax(
            {
                url: flowURI,
                data: JSON.stringify(flowData),
                processData: false,
                contentType: "application/json",
                dataType: "json",
                type: 'POST',
                complete: function(xhr, textStatus) 
                {
                    if (xhr.status == '202')
                    {
                        $("#flowStatus").append("Flow Executed");  
                        console.log(xhr.status);                                                  
                    } else 
                    {
                        $("#flowStatus").append("Flow Execution Failed");                                                                                
                        console.log(xhr.status);
                    }  
                }
            });
    });
});
</script>
</head>
<body>
    <p>
        <label>Message</label>
        <input type = "text" id ="teamsMessage" value="Send a message on teams to Paulie" />
    </p>
    <p>
        <button>Invoke Flow</button>
    </p>
<p id="flowStatus"></p>
</body>
</html>

I will keep adding more examples as I create them, but if you have one, feel free to share and I will add it to the post.

Now secure your HTTP Request Trigger with the instructions here.

Filed Under: Power Platform Tagged With: Power Automate, Powershell, VBA, VBScript

Power Automate: Get a single record from CDS List Records action

January 30, 2020 by Paulie 2 Comments

You can easily retrieve the unique identifier of a record in CDS within flow using the List Records action. But this approach will create an “Apply to each” loop, even if there is only one possible result.

Image showing unwanted "Apply to Each" loop when querying a single record from Common Data Service.

I needed to get the accountid from the Account entity to create a new record in a related table. My list records action looks like this:

Image showing "List Records" action in Microsoft Power Automate.

Note that “Top Count” is set to 1.

The next step of the flow where the new record is created. You can stop the Apply to Each loop being created by using the “first” function. Example code:

first(body('List_records')?['value'])?['accountid']
Image showing how to create a new record in Common Data Service using only a single result from a "List Records" action in Microsoft Power Automate.
Image of Microsoft Flow Expression and the use of the "First" function which can give you the first result from a record set.

Then you can continue to your next action without having to deal with a for each loop. It makes the flow neater and easier to comprehend.

Filed Under: Power Platform Tagged With: Power Automate

Create PDF Invoice using Microsoft Power Automate with JSON

December 2, 2019 by Paulie 1 Comment

This post explains how you can create a PDF document using Microsoft Power Automate and a Microsoft Word Template. In this example the flow is being triggered by a HTTP request containing a JSON payload to generate an invoice. The five step flow follows this sequence:

  1. Receive data from a HTTP request containing a JSON payload.
  2. Populate a Microsoft Word Invoice Template.
  3. Create File (Word Document).
  4. Convert previously created Word document to PDF.
  5. Save the PDF File.
Image of a Microsoft Flow that generates a PDF Invoice from JSON data.

Here is the PDF produced by Power Automate (click here to see full PDF):

Image preview of a PDF produced by Microsoft Flow (Power Automate) from a JSON file

You can view the full JSON payload on Pastebin.

Create a Word Template for the PDF Invoice

The first thing you need to do, is build your word template. I used the Simple Sales Invoice in the Word template gallery as my starting point and modified the appearance to my liking.

Next, add plain text control controls to the document for each of the fields in the JSON file that will appear only once (i.e. everything that is not part of an Invoice line). Do the following:

  • Enable the Developer Tab in Word.
  • Put the cursor into a table cell where your data needs to go.
  • Enter some sample data into that cell.
  • Highlight the sample data and click on “Plain Text Context Control” in the developer toolbar.
  • Click on Properties in the control toolbar ribbon.
  • Give the content control a meaningful name(preferably match it to your JSON field names).
Animated Gif showing how to add plain text content controls to a Microsoft Word Template.

Add Content Controls for repeating data

For the repeating data, follow the same procedure as above for each column of data in your table, but this time make sure the field names match the JSON field names. Then specify the row as repeating content like this:

Animated Gif showing how to add repeating data content to a Word Table.
  1. Select the entire Invoice line item row. I find it is easiest to go to the Layout tab and click “Select” and then choose “Select Row”.
  2. Go back to the developer tab and click on the repeating section content control.
  3. Name the repeating section with a sensible name.

In this example, the JSON for a single invoice line is like this:

{
	"PartNo": "813/00419",
	"Description": "GASKET-EXHAUST FLANGE",
	"ToInvoice": "1",
	"SellingPrice": "0.50",
	"DiscountPercentage": "0.00",
	"NetLineValue": "0.50"
}

Set Repeating Column Headers

My example data has quite a lot of invoice lines which do not all fit on a single page. So it is important to make sure that “Repeat Header Rows” is enabled. This will ensure the subsequent pages have column headings.

Select the top row of your Invoice lines table and go to the Layout tab and select “Repeat Header Rows”.

Image of "Repeat Header Rows" button in Microsoft Word.

Now that you have finished editing the Word document. Save it somewhere you will be able to access it from Flow, such as OneDrive or SharePoint.

Create the Flow

The flow is really easy to build and in this example there are only five steps:

  • Step 1 – Create a new flow
    • Choose “Instant – from blank”
    • Trigger the flow “When a HTTP request is received”
    • When the flow editor appears click the “Generate from Sample” button within the HTTP Request flow part and paste in a sample of your JSON data and then flow will automatically generate the JSON schema which you will be able to use in the rest of the flow.
  • Step 2 – Add the “Populate a Microsoft Word Template” action.
    • Select the previously saved template file.
    • Flow will read the document and present a list of fields to be added to the document.
    • Go through each field and add them to the document, apart from the repeating fields.
    • When you reach the line items block it will first appear like this:
    • Click on the little box highlighted in red which switches the input to accept an entire array. Then you can select the array from your JSON file.
  • Step 3 – Save the File
    • Now your Word document has been populated you can save it somewhere that is appropriate for your environment (I used “Create file – OneDrive for Business).
    • For the Filename I used “INV_” + Invoice Number from JSON File + “.docx”:
  • Step 4 – Convert the Word Invoice to PDF using the path from the previous step.
  • Step 5 – Save the new PDF. I named the file as per the above step but changed the extension to .PDF

Executing the Flow

This flow is triggered via a HTTP request with a JSON payload. In this example it was fired using curl from Linux like this:

#!/bin/bash
host="https://prod-84.westeurope.logic.azure.com:443/workflows/..."
curl -v -d @INV_00102707.json -H 'Content-Type: application/json' $host

But it could just as easily be executed from PowerShell like this:

$FlowUri = "https://prod-84.westeurope.logic.azure.com:443/workflows/..."
$PostBody = Get-Content ".\INV_00102707.json"
Invoke-RestMethod -Method Post -Uri $FlowUri -Body $PostBody

Conclusion

Microsoft Power Automate can provide a good solution for automatically generating invoices or other business documents. In it’s live implementation this flow also:

  • Saves the document to a custom SharePoint list that holds metadata about the document and makes it easy to find documents again.
  • Uses a Sendgrid dynamic template to email the invoice to the recipient and track delivery.

This flow was put into production use and is actually used with a legacy Kerridge system to generate PDF output, functionality that it did not have previously.

Filed Under: Office 365 Tagged With: Power Automate

  • « Go to Previous Page
  • Go to page 1
  • Interim pages omitted …
  • Go to page 4
  • Go to page 5
  • Go to page 6

Primary Sidebar

Power Automate Support Image
Link to my LinkedIn Profile

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 107 other subscribers.

Go to mobile version