TinderClient
A Ruby gem to interact with Tinder's REST API.
Usage
Rake Commands
rake tinder:updates # Fetch updates
rake tinder:profile # Fetch my profile
rake tinder:recommendations # Fetch recommendations
rake tinder:save_token # Save an API token to $token_path ake tinder:get_updates # Fetch updates
To grab a token, call a rake command & specify the phone_number
or api_token
in your environment variables.
rake tinder:save_token
$ rake tinder:save_token \
phone_number=15556667777 \
tinder_token_path=/tmp
Enter the confirmation code sent to 15556667777>
123456
Validating...
Done!
Your refresh token is eyJhbGciOiJIUzI1NiJ9.MTc3ODk5MDk4MDM.5q4R0H08rE0Dd9KgxMPp6jcTfIBLCXgEuVZfC9znJTE
Logging in...
Done!
Your tinder API token is 12a3bc45-a123-123a-1a23-1234abc4de5f
Saved to /tmp/tinder_access_token.txt
Use Tinder Test-Helpers in your RSpec Tests
tinder_client
has webmock stubs you can include in your project to get fake responses back from Tinder:
gem_dir = Gem::Specification.find_by_name("tinder_client").gem_dir
require "#{gem_dir}/spec/tinder/contexts/http_request_stubs"
RSpec.describe 'some test' do
include_context 'http_request_stubs'
# Your tests that use Tinder HTTP requests go here
end
Accessing your saved data
better_tinder
converts responses from Tinder from raw JSON data to Dry::Struct
, for your convenience.
That means, call the services with your API token to return a struct:
SaveRecommendations.call(api_token:)
class Photo < Dry::Struct
attribute :id, Types.string
attribute? :crop_info do
attribute? :user do
attribute :width_pct, Dry::Types['coercible.float']
attribute :x_offset_pct, Types.float
attribute :height_pct, Types.float
attribute :y_offset_pct, Types.float
end
attribute? :algo do
attribute :width_pct, Types.float
attribute :x_offset_pct, Types.float
attribute :height_pct, Types.float
attribute :y_offset_pct, Types.float
end
attribute :processed_by_bullseye, Types.bool
attribute :user_customized, Types.bool
attribute? :url, Types.string
attribute? :processedFiles, Types.array
attribute? :fileName, Types.string
attribute? :extension, Types.string
end
end
class User < Dry::Struct
attribute :_id, Types.string
attribute :bio, Types.string
attribute :birth_date, Types.string
attribute :name, Types.string
attribute :photos, Types.array.of(Photo)
attribute :gender, Types.integer
attribute :jobs, Types.array
attribute :schools, Types.array do
attribute :name, Types.string
end
attribute? :city do
attribute :name, Types.string
end
attribute? :is_traveling, Types.bool
attribute? :hide_age, Types.bool
attribute? :hide_distance, Types.bool
end
# Return this object
class Recommendation < Dry::Struct
attribute :type, Types.string
attribute :user, User
attribute :facebook do
attribute :common_connections, Types.array
attribute :connection_count, Types.integer
attribute :common_interests, Types.array
end
attribute :spotify, Types.hash
attribute :distance_mi, Types.integer
attribute :content_hash, Types.string
attribute :s_number, Types.integer
attribute :teasers, Types.array do
attribute :type, Types.string
attribute :string, Types.string
end
end
SaveUpdates.call(api_token:)
class Message < Dry::Struct
attribute :_id, Types.string
attribute :match_id, Types.string
attribute :sent_date, Types.string
attribute :message, Types.string
attribute :to, Types.string
attribute :from, Types.string
attribute :created_date, Types.string
attribute :timestamp, Types.send('coercible.string')
end
class LikedMessage < Dry::Struct
attribute :message_id, Types.string
attribute :updated_at, Types.string
attribute :liker_id, Types.string
attribute :match_id, Types.string
attribute :is_liked, Types.bool
end
class Person < Dry::Struct
attribute? :bio, Types.string
attribute :birth_date, Types.string
attribute :gender, Types.integer
attribute :name, Types.string
attribute :ping_time, Types.string
attribute :photos, Types.array
end
class Match < Dry::Struct
attribute :_id, Types.string
attribute :closed, Types.bool
attribute :common_friend_count, Types.integer
attribute :common_like_count, Types.integer
attribute :created_date, Types.string
attribute :dead, Types.bool
attribute :following, Types.bool
attribute :following_moments, Types.bool
attribute :id, Types.string
attribute :is_boost_match, Types.bool
attribute :is_fast_match, Types.bool
attribute :is_super_like, Types.bool
attribute :last_activity_date, Types.string
attribute :message_count, Types.integer
attribute :messages, Types.array.of(Message)
attribute :muted, Types.bool
attribute :participants, Types.array
attribute :pending, Types.bool
attribute :person, Person
attribute :readreceipt, Types.hash
attribute :seen, Types.hash
end
class Updates < Dry::Struct
attribute :blocks, Types.array.of(Types.string)
attribute :deleted_lists, Types.array
attribute :goingout, Types.array
attribute :harassing_messages, Types.array
attribute :inbox, Types.array.of(Message)
attribute :poll_interval, Types.hash
attribute :liked_messages, Types.array.of(LikedMessage)
attribute :lists, Types.array
attribute :matches, Types.array.of(Match)
attribute :squads, Types.array
end