Hubspot API - list of properties needed (nodejs) - node.js

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.

Related

Is there a native way to get MongoDB results as object instead of array?

Checked couple of old similar questions but no luck in finding the right answers.
I have a mongo query that uses await/async to fetch results from the database, So the code looks like this :
(async () => {
//get connection object
const db = await getDatabaseConnection("admindb");
//get user data object
const configResponse = await db.collection("config").find({}).toArray();
//prints results
console.log("Successfully Fetched Configuration", configResponse);
})();
The above code works fine, just that it returns me an array of elements since I have used the .toArray() method.
Sample Result:
[
{
_id: "6028d30db7ea89f74df013d9",
tokenize: false,
configurations: { theme: {} }
}
]
Is there a NATIVE WAY (not looking forEach responses) to get result as an object since I will always have only one document returned. I have multiple queries that returns only one document, Hence accessing using the 0th index everytime did not seem the right way.
I am thinking if the findOne() will help you.
Check this out docs
await db.collection("config").findOne({});
Here are some examples

Node.js Query Parameters for Smartsheet API

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.

In Cloud function how can i join from another collection to get data?

I am using Cloud Function to send a notification to mobile device. I have two collection in Firestore clientDetail and clientPersonalDetail. I have clientID same in both of the collection but the date is stored in clientDetail and name is stored in clientPersonal.
Take a look:
ClientDetail -- startDate
-- clientID
.......
ClientPersonalDetail -- name
-- clientID
.........
Here is My full Code:
exports.sendDailyNotifications = functions.https.onRequest( (request, response) => {
var getApplicants = getApplicantList();
console.log('getApplicants', getApplicants);
cors(request, response, () => {
admin
.firestore()
.collection("clientDetails")
//.where("clientID", "==", "wOqkjYYz3t7qQzHJ1kgu")
.get()
.then(querySnapshot => {
const promises = [];
querySnapshot.forEach(doc => {
let clientObject = {};
clientObject.clientID = doc.data().clientID;
clientObject.monthlyInstallment = doc.data().monthlyInstallment;
promises.push(clientObject);
});
return Promise.all(promises);
}) //below code for notification
.then(results => {
response.send(results);
results.forEach(user => {
//sendNotification(user);
});
return "";
})
.catch(error => {
console.log(error);
response.status(500).send(error);
});
});
}
);
Above function is showing an object like this
{clienId:xxxxxxxxx, startDate:23/1/2019}
But I need ClientID not name to show in notification so I'll have to join to clientPersonal collection in order to get name using clientID.
What should do ?
How can I create another function which solely return name by passing clientID as argument, and waits until it returns the name .
Can Anybody please Help.?
But I need ClientID not name to show in notification so I'll have to join to clientPersonal collection in order to get name using clientID. What should do ?
Unfortunately, there is no JOIN clause in Firestore. Queries in Firestore are shallow. This means that they only get items from the collection that the query is run against. There is no way to get documents from two top-level collection in a single query. Firestore doesn't support queries across different collections in one go. A single query may only use properties of documents in a single collection.
How can I create another function which solely return name by passing clientID as argument, and waits until it returns the name.
So the most simple solution I can think of is to first query the database to get the clientID. Once you have this id, make another database call (inside the callback), so you can get the corresponding name.
Another solution would be to add the name of the user as a new property under ClientDetail so you can query the database only once. This practice is called denormalization and is a common practice when it comes to Firebase. If you are new to NoQSL databases, I recommend you see this video, Denormalization is normal with the Firebase Database for a better understanding. It is for Firebase realtime database but same rules apply to Cloud Firestore.
Also, when you are duplicating data, there is one thing that need to keep in mind. In the same way you are adding data, you need to maintain it. With other words, if you want to update/detele an item, you need to do it in every place that it exists.
The "easier" solution would probably be the duplication of data. This is quite common in NoSQL world.
More precisely you would add in your documents in the ClientDetail collection the value of the client name.
You can use two extra functions in this occasion to have your code clear. One function that will read all the documents form the collection ClientDetail and instead of getting all the fields, will get only the ClientID. Then call the other function, that will be scanning all the documents in collection ClientPersonalDetail and retrieve only the part with the ClientID. Compare if those two match and then do any operations there if they do so.
You can refer to Get started with Cloud Firestore documentation on how to create, add and load documents from Firestore.
Your package,json should look something like this:
{
"name": "sample-http",
"version": "0.0.1",
"dependencies": {
"firebase-admin": "^6.5.1"
}
}
I have did a little bit of coding myself and here is my example code in GitHub. By deploying this Function, will scan all the documents form one Collection and compare the ClientID from the documents in the other collection. When it will find a match it will log a message otherwise it will log a message of not matching IDs. You can use the idea of how this function operates and use it in your code.

Google Datastore not retrieving entities

I have been working with the google cloud library, and I can successfully save data in DataStore, specifically from my particle electron device (Used their tutorial here https://docs.particle.io/tutorials/integrations/google-cloud-platform/)
The problem I am now having is retrieving the data again.
I am using this code, but it is not returning anything
function getData(){
var data = [];
const query = datastore.createQuery('ParticleEvent').order('created');
datastore.runQuery(query).then(results => {
const event = results[0];
console.log(results);
event.forEach(data => data.push(data.data));
});
console.log(data)
}
But each time it is returning empty specifically returning this :
[ [], { moreResults: 'NO_MORE_RESULTS', endCursor: 'CgA=' } ]
, and I can't figure out why because I have multiple entities saved in this Datastore.
Thanks
In the tutorial.js from the repo mentioned in the tutorial I see the ParticleEvent entities are created using this data:
var obj = {
gc_pub_sub_id: message.id,
device_id: message.attributes.device_id,
event: message.attributes.event,
data: message.data,
published_at: message.attributes.published_at
}
This means the entities don't have a created property. I suspect that ordering the query by such property name is the reason for which the query doesn't return results. From Datastore Queries (emphasis mine):
The results include all entities that have at least one value for
every property named in the filters and sort orders, and whose
property values meet all the specified filter criteria.
I'd try ordering the query by published_at instead, that appears to be the property with a meaning closest to created.

Hoodie - Update a CouchDB document (Node.js)

I'm handling charges and customers' subscriptions with Stripe, and I want to use these handlings as a Hoodie plugin.
Payments and customer's registrations and subscriptions appear normally in Stripe Dashboard, but what I want to do is update my _users database in CouchDB, to make sure customer's information are saved somewhere.
What I want to do is updating the stripeCustomerId field in org.couchdb.user:user/bill document, from my _users database which creates when logging with Hoodie. And if it is possible, to create this field if it does not exist.
In hoodie-plugin's document, the update function seems pretty ambiguous to me.
// update a document in db
db.update(type, id, changed_attrs, callback)
I assume that type is the one which is mentioned in CouchDB's document, or the one we specify when we add a document with db.add(type, attrs, callback) for example.
id seems to be the doc id in couchdb. In my case it is org.couchdb.user:user/bill. But I'm not sure that it is this id I'm supposed to pass in my update function.
I assume that changed_attrs is a Javascript object with updated or new attributes in it, but here again I have my doubts.
So I tried this in my worker.js:
function handleCustomersCreate(originDb, task) {
var customer = {
card: task.card
};
if (task.plan) {
customer.plan = task.plan;
}
stripe.customers.create(customer, function(error, response) {
var db = hoodie.database(originDb);
var o = {
id: 'bill',
stripeCustomerId: 'updatedId'
};
hoodie.database('_users').update('user', 'bill', o, function(error) {
console.log('Error when updating');
addPaymentCallback(error, originDb, task);
});
db.add('customers.create', {
id: task.id,
stripeType: 'customers.create',
response: response,
}, function(error) {
addPaymentCallback(error, originDb, task);
});
});
}
And between other messages, I got this error log:
TypeError: Converting circular structure to JSON
And my file is not updated : stripeCustomerId field stays null.
I tried to JSON.stringify my o object, but It doesn't change a thing.
I hope than some of you is better informed than I am on this db.update function.
Finally, I decided to join the Hoodie official IRC channel, and they solved my problem quickly.
Actually user.docs need an extra API, and to update them you have to use hoodie.account instead of hoodie.database(name)
The full syntax is:
hoodie.account.update('user', user.id, changedAttrs, callback)
where user.id is actually the account name set in Hoodie sign-up form, and changedAttrs an actual JS object as I thought.
Kudos to gr2m for the fix; ;)

Resources