ask_password.rb
Example: print 10 latest posts from the user's home feed.
Instead of using a config file to read & store authentication info, this example uses a custom client class which reads the password from the console and creates a throwaway access token.
This approach makes sense for one-off scripts (e.g. in manually run Rake tasks), but it shouldn't be used for things that need to be done repeatedly and often. The authentication-related endpoints (createSession) have much lower rate limits than others and they don't reset as quickly, and you are likely to hit them if you call the endpoint over and over during testing.
rb
require 'didkit'
require 'io/console'
require 'minisky'
require 'time'
class TransientClient
include Minisky::Requests
attr_reader :config, :host
def initialize(handle)
@handle = handle
did = DID.resolve_handle(handle)
if did.nil?
raise "Couldn't resolve handle: #{handle}"
end
@host = did.document.pds_host
@config = { 'id' => did.to_s }
end
def ask_for_password
print "Enter password for #{@handle}: "
@config['pass'] = STDIN.noecho(&:gets).chomp
puts
end
def save_config
# ignore
end
end
handle = ARGV[0]
unless handle
puts "Usage: #{$PROGRAM_NAME} <handle | did>"
exit 1
end
# create a client instance & read password
bsky = TransientClient.new(handle)
bsky.ask_for_password
# fetch 10 posts from the user's home feed
result = bsky.get_request('app.bsky.feed.getTimeline', { limit: 10 })
puts
puts "Your timeline:\n\n"
result['feed'].each do |r|
reason = r['reason']
reply = r['reply']
post = r['post']
if reason && reason['$type'] == 'app.bsky.feed.defs#reasonRepost'
puts "[Reposted by @#{reason['by']['handle']}]"
end
handle = post['author']['handle']
timestamp = Time.parse(post['record']['createdAt']).getlocal
puts "@#{handle} • #{timestamp}"
puts
if reply
puts "[in reply to @#{reply['parent']['author']['handle']}]"
puts
end
puts post['record']['text']
puts
puts "=" * 120
puts
end