From 2411de323daeeeba3968ca4b2ee280e56b744e7b Mon Sep 17 00:00:00 2001 From: David Celis Date: Wed, 19 Jun 2024 17:48:33 -0700 Subject: [PATCH] Add support for reading user profiles --- lib/threads/api/client.rb | 10 +++++++ lib/threads/api/profile.rb | 18 ++++++++++++ spec/threads/api/client_spec.rb | 50 +++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 lib/threads/api/profile.rb diff --git a/lib/threads/api/client.rb b/lib/threads/api/client.rb index 7bf63cd..3e1c1f8 100644 --- a/lib/threads/api/client.rb +++ b/lib/threads/api/client.rb @@ -1,3 +1,4 @@ +require_relative "profile" require_relative "thread" module Threads @@ -7,6 +8,15 @@ def initialize(access_token) @access_token = access_token end + def get_profile(user_id = "me", fields: nil) + params = {access_token: @access_token} + params[:fields] = Array(fields).join(",") if fields + + response = connection.get(user_id, params) + + Threads::API::Profile.new(response.body) + end + def list_threads(user_id: "me", **options) params = options.slice(:since, :until, :before, :after, :limit).compact params[:access_token] = @access_token diff --git a/lib/threads/api/profile.rb b/lib/threads/api/profile.rb new file mode 100644 index 0000000..1725fc9 --- /dev/null +++ b/lib/threads/api/profile.rb @@ -0,0 +1,18 @@ +require "time" + +module Threads + module API + class Profile + attr_reader :id, :username, :profile_picture_url, :biography + + def initialize(json) + @id = json["id"] + @username = json["username"] + @profile_picture_url = json["profile_picture_url"] + @biography = json["biography"] + end + + alias_method :bio, :biography + end + end +end diff --git a/spec/threads/api/client_spec.rb b/spec/threads/api/client_spec.rb index 38c1260..78deeff 100644 --- a/spec/threads/api/client_spec.rb +++ b/spec/threads/api/client_spec.rb @@ -5,6 +5,56 @@ RSpec.describe Threads::API::Client do let(:client) { described_class.new("ACCESS_TOKEN") } + describe "#get_profile" do + let(:response_body) do + {id: "1234567890"}.to_json + end + + let(:params) { {} } + let!(:request) do + stub_request(:get, "https://graph.threads.net/v1.0/me") + .with(query: params.merge(access_token: "ACCESS_TOKEN")) + .to_return(body: response_body, headers: {"Content-Type" => "application/json"}) + end + + let(:profile) { client.get_profile(**params) } + + it "returns a response object with the user's profile" do + expect(profile.id).to eq("1234567890") + end + + context "when requesting all fields" do + let(:response_body) do + { + id: "1234567890", + username: "davidcelis", + profile_picture_url: "https://scontent-sjc3-1.cdninstagram.com/link/to/profile/picture/on/threads/", + biography: "Cowboy coder." + }.to_json + end + + let(:params) do + { + fields: ["id", "username", "profile_picture_url", "biography"] + } + end + let!(:request) do + stub_request(:get, "https://graph.threads.net/v1.0/1234567890") + .with(query: {access_token: "ACCESS_TOKEN", fields: "id,username,profile_picture_url,biography"}) + .to_return(body: response_body, headers: {"Content-Type" => "application/json"}) + end + + let(:profile) { client.get_profile("1234567890", **params) } + + it "fully hydrates the Profile" do + expect(profile.id).to eq("1234567890") + expect(profile.username).to eq("davidcelis") + expect(profile.profile_picture_url).to eq("https://scontent-sjc3-1.cdninstagram.com/link/to/profile/picture/on/threads/") + expect(profile.biography).to eq("Cowboy coder.") + end + end + end + describe "#list_threads" do let(:before_cursor) { "QVFIUkFyUFVVczIwWjVNaDVieUxHbW9vWFVqNkh0MHU0cFZARVHRTR3ZADSUxnaTdTdXl2eXBqUG4yX0RLVTF3TUszWW1nXzVJcmU5bnd2QmV2ZAVVDNVFXcFRB" } let(:after_cursor) { "QVFIUkZA4QzVhQW1XdTFibU9lRUF2YUR1bEVRQkhVZAWRCX2d3TThUMGVoQ3ZAwT1E4bElEa0JzNGJqV2ZAtUE00U0dMTnhZAdXpBUWN3OUdVSF9aSGZAhYXlGSDFR" }