hunting_season
is a ruby gem for interacting with the official Product Hunt API.
Authentication
hunting_season
can use any valid API token. Sources include:
-
A
Developer Token
generated in the Product Hunt API Dashboard. -
A client OAuth token as generated by oauth#token - Ask for client level token.
-
A user OAuth token as generated by oauth#authorize - Ask for access grant code on behalf of the user. See the omniauth-producthunt gem for an Omniauth strategy that may work (I haven't tested it yet).
When you have a valid token, simply instantiate the ProductHunt::Client
as follows:
client = ProductHunt::Client.new('mytoken')
Supported Endpoints
hunting_season
is a work-in-progress, please contribute if you need additional functionality.
Look up today's posts.
Post attributes are listed in the API docs and accessed like post["name"]
, post["id"]
, etc.
Example:
client = ProductHunt::Client.new('mytoken')
posts = client.posts
posts.size # -> 14
posts[0]["name"] # -> "Content Marketing Stack"
posts[0]["id"] # -> 30425
Look up all posts.
Post attributes are listed in the API docs and accessed like post["name"]
, post["id"]
, etc.
Example:
client = ProductHunt::Client.new('mytoken')
posts = client.all_posts(per_page: 1, order: 'asc')
posts[0]["name"] # -> "Ferro"
posts[0]["id"] # -> 3
Look up a post using a required numeric ID.
Post attributes are listed in the API docs and accessed like post["name"]
, post["id"]
, etc.
Example:
client = ProductHunt::Client.new('mytoken')
post = client.post(3372)
post["name"]
# => "namevine"
post["id"]
# => 3372
Look up a post's votes, with optional ordering and pagination.
Post attributes are listed in the API docs and accessed like vote["user"]
, vote["id"]
, etc.
Example, look up a post's votes and paginate through them in ascending order:
client = ProductHunt::Client.new('mytoken')
post = client.post(3372)
votes = post.votes(per_page: 2, order: 'asc')
votes[0]["id"]
# => 46164
"#{votes[0]["user"]["name"]} #{votes[0]["user"]["headline"]}"
# => "Jack Smith Co-Founded Vungle - Advisor to Coin"
votes_page_2 = post.votes(per_page: 2, order: 'asc', newer: votes.last["id"])
votes_page_2[0]["id"]
# => 46242
"#{votes_page_2[0]["user"]["name"]} #{votes_page_2[0]["user"]["headline"]}"
# => "Helen Crozier Keyboard Karma"
Get all users using ordering and pagination as noted in the official API docs.
Example:
client = ProductHunt::Client.new('mytoken')
users = client.users(order: 'asc')
users.first["name"] # -> "Nathan Bashaw"
users.first["headline"] # -> "Working on something new :)"
users.first["id"] # -> 1
Look up a user by username or id.
User attributes are listed in the API docs and accessed like user["name"]
, user["headline"]
, etc.
Example:
client = ProductHunt::Client.new('mytoken')
user = client.user('rrhoover')
user["name"]
# => "Ryan Hoover"
user["headline"]
# => "Product Hunt"
Look up a post's comments, with optional ordering and pagination.
Example, look up a post's comments and paginate through them in ascending order:
client = ProductHunt::Client.new('mytoken')
post = client.post(3372)
comments = post.comments(per_page: 2, order: 'asc')
comments[0]["id"]
# => 11378
"#{comments[0]["user"]["name"]}: #{comments[0]["body"]}"
# => "Andreas Klinger: fair point but not using thesaurus nor having the ..."
comments_page_2 = post.comments(per_page: 2, order: 'asc', newer: comments.last["id"])
comments_page_2[0]["id"]
# => 11558
"#{comments_page_2[0]["user"]["name"]}: #{comments_page_2[0]["body"]}"
# => "Mike Jarema: Namevine developer here -- feel free to ask any Qs about ..."
Accessing associated records
For some API responses, an ID reference to or partial details for an associated User or Post are supplied. hunting_season
provides convenience methods to access the full details of these associated records.
Currently #post
and #user
apply when the associated record is present.
Example:
comment = ProductHunt::Client.new('mytoken').post(3372).comments(order: 'asc').first
user_hash = comment["user"] # this will access the partial user details embedded in the response to the #comments call above
user_hash.class
# => Hash
user_hash["name"]
# => "Andreas Klinger"
user_object = comment.user # this will make a separate call to pull the full details of the user who commented
user_object.class
# => ProductHunt::User
user_object["name"]
# => "Andreas Klinger"
post_object = comment.post # likewise for the associated post, this will pull full details of the post on which a comment was made via an additional API call
post_object.class
# => ProductHunt::Post
post_object["name"]
# => "namevine"
ETAG Support
You can retrieve the etag for any call by calling #etag
against the returned object or collection:
client = ProductHunt::Client.new('mytoken')
post = client.post(3372)
etag = post.etag
You then can leverage Product Hunt's API support to increase performance by passing this etag on subsequent requests. If a record has NOT changed, it will respond to #modified?
with false.
post = client.post(3372, headers: { 'If-None-Match': etag }) # pass as custom header
post = client.post(3372, etag: etag) # OR explicitly
if post.modified?
# do something with the modified post
else
# the post remains unmodified, trying to access any attributes on this object will raise an exception
end
Tests
There are two ways to run tests:
-
bundle exec rake
which stubs out all of the calls to Product Hunt's API to local files. -
TOKEN=mytoken USE_LIVE_API=true bundle exec rake
which runs tests against live data from the Product Hunt API using your developer token.
Contributing
Easy.
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Add new functionality, relevant tests and update the README if applicable
- Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Miscellany
Legal: see LICENSE
The name is inspired by a rapper buddy of mine: Katchphraze - Huntin' Season 🎧
Copyright (c) 2014 Mike Jarema