Giter Site home page Giter Site logo

node-hubspot's People

Contributors

antoniofarina avatar austinleegordon avatar brainflake avatar chiragrajk avatar davidmfoley avatar dependabot[bot] avatar durchanek avatar et avatar fabioprod avatar ghassenrjab avatar gorgekara avatar iameap avatar jimbeam2019 avatar kr1sp1n avatar ksvirkou-hubspot avatar lokosama avatar matt-forster avatar mattmsumner avatar mattscamp avatar morrislaptop avatar mpuittinen avatar mswagner avatar pcothenet avatar samlevan avatar tejasmanohar avatar timisbusy avatar trs avatar twisterking avatar valentinmontagne avatar vkhomiv-hubspot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-hubspot's Issues

Allow Bottleneck limiter options to be overridden

Would like to be able to override the Bottleneck limiter options (or at least fix the default options) to allow for requests to be processed concurrently.

In the current version the Bottleneck limiter has minTime set to 1000, delaying each request by 1s. I think it was intended to allow for 9 concurrent requests with maxConcurrent set to 9, but it will almost always only run one at a time since requests should resolve before the 1s delay.

const Bottleneck = require('bottleneck')
const limiter = new Bottleneck({
maxConcurrent: 9,
minTime: 1000,
})

Changing minTime to something like 1000 / 9 will keep it under the 10 requests per second limit.

const Bottleneck = require('bottleneck')
const limiter = new Bottleneck({
  maxConcurrent: 9,
  minTime: 1000 / 9,
})

Might need some tweaking to account for errors. In one application where I tested it, some of the emails being uploaded would bounce back errors and cause some of the following requests to hit the limit.

I'd be happy to work on a PR for this, but I wanted to make sure there weren't any other gotchas that I needed to watch out for.

Fix flaky tests

Build is currently failing because some tests (workflows for example) rely on objects that are not guaranteed to exist in the sandbox.

NPM outdated

commit log

It appears you haven't published to NPM since request was added as a dependency to this package. Would you please bump the version and do so? Till then, I'll use a GitHub user/repo path in my package.json.

createEventType needs UserId

When i use this method i got an error: "UserId not provided in request". I can see that some other methods use it, but not this one.

Endpoints status

@brainflake What endpoints are missing from the library? Can we create a list of them and add so we could start to work on adding it and creating test so maybe next major release has all endpoints?

Also they just release the new timeline and webhooks api's maybe it will be good to go ahead and start to think how to include there.

client.contacts.createOrUpdate is missing from README

This function is missing from README:

client.contacts.createOrUpdate(email, data, cb)

See line 89 of index.js for definition.

I can confirm this function works, as I have used it in my own code.

I tried to make fork and PR, but hit some SSH issues that I didn't have time to fix.

decode error object

I'm trying to decode error object message

     async createContact(data) {
  
        try {
            let contact = await this.hubspot.contacts.create(data)
            return contact;
        }catch(e){
            debug('error object',e)
            throw new Error(e)
        }
      


   
}

I get this print in terminal
Error: StatusCodeError: 409 - {"status":"error","message":"Contact already exists","correlationId":"3c5db087-36d0-415c-94ef-039de03b848a","identityProfile":{"vid":2751,"identity":[{"value":"[email protected]","type":"EMAIL","timestamp":1545572760708,"isPrimary":true},{"value":"a389c82e-60b3-4ef0-9c7c-4f19e432c0d3","type":"LEAD_GUID","timestamp":1545572760719}],"linkedVid":[],"isContact":true,"savedAtTimestamp":1545572760723},"error":"CONTACT_EXISTS","requestId":"71e6085bfec2c5d13046f6b344beed0e"}
but when I can't print the error message, it's not object.

AccessToken expires_in

After the Oauth flow the hubspot object does not contain the accessToken "expires_in" data.
Such data is useful for setting the local cache lifetime properly

best way to handle paged results

when doing a query against the contacts api or any other api that can returned paged results, is there a built in method to get all the results? Or do we need to create our own iterator to do it? A quick example in the README.md would be awesome!

Set expiration on bottleneck jobs

When using Bottleneck in clustering mode, it is strongly recommended to set expiration on every job.

See https://github.com/SGrondin/bottleneck#important-considerations-when-clustering

It would be great if hubspot would pass an expiration to calls to this.limiter.schedule, e.g.

return this.checkApiLimit(params).then(() => {
      this.emit('apiCall', params)
      return this.limiter.schedule({ expiration: this.apiTimeout }, () =>
        request(params)
          .then(res => {
            this.updateApiLimit(res)
            return res
          })
          .then(res => res.body)
      ) // limit the number of concurrent requests
    })

then if I setup clustering mode for hubspot's bottleneck instance, it will apply this recommendation.

Documentation for owners.get not consistent with implementation

Given the following code

'use strict';

const Hubspot = require('hubspot');
const hubspot = new Hubspot({ apiKey: 'demo' });

const opts = {};

return hubspot.owners.get(opts)
.then(results => {
  console.log("Successful get request of owners")
  console.log(results);
  return results;
}).catch(err => {
  console.log("Failed get request of owners")
  console.log(err);
});

I get the following error message:

Failed get request of owners
TypeError: cb is not a function
    at limiter.schedule.then.catch.err ((path omitted)/node_modules/hubspot/lib/client.js:120:13)
    at <anonymous>

This is because Owner.get currently only takes an argument of cb, rather than opts, cb as stated in the documentation, where it said hubspot.owners.get(opts, cb)

I haven't looked into whether the documentation should be changed to get rid of opts, or whether the implementation should be changed to utilize supplied options.

Contacts getById should accept optional parameters

contacts.getById only takes id, but per Hub Spot spec there are more options that can go into the URL query string (as it is a GET)

https://developers.hubspot.com/docs/methods/contacts/get_contact

string[]? property
string? propertyMode // "value_only", "value_and_history"
string? formSubmissionMode // "all", "none", "newest", "oldest"
boolean? showListMemberships

Solution:

Add an options param which accepts these values and adds them to qs


The signature is slightly different to the equivalent company/deal versions documented

Use ResolveWithFullResponse for request-promise calls

Some of the HubSpot API Calls don't return any messages (like the update call - https://developers.hubspot.com/docs/methods/contacts/update_contact), and the status code needs to be validated to determine the success of the calls. Currently, the tests for node-hubspot wrapper validates the test as a success if the message returned is undefined, but that is not necessarily true. As per the HubSpot API documentation, all of the following cases will return an undefined message

  • 204 when a contact is updated
  • 401 when an unauthorized request is made, such as an expired access token of wrong API key.
  • 404 when there is no existing contact with the specified vid.
  • 500 when an internal server error occurs. Please alert us in the API Forum if you receive an HTTP 500 error.

Move to Typescript

@AustinLeeGordon looks like we were able to move past the prettier issue but now it is telling me there is another error...which i believe is another prettier issue

Detailed stack trace: /user_code/node_modules/hubspot/lib/oauth.js:12
...data,
^^^

SyntaxError: Unexpected token ...
at createScript (vm.js:56:10)

Originally posted by @PrimalIan in #154 (comment)

Contacts.createOrUpdate data object issue

This may be a typscript specific issue. When i try to use the contacts.createOrUpdate method i get an error. It requires two inputs into it. a string which would be the email and a data object. All the other methods like create require a JSON object but when i try to use it like this:
const contact_data = { 'properties': [ { "property": "email", "value": postData.email }, { "property": "firstname", "value": postData.f_name }, { "property": "lastname", "value": postData.l_name }, { "property": "company", "value": postData.company }, { "property": "phone", "value": postData.phone }, { "property": "state", "value": postData.state } ] };

it gives me this error:
[ts] Argument of type '{ 'properties': { "property": string; "value": any; }[]; }' is not assignable to parameter of type '{}[]'. Property 'length' is missing in type '{ 'properties': { "property": string; "value": any; }[]; }'.

i make the call like this:
return hubspot.contacts.createOrUpdate(postData.email, contact_data)

useKey function bug

The useKey function requires a callback function for errors, but doesn't call it on success, which means that it can't be used properly.

function useKey (key, cb) {
    if (!key || typeof key !== 'string') {
      return cb(new Error("You must provide a key."));
    }

    self.key = key;
  }

It should probably be:

function useKey (key, cb) {
    if (!key || typeof key !== 'string') {
      return cb(new Error("You must provide a key."));
    }
    else {
        self.key = key;
        return cb(null);
    }
  }

Plan for Form support

Hi guys

Thanks for what is available so far.
I was wondering wether you had in mind to support the Forms?

Cheers
Sam

Better management of api limit

Added a support for checking API limits:

But couple issues:

  • should probably be optional (makes a couple extra api calls + complicate the code)
  • doesn't seem to work with all scopes on OAuth (at least not with the ones I have)

Will try to do a cleaner implementation soon.

'clientId' does not exist in type 'ApiOptions | AccessTokenOptions'.

This bug is about the new Hubspot constructor's signature being incorrect according to the TypeScript engine when taking an example from the documentation.

The steps to reproduce the bug are:

  1. Create a folder named node-hubspot-issue
  2. Open a terminal inside this folder and install the typescript & ts-node packages.
$ yarn add --dev typescript ts-node
  1. Install the node-hubspot package as well.
$ yarn add --dev node-hubspot
  1. Copy/paste the following content to a file named index.ts at the root of the node-hubspot-issue folder.
import Hubspot from 'hubspot';

const hubspot = new Hubspot({
  clientId: '...',
  clientSecret: '...',
  redirectUri: '...',
  refreshToken: '...'
});
  1. Inside the opened terminal, run the script.
$ yarn ts-node index.ts
  1. Observe the exception thrown in the terminal.

The expected behavior was to not have any errors thrown when using the constructor's signature from the documentation.

Here are some screenshots.
image
image

Environment:

  • ArchLinux: 241.7-2-arch
  • Docker: 18.09.2-ce, build 62479626f2
  • TypeScript: 3.3.3333
  • TS Node: 8.0.2
  • Hubspot: 2.1.1

Check API limit does not handle 10 requests / second limit

AS title suggests, if you're running a bunch of API calls, they'll start failing and you'll get the following error:

{“status”:“error”,“message”:“You have reached your secondly limit.”,“errorType”:“RATE_LIMIT”,“correlationId”:“6828d000-3d2f-4701-8d90-b21e53b0d005”,“policyName”:“SECONDLY”,“requestId”:“ce6a6a91-ac17-492f-bbdb-7d72477c319c”}

The API checker currently hits the APILimit end point, but that endpoint only handles the daily limit.

Not sure the best way to handle it, but a quick fix might be to use the .delay chain function on the request-promise object

Passing callbacks as the first argument should be removed

There are some functions that take a callback as the second argument but we have code allowing one to pass it as the first. This seems to happen inconsistently and not be documented anywhere.

I think it's worth removing callbacks as the first argument. It may also be an option to remove callbacks entirely and document how to use promises and then to achieve the same functionality.

feature request: workflows API

Hi,

I'm working on a project require the workflows feature. Any chance that supports this feature in the future?

Thanks.
Luke

Deal's associate for multiple objects at once

Hey, could be handy to let the users associate/removeAssociation of many contacts or companies at once, the hubspot API supports it and it could save some requests, maybe create a new function like associateMany or tweak a little the current one without breaking the current behavior, I could open a PR for that. WDYT?

refreshToken example does not work

const Hubspot = require('hubspot');
const hubspot = new Hubspot({
  clientId: process.env.HUBSPOT_CLIENT_ID,
  clientSecret: process.env.HUBSPOT_CLIENT_SECRET,
  redirectUri: `http://localhost:${PORT}`,
  refreshToken: "someStringHere"
})
return hubspot.refreshAccessToken()
  .then(results => {
    console.log(results.access_token)
    console.log(hubspot.accessToken) // this assigns the new accessToken to the client, so your client is ready to use
    return hubspot.contacts.get()
  })
  .catch((err)=> console.log(err))

This method does not work. I'm getting a 400 BAD_REFRESH_TOKEN error message.

I've diagnosed the problem as a poor refreshToken when instantiating the client which throws an error before I can get to the refreshToken() method.. I searched the website and forums for what should be in the refresh token property... can't find anything.

Anyone know where I can find what should go here?

cannot authenticate via oAUTH

not sure it is appropriate to ask a question here, but I have been struggling with initiating oAUTH with this Library. When I get authenticated I plan on adding timeline create functionality. I just have no idea what I am doing wrong. I used a sample app so I know I am on the right track with my variables. Here is my code, I desperately need a bump in the right direction. Maybe we could do a screen share and willing to pay as I have been battling this for 2 days. Guessing it is something simple I am missing.
I keep getting BAD_AUTH_CODE, "missing or unknown auth code". I could get data via APIkey but the timeline calls require oAUTH. My email is [email protected]

const chai = require('chai')
const expect = chai.expect

const Hubspot = require('hubspot')

class hubspotapi {
authorize(params) {
return new Promise((resolve, reject) => {
let body = '';
if(params.client_id) {
const pams = {
code: 'codecodecode',
clientId: 'xxxxx',
clientSecret: 'yyyyyyy',
redirectUri: 'https://plainsmobile.com'
//
}
const hubspot = new Hubspot(pams)
return hubspot.oauth.getAccessToken({
pams // the code you received from the oauth flow
}).then(data => {
expect(res).to.have.a.property('access_token')
})
return hubspot.contacts.get().then(data => {
expect(data).to.be.a('object')
expect(data.contacts).to.be.a('array')
expect(data.contacts[0]).to.be.an('object')
})
//return hubspot.refreshAccessToken()
// .then(results => {
// console.log(results.access_token)
// console.log(hubspot.accessToken) // this assigns the new accessToken to the client, so your client is ready to use
// return hubspot.contacts.get()
// })

			resolve(response);
			
		} else {
			resolve();
		}
	});
}

}
module.exports=hubspotapi;
hubspotapi.txt

Unexpected token ) in company.js file

I am trying to deploy a project to cloud functions. i switched from TS to JS to try to get better usability with this and other packages. But every time I add const Hubspot = require('hubspot'); I get an error on deployment that halts everything.

Is there a syntax error in your code?
Detailed stack trace: /user_code/node_modules/hubspot/lib/company.js:89
)
^

SyntaxError: Unexpected token )
at createScript (vm.js:56:10)
at Object.runInThisContext (vm.js:97:10)
at Module._compile (module.js:549:28)
at Object.Module._extensions..js (module.js:586:10)
at Module.load (module.js:494:32)
at tryModuleLoad (module.js:453:12)
at Function.Module._load (module.js:445:3)
at Module.require (module.js:504:17)
at require (internal/module.js:20:19)
at Object. (/user_code/node_modules/hubspot/lib/client.js:3:17)
at Module._compile (module.js:577:32)
at Object.Module._extensions..js (module.js:586:10)
at Module.load (module.js:494:32)
at tryModuleLoad (module.js:453:12)
at Function.Module._load (module.js:445:3)
at Module.require (module.js:504:17)

Automatically retry on error 429

It would be nice to automatically retry if we get error 429 back from the server, indicating we have sent too many requests.

This is relatively easy to implement using bottleneck, see https://github.com/SGrondin/bottleneck#retries

If retries are not wanted as a default, perhaps the hubspot client object could pass-through the relevant events from bottleneck so the user of hubspot can listen to them, and provide an example in the docs how to add appropriate error handlers to retry.

To workaround the issue, we can add our own event handler on the limiter, but it requires accessing the undocumented internals of the hubspot client:

const hubspotClient = new Hubspot({
  apiKey,
  limiter: {
    id: 'hubspot',
    maxConcurrent: 2,
    minTime: 150,
    // Clustering options
    datastore: 'ioredis',
    clearDatastore: false,
    clientOptions: redisClientOptions,
    timeout: 60000,
  },
});

const errorMaxRetries = (error: any) => {
  switch (error.statusCode) {
    case 502:
    case 503:
    case 427: {
      return 10;
    }
    case 500: {
      return 1;
    }
  }
  switch (error.code) {
    case 'ECONNRESET':
    case 'ESOCKETTIMEDOUT':
    case 'ETIMEDOUT':
      return 10;
  }
  return 0;
};
((hubspotClient as any).limiter as Bottleneck).on(
  'failed',
  async (error: any, jobInfo: any) => {
    if (jobInfo.retryCount < errorMaxRetries(error)) {
      log.warn(error, 'Retrying HubSpot request.');
      return 500;
    }
  },
);

Broadcast.js throws syntax error in 1.3.4 due to comma after cb

Hi team

Just a minor suggestion - v1.3.4 updated automatically for us from NPM, and then we got a series of errors (copy below). I think it's the trailing comma @ https://github.com/MadKudu/node-hubspot/blob/1.3.4/lib/broadcast.js#L18

Suggest maybe unpublishing v1.3.4 rather than keep it live? Just to avoid others having same problem.

/var/app/current/node_modules/hubspot/lib/broadcast.js:19
)
^
SyntaxError: Unexpected token )
at Object.exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:543:28)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.require (module.js:498:17)
at Module.require (/var/app/current/node_modules/require-in-the-middle/index.js:43:24)
at require (internal/module.js:20:19)
at Object. (/var/app/current/node_modules/hubspot/lib/client.js:1:81)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.