Hello, everybody!
I am having a really difficult time validating requests from HubSpot using the v3 request signature.
Here is the HubSpot documentation:
Basically, it says:
- Create a UTF-8-encoded string that concatenates requestMethod + requestURI + requestBody + timestamp
- Create an HMAC SHA-256 hash of the resulting string using the application secret for the HMAC function.
- Base64 encode the result of the HMAC function
- Compare the hash value to the “x-hubspot-signature-v3” header. If the values are equal, this request is valid.
Assumptions:
- I have tried using just the path, but I think requestURI should take the form “https://www.mysite.com/path/to/endpoint”.
- “application secret” === dev account > app > “Auth” tab > “Client secret”.
I would like to benefit from the experience of somebody here who has already dealt with this and can show me what I’m doing wrong. Barring that, I invite you to look at my code, spot errors, suggest improvements, etc., and thank you so much in advance!
Here’s my code:
uri = "#{scheme}://#{host}#{args["req_path"]}"
body = params |> Jason.encode!()
# Create a string that concatenates together the following:
# Request Method + Request URI + Request Body + Timestamp
val_str = Enum.join([method, uri, body, timestamp], "")
# Create a SHA-256 hash of the resulting string.
hash =
:crypto.mac(:hmac, :sha256, secret, val_str)
|> Base.encode64()
# Compare the hash value to the signature.
x_hubspot_signature == hash
And here’s what my code produces:
X HUBSPOT v3 SIGNATURE: "++IdcWvpfaPQ85JZ3LIYR9YqAm0J2Zy1H5kD6tAgtY0="
VALIDATION STRING: "POSThttps://my_domain.com/api/v1/hs_send_msg{\"callbackId\":\"ap-xxxxxxxx-xxxxxxxxxxxxx-9-0\",\"context\":{\"source\":\"WORKFLOWS\",\"workflowId\":xxxxxxxxx},\"fields\":{\"Contact's Mobile Number\":\"+12345678910\",\"Message\":\"Some test string\",\"Org\":\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - stag\"},\"inputFields\":{\"Contact's Mobile Number\":\"+12345678910\",\"Message\":\"Some test string\",\"Org\":\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - stag\"},\"object\":{\"objectId\":xxxxxxx,\"objectType\":\"CONTACT\"},\"origin\":{\"actionDefinitionId\":12345678,\"actionDefinitionVersion\":1,\"actionExecutionIndexIdentifier\":{\"actionExecutionIndex\":0,\"enrollmentId\":1234567891011},\"extensionDefinitionId\":xxxxxxxx,\"extensionDefinitionVersionId\":1,\"portalId\":xxxxxxxx}}1728041677019"
HASH: "g3wm5qs11huc08xdtp1iy+v97n5dvmx5qqcm83js5y8="
I realize you can’t actually test this, but if you can see what I’m doing wrong, that would be so helpful!
Again, thanks in advance!