Search code examples
pythonazure-function-appxero-api

Xero API Webhook Server using Python and Azure functions


I am working with Azure Function Apps to receive webhooks from Xero for processing. However, I am getting stuck with my HASH not being computed correctly.

I think it something to do with the way Python is processing the Body Request.

Here is the code:

#import Logging module to log errors to console
import logging

#import Azure Functions
import azure.functions as func

#import Cryptopackages
import hmac
import hashlib
import base64

#import JSON
import json

XERO_KEY = 'key here'

#function to generate key
def create_sha256_signature(key, message):
    messagecoded = bytes(message, 'UTF-8')
    return base64.b64encode(hmac.new(key.encode(), messagecoded, digestmod=hashlib.sha256).digest()).decode()

#Define Main function - Recieve a HTTP reponse
def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Recieved a Request from Xero')
    
    #Parse HASH Key from Header
    xerosign = req.headers.get('x-xero-signature')
    logging.info(xerosign)
    
    #Get JSON body
    Data = req.get_body()
    Body = Data
    #Body = json.dumps(payload, separators=(",", ":")).strip()
    logging.info(Body)
    
    #Get Signature from defined function
    signature = create_sha256_signature(XERO_KEY, str(Body))
    
    logging.info(signature)
    logging.info(xerosign)

    if hmac.compare_digest(xerosign, signature):
        return func.HttpResponse(
            status_code=200)
    else:
        return func.HttpResponse(
            status_code=401
            )

Body Request is

{
    "events": [],
    "lastEventSequence": 0,
    "firstEventSequence": 0,
    "entropy": "TXHKKDMKUHWFBYTVJSQU"
}

Header x-xero-signature = C7G5M2SVxs/fAJM8fFLahzex32Rr7jwMHixX/OgvkFQ=


Solution

  • after reviewing what Rett Behrens put through and some more digging into the way the Azure Function App handles data. I have a working solution leveraging Node.js, it terms out the way Microsoft handles an API response, if you don't put in "body":"" it automatically responses with the body from the initial post request. Hence causing the problem where Xero excepts an empty body.

    https://github.com/mast3rbow/Xero-Functionapp

    The github repo includes my working examlpe and will enable a business to send Xero Events directly to Microsoft Power Automate to do some logic handling there.