Skip to content

Ruby wrapper around Hubspot API v3 with simple implementation and batch endpoints support and hubspot private apps aythentication token support

License

Notifications You must be signed in to change notification settings

Pobble/hubspot_v3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HubspotV3

Ruby gem wrapper around Hubspot CRM API V3

Currently this gem focuses on Batch update/create/search of Contacts. More info in source code

Reason why Batch (or Bulk) operations are preferred by this gem is that Hubspot has a strict limits on number of requests (around 100 requests per 10seconds, up to 200 requests per 10 seconds). When dealing with large number of Contacts single request operations are killing those limits quite quickly.

Other solutions out there

Gem currently covers only features that are needed for our use cases (CRM Contacts & Companies), however this repo/gem is open for any Pull Requests with additional features.

If you need other features and wish not to contribute to this gem there are 2 existing Hubspot gems out there:

  • Official gem based on V3 API but is just generated Ruby code
  • Community gem which is better code quality but based on V1 API

It's possible to use our gem along with any of these two gems.

Installation

Add this line to your application's Gemfile:

gem 'hubspot_v3', '~> 1.0'

Gem Version

And then execute:

$ bundle install

Usage

set App Token (API key)

NOTE: Starting November 30, 2022, HubSpot API keys will no longer be able to be used as an authentication method to access HubSpot APIs source

This means you cannot use Hubspot API KEY (a.k.a hapikey) to authenticate but rather create Hubspot Private App and use it's auth token (how to setup Hubspot private app)

# Hubspot private app token (It's not the same as API KEY)
HubspotV3.config.token = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

Contacts - Search


bodyhash = {
  "filterGroups":[
    {
      "filters": [
        {
          "propertyName": "email",
          "operator": "EQ",
          "value": email
        }
      ]
    }
  ]
}
HubspotV3.contacts_search(bodyhash)

Contacts - find by email

HubspotV3.contacts_search_by_emails(["hello@pobble.com", "info@pobble.com"])
[
 {"id"=>"901",
  "properties"=>
   {"createdate"=>"2020-09-10T10:29:54.714Z",
    "email"=>"hello@pobble.com",
    "firstname"=>nil,
    "hs_object_id"=>"901",
    "lastmodifieddate"=>"2021-10-13T10:16:19.015Z",
    "lastname"=>"test"},
  "createdAt"=>"2020-09-10T10:29:54.714Z",
  "updatedAt"=>"2021-10-13T10:16:19.015Z",
  "archived"=>false},
 {"id"=>"3401",
  "properties"=>
   {"createdate"=>"2021-10-13T13:31:04.599Z",
    "email"=>"info@pobble.com",
    "firstname"=>"Bryan",
    "hs_object_id"=>"3401",
    "lastmodifieddate"=>"2021-10-13T13:31:07.126Z",
    "lastname"=>"Cooper"},
  "createdAt"=>"2021-10-13T13:31:04.599Z",
  "updatedAt"=>"2021-10-13T13:31:07.126Z",
  "archived"=>false}
]

Note: will search only primary email of a Contact

Contacts - find by email & results mapped by email

HubspotV3.contacts_search_by_emails(["hello@pobble.com", "info@pobble.com"])

{
    "anas+10093@pobble.com" => {
                "id" => "901",
        "properties" => {
                  "createdate" => "2020-09-10T10:29:54.714Z",
                       "email" => "hello@pobble.com",
                   "firstname" => nil,
                "hs_object_id" => "901",
            "lastmodifieddate" => "2021-10-13T10:16:19.015Z",
                    "lastname" => "test"
        },
         "createdAt" => "2020-09-10T10:29:54.714Z",
         "updatedAt" => "2021-10-13T10:16:19.015Z",
          "archived" => false
    },
    "bcooper@biglytics.net" => {
                "id" => "3401",
        "properties" => {
                  "createdate" => "2021-10-13T13:31:04.599Z",
                       "email" => "info@pobble.com",
                   "firstname" => "Bryan",
                "hs_object_id" => "3401",
            "lastmodifieddate" => "2021-10-13T13:31:07.126Z",
                    "lastname" => "Cooper"
        },
         "createdAt" => "2021-10-13T13:31:04.599Z",
         "updatedAt" => "2021-10-13T13:31:07.126Z",
          "archived" => false
    }
}

Note: will search only primary email of a Contact

Contacts - Batch Create

bodyhash = {
  "inputs": [
    {
      "properties": {
        "email": "equivalent@eq8.eu",
        "firstname": "Tomas",
        "lastname": "Talent",
      }
    }
  ]
}

begin
  HubspotV3.contacts_create(bodyhash)
rescue HubspotV3::RequestFailedError => e
  puts e.message
  # => 409 - Contact already exists. Existing ID: 3401

  httparty_response_object = e.httparty_response
  # =>  #<HTTParty::Response:0x1d920 parsed_response={"status"=>"error"...
end

Contacts - Batch Update

bodyhash = {
  "inputs": [
    {
      "id": "1",
      "properties": {
        "company": "Biglytics",
        "email": "bcooper@biglytics.net",
        "firstname": "Bryan",
        "lastname": "Cooper",
        "phone": "(877) 929-0687",
        "website": "biglytics.net"
      }
    }
  ]
}
HubspotV3.contacts_update(bodyhash)

Companies - Search

bodyhash = {
  "filterGroups":[
    {
      "filters": [
        {
          "propertyName": "name",
          "operator": "EQ",
          "value": "ACME Company"
        }
      ]
    }
  ]
}
HubspotV3.companies_search(bodyhash)

Companies - Search by id

HubspotV3.companies_search_by_ids(['9582682125'])
#=> [
#  {
#    "id"=>"9582682125",
#    "properties"=> {
#      "createdate"=>"2022-09-13T15:06:03.116Z",
#      "domain"=>nil,
#      "hs_lastmodifieddate"=>"2022-09-13T15:20:48.331Z",
#      "hs_object_id"=>"9582682125",
#      "name"=>"ACME Company"},
#    "createdAt"=>"2022-09-13T15:06:03.116Z",
#    "updatedAt"=>"2022-09-13T15:20:48.331Z",
#    "archived"=>false
#  }
#]

HubspotV3.companies_search_by_ids(['66666'])
#=> []

Companies - Batch Create

bodyhash = {
  "inputs": [
    {
      "properties": {
        "name": "ACME Corporation"
      }
    },
    {
      "city": "Cambridge",
      "domain": "biglytics.net",
      "industry": "Technology",
      "name": "Biglytics",
      "phone": "(877) 929-0687",
      "state": "Massachusetts"
    }
  ]
}

begin
  HubspotV3.companies_create(bodyhash)
rescue HubspotV3::RequestFailedError => e
  puts e.message
  # => 409 - some error reason (I never encounterd an error when creating company)

  httparty_response_object = e.httparty_response
  # =>  #<HTTParty::Response:0x1d920 parsed_response={"status"=>"error"...
end

return value:

[
  {
    "id"=>"9674616673",
    "properties"=> {
      ...
    }
    ...
  },
  {
    "id"=>"9674616674",
    "properties"=> {
      ...
    }
    ...
  }
]

Companies - Batch Update

bodyhash = {
  "inputs": [
    {
      "id": "9582682125",
      "properties": {
        "name": "ACME Company"
      }
    }
  ]
}
HubspotV3.companies_update(bodyhash)

Test your app

You can use http interceptor like webmock, vcr.

Or you can use explicit contracts provided in this gem.

require 'hubspot_v3'
require 'hubspot_v3/mock_contract'

HubspotV3::MockContract.contacts_search_by_emails(["hello@pobble.com", "notfound@pobble.com", "info@pobble.com"])
# [
#   {
#     "id" => 1589,
#     "properties" => {
#       "email"=>"hello@pobble.com",
#       ...
#     }
#   },
#   {
#    "id" => 1485,
#    "properties" => {
#       "email"=>"info@pobble.com",
#       ...
#       }
#   }
# ]

HubspotV3::MockContract.contacts_search_by_emails_mapped(["hello@pobble.com", "notfound@pobble.com", "info@pobble.com"]).keys
# => ["hello@pobble.com", "info@pobble.com"]

id field of test Contact contracts is calculated as 'info@pobble.com'.bytes.sum == 1485 (source), create contacts will be 'info@pobble.com'.bytes.sum + 1_000_000 == 1001485 (source)

More info on how to use Contract tests

Troubleshooting

Error - Cannot deserialize value of type

`post': 400 - Invalid input JSON on line 1, column 1: Cannot deserialize value of type `com.hubspot.apiutils.core.models.batch.BatchInput$Json<com.hubspot.inbounddb.publicobject.core.v2.SimplePublicObjectBatchInput>` from Array value (token `JsonToken.START_ARRAY`) (HubspotV3::RequestFailedError)

You probably forgot to wrap your batch call body hash in inputs.

E.g.:

instead of

HubspotV3.companies_update([{"id"=>"1234", "properties"=> {"city" => "Cambridge"}}])

you need to do:

HubspotV3.companies_update("inputs" => [{"id"=>"1234", "properties"=> {"city" => "Cambridge"}}])

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/Pobble/hubspot_v3.

License

The gem is available as open source under the terms of the MIT License.

About

Ruby wrapper around Hubspot API v3 with simple implementation and batch endpoints support and hubspot private apps aythentication token support

Topics

Resources

License

Stars

Watchers

Forks