A simple Ruby server using Sinatra that serves Bluesky custom feeds
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

detect pds hostname automatically in publish task

+34 -7
+17 -7
lib/blue_factory/tasks/publish.rake
··· 22 22 exit 1 23 23 end 24 24 25 + publisher_did = BlueFactory.publisher_did 26 + 25 27 feed = BlueFactory.get_feed(feed_key) 26 28 27 29 if feed.nil? ··· 71 73 avatar_data = File.read(avatar_file) 72 74 end 73 75 74 - server = ENV['SERVER_URL'] || "https://bsky.social" 76 + did_url = if publisher_did.start_with?('did:plc:') 77 + "https://plc.directory/#{publisher_did}" 78 + else 79 + web_domain = did.gsub(/^did\:web\:/, '') 80 + "https://#{web_domain}/.well-known/did.json" 81 + end 82 + 83 + did_json = BlueFactory::Net.get_request(did_url) 84 + pds_host = did_json['service'].detect { |x| x['id'] == '#atproto_pds' }['serviceEndpoint'] 75 85 76 - print "Enter password for your publisher account (#{BlueFactory.publisher_did}): " 86 + print "Enter password for your publisher account (#{publisher_did}): " 77 87 password = STDIN.noecho(&:gets).chomp 78 88 puts 79 89 80 - json = BlueFactory::Net.post_request(server, 'com.atproto.server.createSession', { 81 - identifier: BlueFactory.publisher_did, 90 + json = BlueFactory::Net.post_request(pds_host, 'com.atproto.server.createSession', { 91 + identifier: publisher_did, 82 92 password: password 83 93 }) 84 94 85 95 access_token = json['accessJwt'] 86 96 87 97 if avatar_data 88 - json = BlueFactory::Net.post_request(server, 'com.atproto.repo.uploadBlob', avatar_data, 98 + json = BlueFactory::Net.post_request(pds_host, 'com.atproto.repo.uploadBlob', avatar_data, 89 99 content_type: encoding, auth: access_token) 90 100 91 101 avatar_ref = json['blob'] ··· 101 111 record[:avatar] = avatar_ref if avatar_ref 102 112 record[:contentMode] = feed_content_mode if feed_content_mode 103 113 104 - json = BlueFactory::Net.post_request(server, 'com.atproto.repo.putRecord', { 105 - repo: BlueFactory.publisher_did, 114 + json = BlueFactory::Net.post_request(pds_host, 'com.atproto.repo.putRecord', { 115 + repo: publisher_did, 106 116 collection: BlueFactory::FEED_GENERATOR_TYPE, 107 117 rkey: feed_key, 108 118 record: record
+17
lib/blue_factory/tasks/support.rb
··· 1 1 require 'json' 2 2 require 'net/http' 3 + require 'uri' 3 4 4 5 module BlueFactory 5 6 module Net 6 7 class ResponseError < StandardError; end 8 + 9 + def self.get_request(server, method = nil, params = nil, auth: nil) 10 + headers = {} 11 + headers['Authorization'] = "Bearer #{auth}" if auth 12 + 13 + url = method ? URI("#{server}/xrpc/#{method}") : URI(server) 14 + 15 + if params && !params.empty? 16 + url.query = URI.encode_www_form(params) 17 + end 18 + 19 + response = ::Net::HTTP.get_response(url, headers) 20 + raise ResponseError, "Invalid response: #{response.code} #{response.body}" if response.code.to_i / 100 != 2 21 + 22 + JSON.parse(response.body) 23 + end 7 24 8 25 def self.post_request(server, method, data, auth: nil, content_type: "application/json") 9 26 headers = {}