DEV Community

Cover image for Run Code in Your Power Automate Flow
david wyatt
david wyatt Subscriber

Posted on

Run Code in Your Power Automate Flow

One of the cool things that Logic Apps has over Power Automate Flows is inline scripts, although expressions cover most use cases they don't cover all. And having that ability to run JavaScript for those edge cases is super useful. Luckily there is a workaround in Power Automate, although it's not as easy to implement, luckily vibe coding is now present with the latest AI tools, making it a lot more accessible.

Big caveat with this solution, it could create vulnerability in your DLP process, so make sure all code is reviewed and segregation of duty is e forced.

The work around is to unload our script to another service and call it through an API. Cloudflare is what I recommend, the free tier is amazing (100k daily calls), its easy to use, well documented, and has loads of additional features like database and site hosting. Additionally if you do go above the limits its only $25 a month

cloudflare

One call out is the processing time, its 10ms of cpu time, plenty for running long scripts, but no good for external dependencies like large database writes up calling other API's (you can still do small requests, especially to the built in free database in Cloudflare).

You can write your API in JavaScript, TypeScript, Python, and Rust, but this blog is in JavaScript because it's what I know (barely lol) and it's the only supported in the in browser code editor. But if you want to use Python etc and happy with VS Code and CLI, there are plenty of docs explaining how to.

  1. Cloudflare Setup
  2. API Code
  3. Use in Power Platform

1. Cloudflare Setup

To start sign up for free, sign in and go to 'Compute (Workers)' and select 'Workers & Pages'.

Pages are websites that you can host, workers are API's and what we are using.

workers

There are loads of templates but are going simple with a blank worker aka the Hello World worker.

hello world

Once deployed you can go to the settings section and see the url of your worker.

settings

As this is defaulted to a GET API we can copy the url and paste in a browser and give it a quick test.

browser test

2. API Code

Next we want to create our code to run (as not matter how much we love Hello World, it's not that useful 😎).

You could write your own, or be lazy and use some AI (though I highly recommend you learn the basics of JavaScript first to help debug it).

t3 chat

What's nice about Cloudflare is it has its own built in code editor (and live tester), it's great for basic code, and you also have the option to build in VS Code and deploy directly. In this simple demo we will use the built in editor.

code tester

So what does my demo API do, the age old favourite RegEx. You pass in the regex and the text you want to find the matches and the API will return all matches.

If I submit below code I get an array of matches, in this case just one: ["david.wyatt@mail.com"]

{ "regex":"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}", "text":"can you find the email, its david.wyatt@mail.com, i dont think you will find it" } 
Enter fullscreen mode Exit fullscreen mode

Working through the code you will see we added a API Key, this is because web scrapers will find your API, and with no auth it will get exploited. It's a header named 'X-API-Key', so we just need to store is as available named apiKey and then check to see if it matches our key (password).

const apiKey = request.headers.get('X-API-Key'); if (!apiKey || apiKey !== 'YOUR_SECRET_API_KEY') { return new Response('Unauthorized: Missing or invalid API Key', { status: 401, }); } 
Enter fullscreen mode Exit fullscreen mode

Replace YOUR_SECRET_API_KEY with your api key, if it's not important then you can hardcode it in the code, but really it should be stored in a keyvault, guess what, Cloudflare has one for free you can use. But that's for another blog.

 if (request.method === 'POST' && url.pathname.includes('/find')) { 
Enter fullscreen mode Exit fullscreen mode

This is how you create logic for your endpoints. Above is for a post request from the '/find' endpoint. You can add different types (GET,PATCH,PUT,DELETE) and different endpoints.

You can also add parameters from the endpoint url: {url}/find?version=3

const version = url.searchParams.get('version'); if (version !== 'v3') { console.log(version); } 
Enter fullscreen mode Exit fullscreen mode

But in this demo we are not using parameters, just the body of the request. Below you will see we get the 2 keys/parameters from the body, and then check if the response does not match right type (this will also flag if the parameter is missing as it would return null).

const { regex, text } = await request.json(); if (typeof regex !== 'string' || typeof text !== 'string') { return new Response( 'Bad Request: Request body must contain "regex" and "text" as strings.', { status: 400 }, ); } 
Enter fullscreen mode Exit fullscreen mode

We are using guard clauses (so no need for if else)

The next piece of code is specific to the API, so in my case its finding matches and returning an array.

const regexObj = new RegExp(regex, 'g'); let match; while ((match = regexObj.exec(text)) !== null) { matches.push(match[0]); } 
Enter fullscreen mode Exit fullscreen mode

We create the regex, and then get all the loop over all matches until the match array contains all matches.

The final piece of code to understand is the return, as this converts your json to a string and sends back to the request. If you are sending back text (like HTML / XML) then the content type should be 'text/'.

  • text: text/plain
  • html: text/html
  • xml: text/xml
return new Response(JSON.stringify(matches), { headers: { 'Content-Type': 'application/json' }, }); 
Enter fullscreen mode Exit fullscreen mode

We can test out API on the left of the code screen and only deploy when happy.

api tester

Just remember to:

  • Add endpoint to url
  • Add API key header
  • Add body
  • Click test

You can also add console.logs() and see them in the console at the bottom screen.

3. Use in Power Platform

So our API is working, how do we use it in a flow. Well the super easy way is the HTTP action, simply follow the steps you used in the tester. You will also need a parseJSON to handle the response.

http

But there are 2 issues with this, the first is auth, as you have to hardcode your API key into the flow. The second is usability, as its not great for sharing with others in your team.

To get around this we can use custom connectors. I've gone into more detail how to make them here Power Platform Connectors - Go Custom

Custom Connector Quick Steps

General - setup url, name, image
general

Security - API key label and header value
security

Actions - create one or many actions using sample
actions

Actions - create response schema from sample
response

Test
test

Used in a Flow
in flow


This demo is very simple, you can easily add on more endpoints (extra actions in your custom connector), use JavaScript libraries, simple databases, and even LLM (some good templates available). But hopefully you can see that it's not too difficult (or expensive) to step from the LowCode to ProCode world (especially now with AI).

If you want to check out the custom connector is can be found in my GitHub here, I will leave the API up for a while so you should be able to test it too.


If you would like to get notified every new blog (I also do a few in the Power Platform Community), subscribe below

Top comments (3)

Collapse
 
balagmadhu profile image
Bala Madhusoodhanan

This is super useful. Have couple of fun projects which i think might use this pattern. For most of the systemic data processing I enjoyed C# plugin with the same protocol

Collapse
 
mjboes profile image
Marc Boes

Not fit for all purposes off course, but for the simplest of simplest (regex, json manipulations and comparison) I'd consider typescripting in Excel for Business first. But this is an interesting alternative for Azure Functions app!

Collapse
 
wyattdave profile image
david wyatt

Very much so, regex is just my fall back to demo any code lol (Another good option is to use a custom connector and use the script function).
Azure functions are probably best where possible, but when you have no budget, want something super flexible this is a nice option