Skip to content
A Ruby gem to interact with Tinder's REST API.
Ruby Shell
Branch: master
Clone or download

README.md

RSpec Tests: CircleCI

Code Coverage: codecov

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
You can’t perform that action at this time.