Power Apps Dev: Integrating Document Scanning Functionality into Canvas App

Xiao Ling - Sep 22 '23 - - Dev Community

Microsoft Power Apps is a low-code development platform that enables you to build custom apps tailored to your business needs. Within Power Apps, a 'Canvas App' is a specific type of app that allows you to design your interface by dragging and dropping elements onto a canvas, similar to designing a slide in PowerPoint. While Canvas Apps do not natively support the embedding or execution of JavaScript code, they do allow for the invocation of services through Power Automate (Flow). This article aims to assist developers in integrating document scanning functionalities into Power Apps Canvas by utilizing the Dynamsoft Service REST API.

Pre-requisites

Setting Up a Web Server for Communication with the Dynamsoft Service

Dynamsoft Service is designed to operate within a local network via HTTP requests. To make it accessible from the Internet, a web server needs to be set up to forward requests to Dynamsoft Service.

For a quick setup, you can download example code from the following GitHub repository: https://github.com/yushulx/dynamsoft-service-REST-API/tree/main/examples/REST.

To run the example code:

  1. Install Node.js.
  2. Open app.js and replace the license key with your own.

    license: "LICENSE-KEY",
    
  3. open a terminal and run the following commands:

    npm install
    node app.js
    > Server running at http://0.0.0.0:3000/
    
  4. Use ngrok to expose the local web server to the Internet.

    ngrok http 3000
    

    ngrok

  5. Visit the ngrok URL in a browser to verify that the web server is running properly.

    web server

Building a Document Scanning App with Power Apps Canvas

Step 1: Create a Blank Canvas App

Visit https://make.powerapps.com/ to create a Blank Canvas App.

Power App Canvas App

Step2: Add UI Elements

The UI consists of two buttons, a dropdown list, and an image control.

Power App Canvas UI

  • The Get Devices button triggers an HTTP GET request to retrieve a list of available scanners.
  • The dropdown list displays the list of available scanners.
  • The Scan triggers an HTTP POST request to initiate document scanning.
  • The image control displays the scanned image.

Step3: Create Power Automate Flows

According to our requirements, we create two flows: ScanDocument and GetDevices in Power Automate panel.

Power Automate flows

Power Automate Flow for HTTP GET

The GetDevices flow consists of four operations: HTTP, Parse JSON, Select, and Response.

GetDevices Flow

HTTP

Send an HTTP GET request to the web server. The URL is constructed with the ngrok URL and the /devices path.

power automate HTTP Action

Parse JSON

Parse the response body as JSON to extract the device information.

power automate parse JSON

The schema of the JSON response is as follows:

{
    "type": "object",
    "properties": {
        "devices": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "device": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "type": {
                        "type": "integer"
                    }
                },
                "required": [
                    "device",
                    "name",
                    "type"
                ]
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

It can be automatically generated from the example response body:

{"devices":[{"device":"{\n\t\"deviceInfo\" : \n\t{\n\t\t\"Manufacturer\" : \"VFdBSU4gV29ya2luZyBHcm91cA==\",\n\t\t\"ProductFamily\" : \"U29mdHdhcmUgU2Nhbg==\",\n\t\t\"ProductName\" : \"V2luZG93cyBWaXJ0dWFsIFNjYW5uZXI=\",\n\t\t\"ProtocolMajor\" : 2,\n\t\t\"ProtocolMinor\" : 5,\n\t\t\"SupportedGroups\" : 0,\n\t\t\"Version\" : \n\t\t{\n\t\t\t\"Country\" : 1,\n\t\t\t\"Info\" : \"Mi41LjAgc2FtcGxlIHJlbGVhc2UgNjRiaXQ=\",\n\t\t\t\"Language\" : 2,\n\t\t\t\"MajorNum\" : 2,\n\t\t\t\"MinorNum\" : 5\n\t\t}\n\t},\n\t\"deviceType\" : 64,\n\t\"isSystemDefaultPrinter\" : false,\n\t\"name\" : \"V2luZG93cyBWaXJ0dWFsIFNjYW5uZXI=\"\n}\n","name":"Windows Virtual Scanner","type":64},{"device":"{\n\t\"deviceInfo\" : \n\t{\n\t\t\"BaudRate\" : \"\",\n\t\t\"Description\" : \"WSD Scan Device\",\n\t\t\"Driver Version\" : \"10.0.19041.1806\",\n\t\t\"Hardware Configuration\" : 0,\n\t\t\"Manufacturer\" : \"Microsoft\",\n\t\t\"Name\" : \"HPBCF77F (HP LaserJet Pro M329)\",\n\t\t\"PnP ID String\" : \"\\\\\\\\?\\\\swd#dafwsdprovider#urn:uuid:f8262726-dc64-5cf1-89ab-5e257f2d0f3a#http:##f8262726-dc64-5cf1-89ab-5e257f2d0f3a#scanservice#{6bdd1fc6-810f-11d0-bec7-08002be2092f}\",\n\t\t\"Port\" : \"urn:uuid:f8262726-dc64-5cf1-89ab-5e257f2d0f3a/http://f8262726-dc64-5cf1-89ab-5e257f2d0f3a/ScanService\",\n\t\t\"Remote Device ID\" : \"\",\n\t\t\"STI Driver Version\" : 3,\n\t\t\"STI Generic Capabilities\" : 49,\n\t\t\"Server\" : \"local\",\n\t\t\"Type\" : 65537,\n\t\t\"UI Class ID\" : \"{00000000-0000-0000-0000-000000000000}\",\n\t\t\"Unique Device ID\" : \"{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}\\\\0000\",\n\t\t\"WIA Version\" : \"2.0\"\n\t},\n\t\"deviceType\" : 32,\n\t\"isSystemDefaultPrinter\" : true,\n\t\"name\" : \"SFBCQ0Y3N0YgKEhQIExhc2VySmV0IFBybyBNMzI5KQ==\"\n}\n","name":"HPBCF77F (HP LaserJet Pro M329)","type":32},{"device":"{\n\t\"deviceInfo\" : \n\t{\n\t\t\"BaudRate\" : \"\",\n\t\t\"Description\" : \"HP OfficeJet Pro 6970 [01A3B2]\",\n\t\t\"Driver Version\" : \"10.0.19041.3271\",\n\t\t\"Hardware Configuration\" : 0,\n\t\t\"Manufacturer\" : \"Microsoft\",\n\t\t\"Name\" : \"HP OfficeJet Pro 6970 [01A3B2]\",\n\t\t\"PnP ID String\" : \"\\\\\\\\?\\\\swd#escl#59ca18cd-afb6-5c82-a201-23911ae167ea#{6bdd1fc6-810f-11d0-bec7-08002be2092f}\",\n\t\t\"Port\" : \"SWD\\\\Escl\\\\59ca18cd-afb6-5c82-a201-23911ae167ea\",\n\t\t\"Remote Device ID\" : \"\",\n\t\t\"STI Driver Version\" : 16777218,\n\t\t\"STI Generic Capabilities\" : 16,\n\t\t\"Server\" : \"local\",\n\t\t\"Type\" : 65537,\n\t\t\"UI Class ID\" : \"{00000000-0000-0000-0000-000000000000}\",\n\t\t\"Unique Device ID\" : \"SWD\\\\Escl\\\\59ca18cd-afb6-5c82-a201-23911ae167ea\",\n\t\t\"WIA Version\" : \"2.0\"\n\t},\n\t\"deviceType\" : 32,\n\t\"isSystemDefaultPrinter\" : false,\n\t\"name\" : \"SFAgT2ZmaWNlSmV0IFBybyA2OTcwIFswMUEzQjJd\"\n}\n","name":"HP OfficeJet Pro 6970 [01A3B2]","type":32},{"device":"{\n\t\"deviceInfo\" : \n\t{\n\t\t\"UUID\" : \"f8262726-dc64-5cf1-89ab-5e257f2d0f3a\",\n\t\t\"adminurl\" : \"http://HP6C02E0BCF77F.local.\",\n\t\t\"cs\" : \"binary,color,grayscale\",\n\t\t\"duplex\" : \"F\",\n\t\t\"is\" : \"platen,adf\",\n\t\t\"mopria-certified-scan\" : \"1.2\",\n\t\t\"name\" : \"HP LaserJet Pro M329 [BCF77F]\",\n\t\t\"pdl\" : \"application/octet-stream,application/pdf,image/jpeg\",\n\t\t\"representation\" : \"images/printer.png\",\n\t\t\"rs\" : \"eSCL\",\n\t\t\"service_type\" : 3,\n\t\t\"txtvers\" : \"1\",\n\t\t\"ty\" : \"HP LaserJet Pro M329\",\n\t\t\"vers\" : \"2.63\"\n\t},\n\t\"deviceType\" : 512,\n\t\"name\" : \"SFAgTGFzZXJKZXQgUHJvIE0zMjk=\"\n}\n","name":"HP LaserJet Pro M329","type":512}]}
Enter fullscreen mode Exit fullscreen mode

Select

This operation extracts device information from the JSON object as the output.

power automate select

Response

Send the select output back to the Power App.

Power automate response

Power Automate Flow for HTTP POST

The ScanDocument flow consists of four operations: Compose, HTTP, Parse JSON, and Return value(s) to Power Pages.

scan document flow

Compose

Input the selected scanner information from the Power App page.

power automate compose

HTTP

Append the compose output to the HTTP body and send an HTTP POST request to the web server. The URL is constructed with the ngrok URL and the /scandocument path.

power automate HTTP post

Parse JSON

Parse the response body as JSON to extract the scanned image.

power automate parse JSON

The schema of the JSON response is as follows:

{
    "type": "object",
    "properties": {
        "image": {
            "type": "string"
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Return value(s) to Power Pages

Return the image name to the Power App page.

power automate Return value(s) to Power Pages

Step4: Connect Power Automate Flows to the UI Elements

Get devices

Click on the Get Devices button and then assign the following code to its OnSelect property.

ClearCollect( Devices, GetDevices.Run());
Enter fullscreen mode Exit fullscreen mode

Get device event

The code above will initiate the GetDevices flow when the Get Devices button is clicked. The flow's response will populate the Devices collection, which can be found in the Variables panel.

power automate collection

Display device list

Click on the dropdown list and then assign Devices collection to its Items property. Then, set the display value to name in the properties panel.

power automate dropdown display

Acquire a document image

Click on the Scan button and then assign the following code to its OnSelect property.

Set(jsonString, Concatenate("{", """scan""", ":", DeviceList.Selected.Device, "}"));
Set(data, ScanDocument.Run(jsonString));
Enter fullscreen mode Exit fullscreen mode

scan document event

The code constructs a JSON string with the selected scanner information and then initiates the ScanDocument flow. The data variable will be populated with the response from the flow and can be found in the Variables panel.

variable data

Display the document image

Set the Image property using the URL of the scanned image. The URL is constructed by combining the ngrok URL with the image name.

power automate image display

Step5: Test the App

Scan document in Power App Canvas App

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player