Deal Search API Ignoring Filter Groups (Ruby)

SOLVE
LeeStetson
Participant

When using the example for `Post /crm/v3/objects/deals/search` from the docs at https://developers.hubspot.com/docs/api/crm/deals I can test call and get the expected results. However, when pasting into my own code, my response always includes all deals with none of the specified filtering.

 

I'm using Ruby, but I experimented with the cURL and Python options too. cURL returns the expected response, but the Python option required some edits to the sample code (the import statement was incomplete.)

 

Therefore, I'm wondering if the docs are generating an incomplete sample code, but running the complete code behind the scenes.

 

Here's the code the docs are showing me to use:

 

 

require 'hubspot-api-client'

Hubspot.configure do |config|
  config.api_key['hapikey'] = 'YOUR_HUBSPOT_API_KEY'
end

public_object_search_request = Hubspot::Crm::Deals::PublicObjectSearchRequest.new(filter_groups: [{"filters":[{"value":"true","propertyName":"ready_to_bill","operator":"EQ"}]}], sorts: ["descending"], properties: [["dealname","ready_to_bill"]], limit: 1, after: 0)
begin
  api_response = Hubspot::Crm::Deals::SearchApi.new.do_search(public_object_search_request: public_object_search_request, auth_names: "hapikey")
  puts api_response
rescue Hubspot::Crm::Deals::ApiError => e
  error_message = JSON.parse(e.response_body)['message']
  puts error_message
end

 

 

Has anyone experienced this and come up with a fix? Would it be better to open an issue on the code in GitHub? I'm not able to tell if it's the sample code, or the ruby-api-client that's the problem. 

0 Upvotes
1 Accepted solution

Accepted Solutions
altjx
Solution
Contributor

Honestly I gave up on the HubSpot API Client gem for Ruby. I built my own wrapper around the types of calls that I would be making to HubSpot API through GET, POST, PATCH, and PUT requests.

 

For example, all of my HubSpot API calls get sent to one of these methods:

 

  def get_request(url)
    url.gsub!('https://api.hubapi.com/crm/v3/', '') if url.include? 'https://api.hubapi.com/crm/v3/'
    response = @web.get_request("https://api.hubapi.com/crm/v3/#{url}&hapikey=#{@hubspot_api_key}")
    JSON(response.body)
  end

  def put_request(url)
    url.gsub!('https://api.hubapi.com/crm/v3/', '') if url.include? 'https://api.hubapi.com/crm/v3/'
    response = @web.put_request("https://api.hubapi.com/crm/v3/#{url}&hapikey=#{@hubspot_api_key}")
    JSON(response.body)
  end

  def post_request(url, body)
    url.gsub!('https://api.hubapi.com/crm/v3/', '') if url.include? 'https://api.hubapi.com/crm/v3/'
    response = @web.post_request("https://api.hubapi.com/crm/v3/#{url}&hapikey=#{@hubspot_api_key}", body)
    JSON(response.body)
  end

  def patch_request(url, body)
    url.gsub!('https://api.hubapi.com/crm/v3/', '') if url.include? 'https://api.hubapi.com/crm/v3/'
    response = @web.patch_request("https://api.hubapi.com/crm/v3/#{url}&hapikey=#{@hubspot_api_key}", body)
    JSON(response.body)
  end

 

so if I want to fetch the deals for a particular company, here's what I call:

 

  def find_existing_deal(company)
    response = {}
    deals = get_request("objects/companies/#{company.hubspot_id}/associations/deals?limit=500")
    unless deals['results'].empty?
      # Find the deal that has a DealType of XYZ
      deals['results'].each do |result|
        deal_id = result['id']

        # Retrieve deal details
        get_response = get_request("objects/deals/#{deal_id}?properties=dealtype")
        if get_response['properties']['dealtype'].blank?
          SlackBot.new.send_message(
            "Error updating HubSpot! #{company.name} does not have a dealType assigned to their deal. Please update this deal manually.", '#sales'
          )
          SlackBot.new.send_message(
            "You can access this deal at the following URL: https://app.hubspot.com/contacts/4512633/deal/#{deal_id}", '#sales'
          )
          exit(0)
        end
        next unless ['New Business','Existing Business'].any? do |a|
                      a.include? get_response['properties']['dealtype']
                    end

        response = get_response
        break
      end
    end

    response
  end

 

may not necessarily be the cleanest, but I've been able to get this implemented pretty much all over app avoiding the api-client and its limitations or confusions.

Hope this helps!

View solution in original post

4 Replies 4
dennisedson
Community Manager

@altjx , @GaryElliott  any thoughts here?

@LeeStetson , feel free to add an issue to the repo if there is indeed an issue 👍

Thanks,

Dennis




Check out our Community Developer Blog
where we feature our Community driven developer podcast and how to content
0 Upvotes
altjx
Solution
Contributor

Honestly I gave up on the HubSpot API Client gem for Ruby. I built my own wrapper around the types of calls that I would be making to HubSpot API through GET, POST, PATCH, and PUT requests.

 

For example, all of my HubSpot API calls get sent to one of these methods:

 

  def get_request(url)
    url.gsub!('https://api.hubapi.com/crm/v3/', '') if url.include? 'https://api.hubapi.com/crm/v3/'
    response = @web.get_request("https://api.hubapi.com/crm/v3/#{url}&hapikey=#{@hubspot_api_key}")
    JSON(response.body)
  end

  def put_request(url)
    url.gsub!('https://api.hubapi.com/crm/v3/', '') if url.include? 'https://api.hubapi.com/crm/v3/'
    response = @web.put_request("https://api.hubapi.com/crm/v3/#{url}&hapikey=#{@hubspot_api_key}")
    JSON(response.body)
  end

  def post_request(url, body)
    url.gsub!('https://api.hubapi.com/crm/v3/', '') if url.include? 'https://api.hubapi.com/crm/v3/'
    response = @web.post_request("https://api.hubapi.com/crm/v3/#{url}&hapikey=#{@hubspot_api_key}", body)
    JSON(response.body)
  end

  def patch_request(url, body)
    url.gsub!('https://api.hubapi.com/crm/v3/', '') if url.include? 'https://api.hubapi.com/crm/v3/'
    response = @web.patch_request("https://api.hubapi.com/crm/v3/#{url}&hapikey=#{@hubspot_api_key}", body)
    JSON(response.body)
  end

 

so if I want to fetch the deals for a particular company, here's what I call:

 

  def find_existing_deal(company)
    response = {}
    deals = get_request("objects/companies/#{company.hubspot_id}/associations/deals?limit=500")
    unless deals['results'].empty?
      # Find the deal that has a DealType of XYZ
      deals['results'].each do |result|
        deal_id = result['id']

        # Retrieve deal details
        get_response = get_request("objects/deals/#{deal_id}?properties=dealtype")
        if get_response['properties']['dealtype'].blank?
          SlackBot.new.send_message(
            "Error updating HubSpot! #{company.name} does not have a dealType assigned to their deal. Please update this deal manually.", '#sales'
          )
          SlackBot.new.send_message(
            "You can access this deal at the following URL: https://app.hubspot.com/contacts/4512633/deal/#{deal_id}", '#sales'
          )
          exit(0)
        end
        next unless ['New Business','Existing Business'].any? do |a|
                      a.include? get_response['properties']['dealtype']
                    end

        response = get_response
        break
      end
    end

    response
  end

 

may not necessarily be the cleanest, but I've been able to get this implemented pretty much all over app avoiding the api-client and its limitations or confusions.

Hope this helps!

View solution in original post

LeeStetson
Participant

Thanks! I removed the api-client dependency myself and implemented something similar to what you've shared.

 

I'll probably still open an issue in Github, but it's really not important right now since I'm only working on a script with a fairly small scope.

AGlyatsevich
Member

The issue was found in the 'hubspot-api-client' gem:

The search API method accepts filterGroups parameter,

however PublicObjectSearchRequest class accepts it only and exactly like this: filter_groups, which is ignored in backend (search API method).

 

Example of non-working ruby code:

 

request = Hubspot::Crm::Contacts::PublicObjectSearchRequest.new(
  filterGroups: [ { 'filters': [ {
                   'value': 'someemail@example.com',
                   'propertyName': 'email',
                   'operator': 'EQ'
   } ] } ], sorts: ['id'], properties: ['id'], limit: 1, after: 0)

Hubspot::Crm::Contacts::SearchApi.new.do_search(public_object_search_request: request, auth_names: 'hapikey')

 

 

Returns error:

ArgumentError: `filterGroups` is not a valid attribute in `Hubspot::Crm::Contacts::PublicObjectSearchRequest`. Please check the name to make sure it's valid. List of attributes: [:filter_groups, :sorts, :query, :properties, :limit, :after]

  

 

Another non-working example (implemented exactly as it is in the documentation, pay attention to filter_groups parameter):

 

request = Hubspot::Crm::Contacts::PublicObjectSearchRequest.new(
  filter_groups: [ { 'filters': [ {
                   'value': 'someemail@example.com',
                   'propertyName': 'email',
                   'operator': 'EQ'
   } ] } ], sorts: ['id'], properties: ['id'], limit: 1, after: 0)

Hubspot::Crm::Contacts::SearchApi.new.do_search(public_object_search_request: request, auth_names: 'hapikey')

 

 

Returns all existing contacts (ignoring search filter).

 

Current solution is to write your own layer for requests (gem 'rest-client' works well for that)