3

Having eventually figured out the Zoho OAuth authentication, I'm now faced with trying to debug their error codes when attempting to insert a new record.

<cfsavecontent variable="JSONData">
{
  "data": { 
    "Last_Name": "Smith",
"First_Name": "John",
    "Email": "john@smith.com",
    "Phone": "0123456789",
    "Lead_Source": "PPC",
"Build_Cost_text": "50",
"Estimated_Sales_Value": "100",
"Stage_of_Build_Work": "Not Started",
"Work_Starting_Date_text": "01/06/2021",
"Number_of_Units": "1",
"Address_of_Development": "123 Any Street",
"Gross_floor_area_m2": "100",
"Development_Use": "Self Build",
"Please_share_any_additional_information": "Just testing stuff",
    "Company": "Smith Widgets"
      }
  }
</cfsavecontent>


<cfhttp method="POST" url="https://www.zohoapis.com/crm/v2/Leads" result="zohopostresult">
<cfhttpparam type="header" name="Authorization" value="Zoho-oauthtoken #gettoken.access_token#">
<cfhttpparam type="header" name="content-type" value="application/json" />
<cfhttpparam type="body" value="#JSONData#" />
</cfhttp>

The error returned using the above code is;

{"code":"INVALID_DATA","details":{"expected_data_type":"jsonarray","api_name":"data"},"message":"invalid data","status":"error"}

If I use cfdump / deserializeJSon to review the 'JSONData' variable, it outputs just fine. I've been looking at this all day, so I might well be missing something that's staring me in the face.

Lee
  • 989
  • 2
  • 14
  • 30

1 Answers1

6

For the sake of sanity, don't use <cfsavecontent>, use <cfset>.

<cfset payload = {
    "data": {
        "Last_Name": "Smith",
        "First_Name": "John",
        "Email": "john@smith.com",
        "Phone": "0123456789",
        "Lead_Source": "PPC",
        "Build_Cost_text": "50",
        "Estimated_Sales_Value": "100",
        "Stage_of_Build_Work": "Not Started",
        "Work_Starting_Date_text": "01/06/2021",
        "Number_of_Units": "1",
        "Address_of_Development": "123 Any Street",
        "Gross_floor_area_m2": "100",
        "Development_Use": "Self Build",
        "Please_share_any_additional_information": "Just testing stuff",
        "Company": "Smith Widgets"
    }
}>

<cfdump var="#payload#">

<cfhttp method="POST" url="https://www.zohoapis.com/crm/v2/Leads" result="zohopostresult">
  <cfhttpparam type="header" name="Authorization" value="Zoho-oauthtoken #gettoken.access_token#">
  <cfhttpparam type="header" name="content-type" value="application/json" />
  <cfhttpparam type="body" value="#SerializeJSON(payload)#" />
</cfhttp>

Note that payload will be a struct - ColdFusion supports struct literal syntax, which incidentally also accepts JSON's format.

In order to send the data as JSON, you need to serialize it from struct to string. That's what SerializeJSON(payload) is for.

The error is pretty clear.

"expected_data_type":"jsonarray"

So you need to send an array, not an object. I don't know Zoho's API definitions, but my guess would be either

<cfset payload = {
    "data": [{
        ...
    }]
}>

or

<cfset payload = [{
    "data": {
        ...
    }
}]>
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • You were indeed correct - I was missing the brackets (after "data", rather than before). My original code actually worked once I'd added those, but this alternative approach works too. – Lee Jun 02 '21 at 07:28
  • 3
    @Lee Yeah, they are the exact same approach, really. The variant using native ColdFusion data structures and -syntax + `SerializeJSON()` is just more maintainable and less error-prone than ``. – Tomalak Jun 02 '21 at 08:04