#!/usr/bin/env ruby # 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. require 'bundler/setup' 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} " 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