Learn how to update an account using VAT data through an API call (Power Automate) and JavaScript, using the Modern Ribbon (not Ribbon Workbench)
The challenge
When creating a new account in Dynamics 365, it can be time consuming to enter the correct account data, and there is a risk of mistakes.
In many countries, the company data is publicly available, and the information can usually be accessed through an API call
Let’s make a custom button that starts a Power Automate flow that can get this data, and return it to Dynamics
Solution
In this blog post I will be using the Danish equivalent to VAT (CVR)
I found two good Danish providers - I will continue with the first one (free up to 50 API calls pr. day)
Step 1
Create a custom button
We can search the API using either the company name or the VAT number. We will use the VAT number in this exercise.
If you don’t have a field for VAT, create one and insert it into your form.
Go to your app, and add a new button to your main form.
I haved named my button update account data
We will return to the button again.
Step 2
Create a Power Automate Flow
Go to make.powerautomate.com and create a new Automated Cloud Flow (you might also consider setting this flow up as a Logic App in Azure)
Step 3
Your first action (trigger action) is when a HTTP request is received
In the Request Body JSON Schema insert the following code
{
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
}
Change who can trigger the flow to anyone
Warning anybody who has the HTTP POST URL could potentially trigger the flow
Step 4
Insert a get a row by ID action and insert the id from the trigger output. Make sure that you are also limiting the output in select columns to the internal name of your VAT-number field (we want this flow to run as fast as possible)
Step 5
Insert a new action called HTTP
The documentation for CVRAPI is in Danish, but it is simple - the request for a search is https://cvrapi.dk/api?search=
& account name or VAT number. The documentation also explains that a country code is always required, so we must also insert &country=dk
Here is two API examples
https://cvrapi.dk/api?search=Microsoft&country=dk
https://cvrapi.dk/api?search=13612870&country=dk
virkdata.dk requires an API Key.
To use an API key, change authentication to raw and insert the API key in value (this is not needed for cvrapi)
Now our HTTP request will look like this
You can check out the data that the API is returning by following this link (this will also give you the internal names that we are going to use in the next step)
cvrapi.dk/api?search=13612870&country=dk
Step 6
Next we want to update our account, so the next action should be update a row
Row ID should be id from our trigger
We will update Account name, ZIP code and Main Phone, you can choose other fields from the API if you like (if you know parse from JSON, you can also do that instead)
Account name outputs('HTTP')['body']?['name']
ZIP code outputs('HTTP')['body']?['zipcode']
Main Phone outputs('HTTP')['body']?['phone']
Step 7
Our last action is going to be response
Make sure the status code is 200
Step 8
Save your flow.
If you go to the top of the flow you will see that a link is now available in the HTTP POST URL, we are going to use this link later
If you want to improve your search result you could change the flow so that if a VAT number is available we will use this as a search query - if not, then we use the company name
The code
Now we are going to use some code. I left some comments in the code, so you can follow along what is happening in the console
Explanation of the code
The code is triggered by the main function, which is then getting the context of the form (FormContext). We are then asking the code to return the ID of the record.The record is returned with a
{
and a}
, so we are “cleaning” up the ID by removing the curly brackets with.replace
When the user is clicking the new button, we are asking if the user wants to continue with
Xrm.Navigation.openConfirmDialog
If user selects no, we are cancelling the script. If the user select yes, we are then posting the
EntityID
that we got usingFormContext.data.entity.getId()
to the Power Automate flow with thePostRecordID
functionWe are then showing a
FormNotification
to tell the user that a flow is running.If the HTTP request fails, we are telling the user that we could not find the company (the documentation can send other errors, but we don’t handle them in this exercise)
If the HTTP request succeed, Power Automate will update the record for us, and we will refresh the form with
FormContext.data.refresh(false)
and then update theFormNotification
Last, we will make sure to clear the form notification after 10 seconds with the
setTimeout
function
Copy below code and save it as a .js file - remember to insert your own HTTP POST URL in the code
I have named my JavaScript file updateCompanyData.js
// Get values from the form context
const getEntityValues = async (FormContext) => {
console.log("Called");
const entityId = FormContext.data.entity.getId().replace("{", "").replace("}", "");
console.log(entityId);
return entityId;
};
// Send the entityId to Power Automate
const postEntityId = async (recordId) => {
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: recordId
}),
redirect: 'follow'
};
const url = `INSERT HTTP POST URL HERE`;
try {
const response = await fetch(url, requestOptions);
if (response.ok) {
console.log("Flow completed successfully.");
return true;
} else {
console.log("Flow completed with error:", response.status, response.statusText);
return false;
}
} catch (error) {
console.log('Error executing flow:', error);
return false;
}
};
// Main function to handle the button click
async function main(FormContext) {
try {
console.log("Started");
const entityId = await getEntityValues(FormContext);
// Show confirmation dialog
const confirmStrings = { text: "Do you want to update the account data?", title: "Update account data" };
const confirmOptions = { height: 200, width: 450 };
const confirmed = await new Promise((resolve) => {
Xrm.Navigation.openConfirmDialog(confirmStrings, confirmOptions).then(
function (success) {
resolve(success.confirmed);
}
);
});
if (!confirmed) {
console.log("User canceled the action.");
return;
}
// Save the form before running the flow
await FormContext.data.entity.save();
FormContext.ui.setFormNotification("Getting company data, please wait...", "INFO", entityId)
const flowCompleted = await postEntityId(entityId);
if (flowCompleted) {
console.log("Flow execution successful, refreshing form...");
// Refresh the form
FormContext.data.refresh(false);
console.log("Form refreshed.");
// Success message to user
FormContext.ui.setFormNotification("Company data has been updated successfully", "INFO", entityId)
} else {
console.log("Flow execution failed or returned non-200 status.");
FormContext.ui.setFormNotification("Error: Could not find any company data. Is the VAT number correct?", "ERROR", entityId)
}
//Clear the success message
setTimeout(function() {
FormContext.ui.clearFormNotification(entityId);
}, 10000);
console.log("Main function completed");
} catch (error) {
console.log(`Main function failed: ${error}`);
} finally {
console.log("Main function stopped");
}
}
Step 9
Let’s go back to our button.
In the command bar click Add library and then select New web resource
Upload your JavaScript file and give it a name. I have called mine updateCompanyData
Step 10
After you have uploaded your new web resource, search for the resource, select it and click add
Step 10
In the command bar menu insert main in function name and under Parameter 1 select PrimaryControl
Step 11
Visibility
We don’t want the button to be available if the form is new (the user has not clicked save), or if the VAT field is empty.
In the command bar menu under visibility, change the value to Show on condition from formula and insert the following code
If(FormMode = FormMode.New || IsBlank(Self.Selected.Item.VAT), false, true)
Change .VAT to the display name of your column, if it is not VAT
The only thing that is left to do is to click Save and Publish
Running the code
After the code has been uploaded, we can now make an update of the company data with a click of a button
If the form is new we won’t show the button just yet
We won’t show the button either if the VAT field is empty
Here the user has inserted the VAT number, and the button update account data is visible - dare we press it?
We ask the user if they want to update the company data
We are now telling the user that the data is being collected (usually takes 1-2 seconds)
Here we have updated the data, and is telling the user it has been updated successfully
Here we are telling the user that a company could not be found (since the VAT is wrong)
I am sure you can find equivalent API services for VAT in your country. If not, I recommend you try openweathermap.org so that you can always update the current weather for the company you are going to visit next
And finally a little disclaimer - I am a low-code dude, the code above might not be 100% correct - this blog is just me trying to share what I am learning :)
See also
- Refresh SharePoint list data fast in Power BI
- Create dynamic dates in Power BI with OData
- Update metadata for locked/checked out/need approval files
- Disable the folder ID for SharePoint document integration
- Trigger a Power Automate Flow with modern ribbon, with a custom button in Dynamics 365 (not Ribbon Workbench)