Hello all,
I am working to create a Webhook for a Hosted Feature Service in ArcGIS Online that will use Microsoft Power Automate to send emails when a HTTP request is received. I want to receive emails when a feature service is edited, but I am having trouble with my payload schema for the HTTP request (receiving a "BadRequest" error). I am wondering if anyone has done this and can share what their JSON payload schema consisted of.
Thanks,
Henry
Instead of using the payload option, just copy/paste directly into the Request Body JSON Schema window.
An Example:
You might want to edit your Change Types to call out the subscriptions directly. I'd also double check that the HookUrl is the same on AGOL as in your flow.
I made the update to the Change Types and re-copy/pasted the Hook Url. Still no test results after making a change to the feature service. I am so stumped on what I am doing wrong!
I wanted to add to the great information already provided here.
To avoid Bad Requests, try removing any actions that sends alerts or messages or otherwise connects to Microsoft Office or teams, mail etc.
Due to a bug (wrong content-type) I have found that these actions can cause Bad Requests when getting requests from a live Feature service WebHook trigger. This can be deceiving as it usually works well in test mode (when using a previous successful test request).
If you have a need to have alerts as par of your workflows, maybe a workaround would be to have another flow handling only the alert/message piece.
I was able to create a working Flow package (with no alerts) that completes the following workflow:
- handles request with Payload
- gets token
- query URL returning final JSON with feature changes.
The actions json are below. Just export/change/import into new Flow and change credentials within.
Hopefully it will help those interested handling feature service changes with Power Automate.
{ "actions": { "Parse_JSON": { "runAfter": { "Initialize_variable_-_STATUS": [ "Succeeded" ] }, "type": "ParseJson", "inputs": { "content": "@triggerBody()?['$formdata']", "schema": { "type": "array", "items": { "type": "object", "properties": { "key": { "type": "string" }, "value": { "type": "string" } }, "required": [ "key", "value" ] } } } }, "Apply_to_each": { "foreach": "@body('Parse_JSON')", "actions": { "Parse_JSON_2": { "runAfter": {}, "type": "ParseJson", "inputs": { "content": "@items('Apply_to_each')['value']", "schema": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "layerId": { "type": "integer" }, "orgId": { "type": "string" }, "serviceName": { "type": "string" }, "lastUpdatedTime": { "type": "integer" }, "changesUrl": { "type": "string" }, "events": { "type": "array", "items": { "type": "string" } } }, "required": [ "name", "layerId", "orgId", "serviceName", "lastUpdatedTime", "changesUrl", "events" ] } } } }, "HTTP": { "runAfter": { "Parse_JSON_2": [ "Succeeded" ] }, "type": "Http", "inputs": { "method": "POST", "uri": "https://www.arcgis.com/sharing/rest/generateToken", "headers": { "Content-Type": "application/x-www-form-urlencoded" }, "body": "username=@{variables('Username')}&password=@{variables('Password')}&f=json&referer=http://arcgis.com" } }, "Parse_JSON_3": { "runAfter": { "HTTP": [ "Succeeded" ] }, "type": "ParseJson", "inputs": { "content": "@body('HTTP')", "schema": { "properties": { "expires": { "type": "integer" }, "ssl": { "type": "boolean" }, "token": { "type": "string" } }, "type": "object" } } }, "Apply_to_each_2": { "foreach": "@body('Parse_JSON_2')", "actions": { "HTTP_2": { "runAfter": {}, "type": "Http", "inputs": { "method": "POST", "uri": "@{items('Apply_to_each_2')['changesUrl']}&token=@{body('Parse_JSON_3')?['token']}&f=json", "headers": { "Content-Type": "application/x-www-form-urlencoded" } } }, "Parse_JSON_4": { "runAfter": { "HTTP_2": [ "Succeeded" ] }, "type": "ParseJson", "inputs": { "content": "@body('HTTP_2')", "schema": { "type": "object", "properties": { "statusUrl": { "type": "string" } } } } }, "Do_until": { "actions": { "HTTP_3": { "runAfter": {}, "type": "Http", "inputs": { "method": "POST", "uri": "@{body('Parse_JSON_4')?['statusUrl']}?token=@{body('Parse_JSON_3')?['token']}&f=json", "headers": { "Content-Type": "application/x-www-form-urlencoded" } } }, "Parse_JSON_5": { "runAfter": { "HTTP_3": [ "Succeeded" ] }, "type": "ParseJson", "inputs": { "content": "@body('HTTP_3')", "schema": { "type": "object", "properties": { "submissionTime": { "type": "integer" }, "lastUpdatedTime": { "type": "integer" }, "status": { "type": "string" }, "responseType": { "type": "string" }, "resultUrl": { "type": "string" } } } } }, "Set_variable": { "runAfter": { "Parse_JSON_5": [ "Succeeded" ] }, "type": "SetVariable", "inputs": { "name": "Status", "value": "@body('Parse_JSON_5')?['status']" } }, "Condition": { "actions": { "HTTP_4": { "runAfter": {}, "type": "Http", "inputs": { "method": "POST", "uri": "@{body('Parse_JSON_5')?['resultUrl']}?token=@{body('Parse_JSON_3')?['token']}&f=json", "headers": { "Content-Type": "application/x-www-form-urlencoded" } } }, "Parse_JSON_6": { "runAfter": { "HTTP_4": [ "Succeeded", "Failed" ] }, "type": "ParseJson", "inputs": { "content": "@outputs('HTTP_4')['headers']", "schema": { "type": "object", "properties": { "location": { "type": "string" } } } } }, "HTTP_5": { "runAfter": { "Parse_JSON_6": [ "Succeeded" ] }, "type": "Http", "inputs": { "method": "GET", "uri": "@body('Parse_JSON_6')?['location']" } }, "Compose": { "runAfter": { "HTTP_5": [ "Succeeded" ] }, "type": "Compose", "inputs": "@base64ToString(body('HTTP_5')?['$content'])" }, "Parse_JSON_7": { "runAfter": { "Compose": [ "Succeeded" ] }, "type": "ParseJson", "inputs": { "content": "@outputs('Compose')", "schema": { "type": "object", "properties": { "layerServerGens": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer" }, "serverGen": { "type": "integer" } }, "required": [ "id", "serverGen" ] } }, "transportType": { "type": "string" }, "responseType": { "type": "string" }, "edits": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer" }, "features": { "type": "object", "properties": { "adds": { "type": "array", "items": { "type": "object", "properties": { "geometry": { "type": "object", "properties": { "x": { "type": "number" }, "y": { "type": "number" } } }, "attributes": { "type": "object", "properties": { "OBJECTID": { "type": "integer" }, "GlobalID": { "type": "string" }, "REQUESTID": {}, "PROBLEM": {}, "COMMENTS": {}, "NAME": {}, "PHONE": {}, "EMAIL": {}, "REQUESTDATE": {}, "STATUS": {}, "FACILITYKEY": {}, "CreationDate": { "type": "integer" }, "Creator": { "type": "string" }, "EditDate": { "type": "integer" }, "Editor": { "type": "string" } } } }, "required": [ "geometry", "attributes" ] } }, "updates": { "type": "array" }, "deleteIds": { "type": "array" } } }, "attachments": { "type": "object", "properties": { "adds": { "type": "array" }, "updates": { "type": "array" }, "deleteIds": { "type": "array" } } } }, "required": [ "id", "features", "attachments" ] } } } } } }, "Set_variable_2": { "runAfter": { "Parse_JSON_7": [ "Succeeded" ] }, "type": "SetVariable", "inputs": { "name": "Status", "value": "\"Completed\"" } } }, "runAfter": { "Set_variable": [ "Succeeded" ] }, "expression": { "not": { "equals": [ "@body('Parse_JSON_5')?['resultUrl']", "" ] } }, "type": "If" } }, "runAfter": { "Parse_JSON_4": [ "Succeeded" ] }, "expression": "@equals(variables('Status'), '\"Completed\"')", "limit": { "count": 60, "timeout": "PT1H" }, "type": "Until" } }, "runAfter": { "Parse_JSON_3": [ "Succeeded" ] }, "type": "Foreach" } }, "runAfter": { "Parse_JSON": [ "Succeeded" ] }, "type": "Foreach" }, "Initialize_variable_-_STATUS": { "runAfter": { "Password": [ "Succeeded" ] }, "type": "InitializeVariable", "inputs": { "variables": [ { "name": "Status", "type": "string", "value": "Pending" } ] } }, "Password": { "runAfter": { "Username": [ "Succeeded" ] }, "type": "InitializeVariable", "inputs": { "variables": [ { "name": "Password", "type": "string", "value": "Password_Goes_Here!" } ] } }, "Username": { "runAfter": {}, "type": "InitializeVariable", "inputs": { "variables": [ { "name": "Username", "type": "string", "value": "Username_Goes_Here!" } ] } } } }
Thank you very much for this information and the detailed response. This was very helpful and I appreciate you taking the time to provide this information.
I am hoping you can expand a bit on how to "have another flow handling only the alert/message piece"? Sending alerts as a part of our flow is ultimately the goal for our WebHook work flow. I am wondering how a separate flow that handles the alerts will be able to communicate with the other flow that handles the HTTP request and parsing the json?
Thank you again,
-Henry
For the past few days, I have encountered an error on the first module When a HTTP request is received : BadRequest.
This issue seems to come from the JSON schema of the request body predefined during my configuration. @Anonymous User, would Esri have recently modified the request sent by the webhook (e.g Content-Type header)?
I solved this issue by removing the JSON schema of the request body (leave blank) in my first module.
Hi @hgaignard I was not able to repro this with JSON schema in the HTTP module:
{
"type": "object",
"properties": {
"$content-type": {
"type": "string"
},
"$content": {
"type": "string"
},
"$formdata": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": [
"key",
"value"
]
}
}
}
}
I tried a couple of different change types with no issues. Are you still seeing the issue?
Thanks,
-Peter
I just reproduced the error with the schema you provided.
The issue stems from flows which also include connectors like Teams, Outlook, etc.
@PhilLarkin1, I confirm, if I delete my last Outlook module, I no longer have the "BadRequest" error for the first HTTP module with a predefined JSON schema.
To keep the Outlook module, I need to remove the JSON schema from the first HTTP module.
But it worked before...