helpers do def curl ext, url #p "/run/current-system/sw/bin/curl -fsSL #{ext} #{url}" response = `/run/current-system/sw/bin/curl -fsSL #{ext} #{url}` $?.success? ? response : nil end def fetch url, accept = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' response = curl("-H 'Accept: #{accept}'", url) response ? JSON.parse(response) : nil end # https://github.com/mastodon/mastodon/blob/main/app/lib/request.rb def send_signed object, url keypair = OpenSSL::PKey::RSA.new(File.read('private.pem')) date = Time.now.utc.httpdate body = object.to_json sha256 = OpenSSL::Digest::SHA256.new digest = "SHA-256=" + sha256.base64digest(body) host = URI.parse(url).host inbox = fetch(url)["inbox"] return false unless inbox request_uri = URI(inbox).request_uri signed_string = "(request-target): post #{request_uri}\nhost: #{host}\ndate: #{date}\ndigest: #{digest}\ncontent-type: application/activity+json" signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), signed_string)) signed_header = 'keyId="' + ACTOR + '#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="' + signature + '"' p curl("-X POST -H 'Content-Type: application/activity+json' -H 'Host: #{host}' -H 'Date: #{date}' -H 'Digest: #{digest}' -H 'Signature: #{signed_header}' -d '#{body}'", inbox) $?.success? end def people File.read('cache/people.tsv').split("\n").collect {|l| l.chomp.split("\t")} end def mention actor person = people.select{|p| p[1] == actor} if person.empty? a = fetch(actor) return nil unless a mention = "#{a["preferredUsername"]}@#{URI(actor).host}" File.open('cache/people.tsv','a'){|f| f.puts "#{mention}\t#{actor}"} mention else person[0][0] end end def actor mention mention = mention.sub(/^@/, '').chomp actors = people.select{|p| p[0] == mention} if actors.empty? user, server = mention.split("@") a = fetch("https://#{server}/.well-known/webfinger?resource=acct:#{mention}", "application/jrd+json") return nil unless a actor = a["links"].select { |l| l["rel"] == "self" }[0]["href"] File.open('cache/people.tsv','a'){|f| f.puts "#{mention}\t#{actor}"} actor else actors[0][1] end end end