I use Power Automate and Dynamics for many of my tasks and was excited to see API support.
I created an azure function to calculate the MD5 has which seems to be working well:
Python code:
import hashlib
import json
import azure.functions as func
def main(req: func.HttpRequest) -> func.HttpResponse:
req_body = req.get_json() # Parse the JSON request body
# Access the 'req' field from the JSON payload
if 'req' in req_body:
input_string = req_body['req']
md5_hash = get_md5_hash(input_string)
response_data = {
"req": input_string,
"md5_hash": md5_hash
}
return func.HttpResponse(json.dumps(response_data), headers={"Content-Type": "application/json"})
else:
return func.HttpResponse("Invalid request", status_code=400)
def get_md5_hash(input_string: str) -> str:
md5 = hashlib.md5()
md5.update(input_string.encode('utf-8'))
return md5.hexdigest()
I call this function with the string as told, I use GUID() in power automate to generate a new, random submission ID on every run; the submission would look like this: f2364b6e-3b41-478a-84e2-416e1730afb0
Because I need to have the root node “Payload” I struggle with the API. I create the content (copy / paste from the example provided in the API documentation:
JSON Payload
{
"payload": {
"Header": {
"MessageType": "Request",
"SubmissionNumber": "@{outputs('Submission_No')}",
"Authentication": {
"AccNumber": "@{outputs('Account')}",
"MD5Value": "@{outputs('MD5_Hash_Value')}",
"ApplicationID": "@{outputs('Application_ID')}"
}
},
"Body": {
"InvoiceData": {
"InvoiceType": "INVOICE",
"ClientID": "1343151",
"ClientAddress": {
"Address": "123 Test Street<br/>Manchester<br/>MA1 5TH<br/>United Kingdom",
"CountryISO": "GB"
},
"Currency": "GBP",
"TermDays": "14",
"Language": "en",
"InvoiceLines": {
"ItemLines": {
"ItemLine": [
{
"ItemID": "0",
"ItemName": "BC1",
"ItemDescription": "300 Business Cards (250gsm)",
"ItemNominalCode": "4000",
"Tax1": {
"TaxName": "VAT",
"TaxPercentage": "20.00",
"TaxAmount": "20"
},
"UnitCost": "100",
"Qty": "1"
},
{
"ItemID": "0",
"ItemName": "EMB1",
"ItemDescription": "Embossing Stamp",
"ItemNominalCode": "4000",
"Tax1": {
"TaxName": "VAT",
"TaxPercentage": "20.00",
"TaxAmount": "10"
},
"UnitCost": "50",
"Qty": "1"
}
]
}
},
"Scheduling": {
"SingleInvoiceData": {
"IssueDate": "2023-07-07",
"PurchaseReference": "0095446"
}
}
}
}
}
}
I transfer the body through http to another azure function to forward this without injecting a header, body or changing the root node:
import json
import logging
import azure.functions as func
import http.client
def main(req: func.HttpRequest) -> func.HttpResponse:
try:
# Read the body of the HTTP request
req_body = req.get_body().decode('utf-8')
# Construct the payload for the API
api_payload = req_body
# Send the payload to the API
api_url = "api.quickfile.co.uk:443"
endpoint = "/1_2/invoice/create"
connection = http.client.HTTPSConnection(api_url)
connection.request("POST", endpoint, api_payload)
response = connection.getresponse()
status_code = response.status
response_body = response.read().decode('utf-8')
if status_code == 200:
response_msg = "Payload sent successfully"
else:
response_msg = f"API request failed with status code: {status_code}"
return func.HttpResponse(
body=response_msg,
status_code=status_code,
headers={"Content-Type": "text/plain"}
)
except Exception as e:
logging.error(str(e))
return func.HttpResponse("Internal Server Error", status_code=500)
I receive an error 400 from the API and no further information / text.
If I would not need the root node “payload” I could use the default header and body http post function in power automate.
Has anyone solved this to connect the quickfile API with the microsoft power automate world? Happy for any other approach that may be worth exploring.