0.01
No commit activity in last 3 years
No release in over 3 years
There's a lot of open issues
A client for Tinder written in Ruby
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

 Project Readme

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