#!/usr/bin/env ruby # Example: monitor the firehose for people blocking your account or adding you to lists. require 'bundler/setup' require 'didkit' require 'minisky' require 'skyfall' $handle = ARGV[0] if $handle.nil? puts "Usage: #{$PROGRAM_NAME} " exit 1 end $monitored_did = DID.resolve_handle(ARGV[0]).to_s if $monitored_did.empty? puts "Couldn't resolve handle: #{ARGV[0]}" exit 1 end sky = Skyfall::Firehose.new('bsky.network', :subscribe_repos) sky.on_connect { log "Connected, monitoring #{$monitored_did}" } sky.on_disconnect { log "Disconnected" } sky.on_reconnect { log "Reconnecting..." } sky.on_error { |e| log "ERROR: #{e}" } sky.on_message do |msg| # we're only interested in repo commit messages next if msg.type != :commit msg.operations.each do |op| next if op.action != :create begin case op.type when :bsky_block process_block(msg, op) when :bsky_listitem process_list_item(msg, op) end rescue StandardError => e log "Error: #{e}" end end end def log(msg) puts "[#{Time.now}] #{msg}" end def process_block(msg, op) if op.raw_record['subject'] == $monitored_did owner_handle = get_user_handle(op.repo) log "@#{owner_handle} has blocked you!" end end def process_list_item(msg, op) if op.raw_record['subject'] == $monitored_did owner_handle = get_user_handle(op.repo) list_uri = op.raw_record['list'] list_name = get_list_name(list_uri) log "@#{owner_handle} has added you to list \"#{list_name}\"" end end def get_user_handle(did) DID.new(did).get_verified_handle end def get_list_name(list_uri) # the listitem record only has an URI of the list, # so we need to look up the list record separately repo, collection, rkey = list_uri.gsub('at://', '').split('/') # get DID document to find out what their PDS is pds = DID.new(repo).document.pds_host # load the list record from their PDS sky = Minisky.new(pds, nil) record = sky.get_request('com.atproto.repo.getRecord', { repo: repo, collection: collection, rkey: rkey }) record['value']['name'] end # close the connection cleanly on Ctrl+C trap("SIGINT") { sky.disconnect } sky.connect