I am trying to send include parameters with a get-sheet request smartsheet.sheets.getSheet(options) using the Node.js sdk. The API documentation is vague on how to add the include parameters in the API call.
I found a Smartsheet Developers Blog post Demystifying Query Parameters in the Smartsheet API that provides more guidance, but the Node.js example code they provide is invalid javascript:
// Set options
var options = {
queryParameters: {
include: "attachments",
include: "source",
includeAll: true
}
};
// List sheets
smartsheet.sheets.listSheets(options)
.then(function(response) {
...
In the above code the last include query parameter will override all of the prior values and you will be left with a options variable that looses the "attachements" parameter:
queryParameters: {
include: "source",
includeAll: true
}
To me the obvious solutions would be for include to take an array like:
include: ["attachments", "source"],
Any suggestions?
Outside of using the SDK whatever values needed for the include query string are added to the URL as a comma separated list. The SDK will take the value you provide for the include parameter of the queryParameters object and add that as the value for the include query string and append it to the URL.
Instead of providing the include parameter multiple times in the queryParameters object or providing an array you would give a single string value for include with all of the options you wish to use comma separated.
For example, a GET Sheet request that asks for the source info and attachments to be included would look like this:
const options = {
id:<SHEET_ID>,
queryParameters : {
include: 'source,attachments',
includeAll: true
}
}
smartsheet.sheets.getSheet(options)
.then(sheet => {
console.log(sheet);
})
.catch(err => {
console.log(err);
})
Note, the includeAll query string is for pagination and can be used separately to have all rows of the sheet included in the response.
Also, if you are running test requests in your console and set logLevel: 'info' when creating your Smartsheet client with the access token you can see the URL being used for the request get printed out above the sheet data response and it will show you how the URL is being structured.
Related
I am integrating the hubspot API to track user interaction with our site. I am creating dynamic lists and I want to filter a user into a certain contact list by which URL they visit.
"filters": [
[
{
"operator": "CONTAINS",
"property": "hs_URL",
"value": `${id}`
},
],
]
I keep getting this error for all my attempts:
{"status":"error","message":"Couldn't find a Property with the given name 'hs_URL'","correlationId":"0723dcee-534b-4f92-9104-509d6885abbe","propertiesErrorCode":"PROPERTY_NOT_FOUND"},
I cannot seem to find a master property list and have tried many string combinations. Anyone familiar with hubspot property lists would be my savior.
Thank you~!
It's been a few months, so you may not need this anymore, but since I landed here while looking for a way to get all the properties from an object type in hubspot using nodejs, this might help others looking for the solution.
The master list of properties can be retrieved with the following API call:
const response = await hubspotClient.crm.properties.coreApi.getAll(objectType, false);
The arguments for getAll() expect:
objectType: a string, i.e "contacts".
archived: a boolean, i.e false. Set this true if you want to get archived properties.
The following code was adapted based on this page from the hubspot API docs:
https://developers.hubspot.com/docs/api/crm/properties
Once you're on the page, you can click on the "Endpoints" Tab to reveal code snippets for multiple environments, including nodejs.
For this example, getProperties(), retrieves all properties for a given object type. I used contacts for the object type, which I believe is where you are storing the url property, but you could use the same function to get properties for other object types such as companies or deals.
It might be worth noting that I mapped the results to return just the property names, which sounds like all you need for your case, but more information is contained in the results if you need it. Just remove this bit to get more information on each property:
.map(prop => prop.name)
const hubspot = require('#hubspot/api-client')
const hubspotClient = new hubspot.Client({ apiKey: "YOUR_API_KEY" })
const getProperties = async (objectType) => {
try {
const response = await hubspotClient.crm.properties.coreApi.getAll(objectType, false);
return response.body.results.map(prop => prop.name);
} catch (e) {
e.message === 'HTTP request failed'
? console.error(JSON.stringify(e.response, null, 2))
: console.error(e);
}
}
Here's an example for running the function to get a list of all property names for contacts.
(async () => {
var properties = await getProperties("contacts");
console.log(JSON.stringify(properties ,null,2));
})();
It took me a bit to find this, so figured I would post here in the hopes it saves time for someone else. This is the first time I've posted a solution, and I'm pretty new to this API and Hubspot in general, so feedback and/or better solutions are welcome. Cheers.
I am new to Javascript.
I am developping an API to retrieve information from MySQL with :
Node.js
Express
Sequelize
I developed the following controller based on a Sequelize finder (findByPk, to retrieve information by a primary key). There are several nested includes.
exports.findByPk = (req, res) => {
Poi.findByPk(req.params.id,{
attributes: [
'name',
'description'
],
include: [{
model: Source,
attributes: ['originalId'],
where: {source: 'google'}
},{
...
}]
})
.then(data => {
res.send(data);
})
};
As far as I understand, the finder outputs a relatively complex Sequelize instance object data which is passed in res.send (but the API gives access to a proper Json).
I need to postprocess data before passing the result in res.send :
I need to retreive information from a Google API using the data fields, and add this information to the API output
I need to compute some values based on the data fields, and add these values to the API output (long story short, it cannot be part of the Sequelize query because of a known issue in Sequelize)
How to retrieve the values I need from data ? Should I treat it as a regular javascript object, understand its structure, and manually retrieve the values I need ? Or are there methods for that ?
After that, how to add information to data ? Should I actually add information to data, or create a new object ? Should it be a Sequelize object or can it be a regular json-like javascript object ?
Thank you very much
You can just turn data (that is actually an instance of the Poi Sequelize model) into a plain JS object and afterwards work with it in a regular way:
.then(data => {
const plainObject = data.get({ plain: true });
plainObject.newProp = 1
// some work here including accessing Google API
...
res.json(plainObject);
I have a button on the Purchase Order record that performs a saved search query on the current record and then uses the http module to send that data via a POST to a url. That url then sends the data posted back as part of the success confirmation. The idea with the saved search is to create a javascript object that contains all the data that I want from the purchase order (main record and items sublist with subrecords) and then to use JSON.stringify to create a JSON payload for the http POST. I can't do this with the currentRecord because if you inspect it it only contains the internal id. This would also prevent me from having to go to the great lengths of writing a lot of code to manually build up a JSON string from the currentRecord.
Unfortunately I don't really understand how to specify the column names in the dynamically created saved search. Sometimes it looks to me like the column names are those from the NetSuite Records Browser and other times the script gives an error (column not found) if I use a column name from the NetSuite Records Browser (for example currencysymbol).
I'm also not sure how to specify columns that appear in sublists or subrecords in sublists. I tried to use item.itemtype but this gave me a column not found error. Just item completes successfully but I'm not sure whether this was really successfull since it is difficult to decode the returned result after the JSON.stringify (it adds a lot of backslashes). Using console.log (for some reason I don't get anything back using the NetSuite log.audit) is also quite difficult, although it looks like it is returning an array with 5 rows. So using item might sort of be successful. I say sort of because I have 3 item lines and it is returning 5 array rows.
So basically I would like to know where one can find the names of the columns to use in NetSuite for a saved search; and also how to specify sublist column names and sublist subrecord column names in a saved search.
/**
* #NApiVersion 2.0
* #NScriptType ClientScript
* #NModuleScope SameAccount
*/
define(['N/ui/dialog', 'N/currentRecord', 'N/record', 'N/url', 'N/http', 'N/search'], function (dialog, rec, record, url, http, s) {
function pageInit(context) {
// All client scripts need at least one dummy function.
} // pageInit
function onButtonClick() {
var currentRecord = rec.get();
// Create a saved search dynamically.
var rs = s.create({
type: s.Type.PURCHASE_ORDER,
filters: [
["mainline", s.Operator.IS, "F"], "and",
["internalid", s.Operator.IS, currentRecord.id]
],
columns: [
"internalid",
"currency",
{
name: "item",
sort: s.Sort.ASC // DESC
}
]
});
var myPostDataObj = rs.run().getRange(0, 1000);
console.log(myPostDataObj);
var headers = {
'Content-Type': 'application/json; charset=utf-8',
};
http.post.promise({
url: 'http://httpbin.org:80/post',
body: JSON.stringify(myPostDataObj),
headers: headers
})
.then(function(response){
console.log('SUCCESS: ' + JSON.stringify(response));
})
.catch(function onRejected(reason) {
console.log('ERROR: ' + JSON.stringify(reason));
})
}
return {
pageInit: pageInit,
onButtonClick: onButtonClick
};
}); // Define
There are two Chrome extensions I suggest you get;
NetSuite Field Explorer. This extension will show you the ids (and values) of all the fields in a NetSuite record.
NetSuite Search Export. This extension will convert/export a saved search to SuiteScript.
For what you're doing, I would create your saved search in the UI, and then export it using the Saved Search Export extension, paste that into your code (where s.create is), and work from there.
The first extension is nice to get to the sublist field ids. Saves a lookup in the record browser.
In nodejs I am trying to filter podio data by using FilterItems its working fine but its not giving files attributes. I can get the files count but I need uploaded files details. Here is my sample code
var Podio = require('podio-js').api;
var podio = new Podio({
authType: 'server',
clientId: 'XXXXX',
clientSecret:'*****************'
});
podio.authenticateWithApp('XXXXX', 'YYYYYYYYYYYYYY', function(err) {
podio.request('POST', '/item/app/XXXXX/filter', {
"filters": { "email":'sample#gmail.com'}
}).then(function(responseData) {
console.log(responseData);
}).catch(function(e) {
console.log(e);
});
});
To solve this problem am doing one more call Get Item by using Item-id (Which I have received from filter call).
Here my question is why filter method is not giving files details whether its bug in podio filter call or is there any specific reason. Please suggest better way too.
Note: In my scenario I should use only filter functionality;
You can get additional fields (including files) by bundling responses using fields parameter. It's described here: https://developers.podio.com/index/api
Sample:
// Include files when getting filtered items
/item/app/{app_id}/filter/?fields=items.fields(files)
I'm using express and multer. In the following the files are in a random order. The order of the files is important to this particular request. How can I obtain the original order from the request? All I need is an array of original names.
/* POST Put user items. */
router.post('/put', upload.array('useritem'), function (req, res, next) {
// req.files is always in a different order.
});
Node doesn't guarantee the index order of arrays. See this question for more info: Nodejs Order of properties guarantee
As pointed out emphatically, my statement above is incorrect. The correct statement would have been that you should not relay on the order of properties in an object if you have used JSON.stringify() to convert the object to JSON and then sent it as the payload of a request.
Although my original statement is apparently incorrect, it is a problem I've run into myself — where array values show up in the wrong order on my server — and I solved it like illustrated below. Amit's suggestion in the comments above could be the source of the problem. Specifically that it's your client side javascript that's not originally entering the files in the order you'd expect.
Whatever the cause, you'll have to do some work on the client side to add an 'artificial' index to each file and then pass them through as an array of objects.
So instead of this:
var files = ['file1.jpg','file2.jpg','file3.jpg'];
You'll need to pass an object to your backend like so:
var files = [
{ index : 0, file : 'file1.jpg' },
{ index : 1, file : 'file2.jpg' },
{ index : 2, file : 'file3.jpg' },
];
And then you'll need to sort the array of objects once it's received by your backend instance, like so:
files.sort(function(a, b) {
return a.index - b.index;
});
And then you can loop through the files array and do what you will:
var justFiles = [];
async.each(files, function(file, iterate){
justFiles.push(file.file);
return iterate();
}, function(result){
console.log(justFiles);
});
And the output would be:
'file1.jpg','file2.jpg','file3.jpg'