Skip to content

Instantly share code, notes, and snippets.

@wvengen
Created July 17, 2026 13:06
Show Gist options
  • Select an option

  • Save wvengen/827ec18fb69021128e46af30da779c46 to your computer and use it in GitHub Desktop.

Select an option

Save wvengen/827ec18fb69021128e46af30da779c46 to your computer and use it in GitHub Desktop.
Joining an Hypothesis group
#!/usr/bin/env ruby
#
# Joining an Hypothesis group is done through the web, and there is no API method to do so.
# Sometimes this is useful. Here is an implementation that logs into Hypothesis, and joins a group.
#
# Set the environment variables:
# HYPOTHESIS_USERNAME
# HYPOTHESIS_PASSWORD
# Then call the script with argument the Hypothesis group id.
# ruby join_hypothesis_group.rb abcd12345
#
# https://hypothes.is/
#
require 'faraday'
def web_join_group(id)
conn = web_connection
cookies = {}
# get csrf token for login
res = conn.get("login")
csrf_token = web_csrf_token res
return false unless csrf_token
cookies.merge! cookie_header_to_hash(res.headers["Set-Cookie"])
# login
res = conn.post("login", csrf_token:, username: ENV["HYPOTHESIS_USERNAME"], password: ENV["HYPOTHESIS_PASSWORD"]) do |req|
req.headers["Cookie"] = cookies.map { |k, v| [ k, v ].join("=") }.join("; ")
end
cookies.merge! cookie_header_to_hash(res.headers["Set-Cookie"])
# join group
conn.post("groups/#{id}/", group_join: "") do |req|
req.headers["Cookie"] = cookies.map { |k, v| [ k, v ].join("=") }.join("; ")
end
true
end
def web_connection
Faraday.new(url: "https://hypothesis.is/") do |builder|
builder.request :url_encoded
builder.response :raise_error
end
end
def web_csrf_token(response)
response.body.match(/"csrfToken"\s*:\s*"([^"]+)"/)&.captures&.first
end
# Somehow the existing cookie jar implementations didn't work when parsing multiple cookies.
def cookie_header_to_hash(cookies)
cookies&.split(/,\s*(?=[^ ,;=]+=)/)&.map { |c| c.split(";").first.split("=") }&.to_h
end
web_join_group(ARGV.argv[0])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment