I've been developing an app to provide better reporting for my company using Google Sheets and Appscripts. The MVP is working out pretty well so far.
I'm trying to add some capabilities in regards to contact web conversion activities and have been using CRM V3 to get all relevant contact properties and in the process ran into a rather humorous error message. I couldn't find any references on Google so I guess I'm lucky?
"Exception: Request failed for https://api.hubapi.com returned code 400. Truncated server response: {"status":"error","message":"Exception while calling underlying service. This is not peano's fault."
I think this has to do with paging beyond 10,000 in CRM V3 but I'm not sure. Any thoughts?
{"status":"error","message":"Exception while calling underlying service. This is not peano's fault.","correlationId":"b9a67789-16b5-4406-a40b-cd7295a1ee3e","category":"VALIDATION_ERROR"}
I'm using the python API provided by hubspot and getting all contacts from hubspot.
This error doesn't make any sense, since sometimes it works and sometimes it doesn't, without changing any code.
I'm fixing this error by only stopping my server app and running it again, with the same code.
Could at least hubspot provide better error messages?
For context, the peano's fault error could be due to anything. In this case, I have reached out to our internal team and we are looking to unwrap peano errors so that it returns a standard and meaningful error mesages.
No worries, this has been a ton of fun! I suspect the error message is an easter egg planted by one of your more senior programmers as I am guessing it relates to Giuseppe Peano, a famous mathematician from the 19th century.
This is above my paygrade but from what I understand, Peono is sort of the Pythagoras of natural numbers. The axiomatization of natural numbers looks a lot like the precursors to an iterator. While I can't speak for Rodrigo, I suspect my error came about because I ran into the API query limit of 10,000.
Thanks again Wendy, and looking forward to hearing Peono's story.
Exception: Request failed for https://api.hubapi.com returned code 400. Truncated server response: {"status":"error","message":"Exception while calling underlying service. This is not peano's fault.","correlationId":"6c666214-ee88-42b7-94c6-ff1a0... (use muteHttpExceptions option to examine full response) at getConversions(Code:491:32)
I don't have the original code that generated that error because I have moved on to a different strategy. Rather than trolling through all 22k contacts, I'm using CRM V3 Search function so now I have a new problem lol. Whereas before I was using the GET method, search uses the POST method which I am less familiar with when it comes to AppScripts.
I am able to get a response via Postman but not in Appscripts. The error I get now is "Authentication credentials not found." which makes me think that my token is not being passed into the query parameter. Here's the code:
function getConversions() {
// Prepare authentication to Hubspot
var service = getService();
var headers = {headers: {'Authorization': 'Bearer ' + service.getAccessToken()}};
Logger.log(headers);
var raw = JSON.stringify({"filterGroups":[{"filters":[{"propertyName":"hs_analytics_last_visit_timestamp","operator":"GT","value":"1561514165666"}]}],"limit":100,"after":0});
var options = {
'method' : 'post',
headers: headers,
'contentType': 'application/json',
// Convert the JavaScript object to a JSON string.
body : raw,
redirect: 'follow',
"muteHttpExceptions": true
};
var response = UrlFetchApp.fetch('https://api.hubapi.com/crm/v3/objects/contacts/search?', options);
var result = JSON.parse(response.getContentText());
Logger.log(result);
};
Hey Wendy, sorry for the late response, I've been swamped with other work items but I managed to finally solve this confounding problem, I'll be it through trial and error.
I used the link that you sent and started examining JSON object that was being sent to the Hubspot API and indeed there are mutations that happen between what is written in Google App Scripts GAS and the end product.
As an example, GAS has the UrlFetchApp as a Class vs Javascript Fetch and has some material differences like it doesn't have body or redirect as properties. Instead, you have to use payload which is mutated once it is sent. In the same vein, you were onto something when you tried to correct for the content type syntax.
With your help, Tanaike from stack overflow, and a lot of hours the solution included the syntactical changes to the JSON payload as well as changing the authorization to the API key which is how the search query is demonstrated on Hubspot's new developer portal. Reading is winning? In the end, the solution may not be pretty but it works.
// array of people with activities var activePeople = Array(); var keep_going = true; var offset=0;
//a loop that runs through the api response, it also updates the pagination for repeat queries while(keep_going){ //Search query var raw = {"filterGroups":[{"filters":[{"propertyName":"hs_analytics_last_timestamp","operator":"GT","value":"1561514165666"}]}],"properties":["hs_analytics_num_visits","firstname","lastname","company"],"limit":100,"after":offset} //Logger.log(raw.after); //JSON POST Data sent to Hubspot server var options = { method : 'post', contentType: "application/json", // Convert the JavaScript object to a JSON string. payload : JSON.stringify(raw), muteHttpExceptions: true };
// Uses CRM V3's search capability using the API vs Token. Token approach did not work var url = API_URL + "/crm/v3/objects/contacts/search?hapikey=mykey"; var response = UrlFetchApp.fetch(url, options); var result = JSON.parse(response.getContentText()); const pagination=(Math.floor(result.total/100)*100);
keep_going=JSON.stringify(result.paging);
//Logger.log(keep_going); //if(keep_going){Logger.log("thisfired")}else{Logger.log("this never fired")};
Logger.log(offset); Logger.log(options)
// For each deal, we take the stageId, source & amount result.results.forEach(function(person) { var firstName = (person.properties.hasOwnProperty("firstname")) ? person.properties.firstname : "unknown"; var lastName = (person.properties.hasOwnProperty("lastname")) ? person.properties.lastname : "unknown"; var countViews = (person.properties.hasOwnProperty("hs_analytics_num_visits")) ? person.properties.hs_analytics_num_visits : "unknown"; var company = (person.properties.hasOwnProperty("company")) ? person.properties.company : "unknown";