Class: Bskyrb::RecordManager

Inherits:
Object
  • Object
show all
Includes:
RequestUtils
Defined in:
lib/bskyrb/records.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from RequestUtils

#at_post_link, #create_record_uri, #default_authenticated_headers, #default_headers, #delete_record_uri, #get_post_thread_uri, #mute_actor_uri, #query_obj_to_query_params, #resolve_handle, #upload_blob_uri

Constructor Details

#initialize(session) ⇒ RecordManager

Returns a new instance of RecordManager.



7
8
9
# File 'lib/bskyrb/records.rb', line 7

def initialize(session)
  @session = session
end

Instance Attribute Details

#sessionObject (readonly)

Returns the value of attribute session.



5
6
7
# File 'lib/bskyrb/records.rb', line 5

def session
  @session
end

Instance Method Details

#block(username) ⇒ Object



134
135
136
# File 'lib/bskyrb/records.rb', line 134

def block(username)
  profile_action(username, "app.bsky.graph.block")
end

#create_post(text) ⇒ Object



82
83
84
# File 'lib/bskyrb/records.rb', line 82

def create_post(text)
  create_post_or_reply(text)
end

#create_post_or_reply(text, reply_to = nil) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/bskyrb/records.rb', line 56

def create_post_or_reply(text, reply_to = nil)
  input = Bskyrb::ComAtprotoRepoCreaterecord::CreateRecord::Input.from_hash({
    "collection" => "app.bsky.feed.post",
    "$type" => "app.bsky.feed.post",
    "repo" => session.did,
    "record" => {
      "$type" => "app.bsky.feed.post",
      "createdAt" => DateTime.now.iso8601(3),
      "text" => text,
    },
  })
  if reply_to
    input.record["reply"] = {
      "parent" => {
        "uri" => reply_to.uri,
        "cid" => reply_to.cid,
      },
      "root" => {
        "uri" => reply_to.uri,
        "cid" => reply_to.cid,
      },
    }
  end
  create_record(input)
end

#create_record(input) ⇒ Object



36
37
38
39
40
41
42
43
44
45
# File 'lib/bskyrb/records.rb', line 36

def create_record(input)
  unless input.is_a?(Hash) || input.class.name.include?("Input")
    raise "`create_record` takes an Input class or a hash"
  end
  HTTParty.post(
    create_record_uri(session.pds),
    body: input.to_h.compact.to_json,
    headers: default_authenticated_headers(session),
  )
end

#create_reply(replylink, text) ⇒ Object



86
87
88
89
# File 'lib/bskyrb/records.rb', line 86

def create_reply(replylink, text)
  reply_to = get_post_by_url(replylink)
  create_post_or_reply(text, reply_to)
end

#delete_record(collection, rkey) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/bskyrb/records.rb', line 47

def delete_record(collection, rkey)
  data = { collection: collection, repo: session.did, rkey: rkey }
  HTTParty.post(
    delete_record_uri(session),
    body: data.to_json,
    headers: default_authenticated_headers(session),
  )
end

#follow(username) ⇒ Object



130
131
132
# File 'lib/bskyrb/records.rb', line 130

def follow(username)
  profile_action(username, "app.bsky.graph.follow")
end

#get_latest_n_posts(username, n) ⇒ Object



151
152
153
154
155
# File 'lib/bskyrb/records.rb', line 151

def get_latest_n_posts(username, n)
  endpoint = XRPC::EasyEndpoint.new(session.pds, "app.bsky.feed.getAuthorFeed", authenticated: true)
  endpoint.authenticate(session.access_token)
  hydrate_feed endpoint.get(actor: username, limit: n), Bskyrb::AppBskyFeedGetauthorfeed::GetAuthorFeed::Output
end

#get_latest_post(username) ⇒ Object



146
147
148
149
# File 'lib/bskyrb/records.rb', line 146

def get_latest_post(username)
  feed = get_latest_n_posts(username, 1)
  feed.feed.first
end


168
169
170
171
172
# File 'lib/bskyrb/records.rb', line 168

def get_popular(n)
  endpoint = XRPC::EasyEndpoint.new session.pds, "app.bsky.unspecced.getPopular", authenticated: true
  endpoint.authenticate session.access_token
  hydrate_feed endpoint.get(limit: n), Bskyrb::AppBskyUnspeccedGetpopular::GetPopular::Output
end

#get_post_by_url(url, depth = 10) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/bskyrb/records.rb', line 11

def get_post_by_url(url, depth = 10)
  # e.g. "https://staging.bsky.app/profile/naia.bsky.social/post/3jszsrnruws27"
  # or "at://did:plc:scx5mrfxxrqlfzkjcpbt3xfr/app.bsky.feed.post/3jszsrnruws27"
  # regex by chatgpt:
  query = Bskyrb::AppBskyFeedGetpostthread::GetPostThread::Input.new.tap do |q|
    q.uri = at_post_link(session.pds, url)
    q.depth = depth
  end
  res = HTTParty.get(
    get_post_thread_uri(session.pds, query),
    headers: default_authenticated_headers(session),
  )
  Bskyrb::AppBskyFeedDefs::PostView.from_hash res["thread"]["post"]
end

#get_skyline(n) ⇒ Object



157
158
159
160
161
# File 'lib/bskyrb/records.rb', line 157

def get_skyline(n)
  endpoint = XRPC::EasyEndpoint.new(session.pds, "app.bsky.feed.getTimeline", authenticated: true)
  endpoint.authenticate(session.access_token)
  hydrate_feed endpoint.get(limit: n), Bskyrb::AppBskyFeedGettimeline::GetTimeline::Output
end

#hydrate_feed(response_hash, klass) ⇒ Object



174
175
176
177
178
179
180
181
182
183
# File 'lib/bskyrb/records.rb', line 174

def hydrate_feed(response_hash, klass)
  klass.from_hash(response_hash).tap do |feed|
    feed.feed = response_hash["feed"].map do |h|
      Bskyrb::AppBskyFeedDefs::FeedViewPost.from_hash(h).tap do |obj|
        obj.post = Bskyrb::AppBskyFeedDefs::PostView.from_hash h["post"]
        obj.reply = Bskyrb::AppBskyFeedDefs::ReplyRef.from_hash h["reply"] if h["reply"]
      end
    end
  end
end

#like(post_url) ⇒ Object



120
121
122
123
# File 'lib/bskyrb/records.rb', line 120

def like(post_url)
  post = get_post_by_url(post_url)
  post_action(post, "app.bsky.feed.like")
end

#list_records(collection, username, limit = 10) ⇒ Object



163
164
165
166
# File 'lib/bskyrb/records.rb', line 163

def list_records(collection, username, limit = 10)
  listRecords = XRPC::EasyEndpoint.new(session.pds, "com.atproto.repo.listRecords")
  listRecords.get(repo: resolve_handle(session.pds, username)["did"], collection: collection, limit: limit)["records"]
end

#mute(username) ⇒ Object



138
139
140
141
142
143
144
# File 'lib/bskyrb/records.rb', line 138

def mute(username)
  HTTParty.post(
    mute_actor_uri(session.pds),
    body: { actor: username }.to_json,
    headers: default_authenticated_headers(session),
  )
end

#post_action(post, action_type) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/bskyrb/records.rb', line 104

def post_action(post, action_type)
  data = {
    collection: action_type,
    repo: session.did,
    record: {
      subject: {
        uri: post.uri,
        cid: post.cid,
      },
      createdAt: DateTime.now.iso8601(3),
      "$type": action_type,
    },
  }
  create_record(data)
end

#profile_action(username, type) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/bskyrb/records.rb', line 91

def profile_action(username, type)
  input = Bskyrb::ComAtprotoRepoCreaterecord::CreateRecord::Input.from_hash({
    "collection" => type,
    "repo" => session.did,
    "record" => {
      "subject" => resolve_handle(session.pds, username)["did"],
      "createdAt" => DateTime.now.iso8601(3),
      "$type" => type,
    },
  })
  create_record(input)
end

#repost(post_url) ⇒ Object



125
126
127
128
# File 'lib/bskyrb/records.rb', line 125

def repost(post_url)
  post = get_post_by_url(post_url)
  post_action(post, "app.bsky.feed.repost")
end

#upload_blob(blob_path, content_type) ⇒ Object



26
27
28
29
30
31
32
33
34
# File 'lib/bskyrb/records.rb', line 26

def upload_blob(blob_path, content_type)
  # only images
  image_bytes = File.binread(blob_path)
  HTTParty.post(
    upload_blob_uri(session.pds),
    body: image_bytes,
    headers: default_authenticated_headers(session),
  )
end