~edwardloveall/scribe

bb94fb41b198b78566d0ab8400d31ccb3e5bc142 — Edward Loveall 3 months ago 91687bb
Support medium's redirectUrl query param

When a post has a gi= query param, Medium makes a global_identifier
"query". This redirects via a 307 temporary redirect to a url that
looks like this:

https://medium.com/m/global-identity?redirectUrl=https%3A%2F%2Fexample.c
om%2Fmy-post-000000000000

Previously, scribe looked for the Medium post id in the url's path, not
it's query params since query params can include other garbage like
medium_utm (not related to medium.com). Now it looks first for the post
id in the path, then looks to the redirectUrl as a fallback.
2 files changed, 24 insertions(+), 4 deletions(-)

M spec/requests/articles/show_spec.cr
M src/actions/articles/show.cr
M spec/requests/articles/show_spec.cr => spec/requests/articles/show_spec.cr +6 -0
@@ 68,4 68,10 @@ describe Articles::Show do

    TestClient.last_post_id.should eq("777777abcdef")
  end

  it "parses the post id for global identity redirects" do
    HttpClient.get("/m/global-identity?redirectUrl=https%3A%2F%2Fexample.com%2Fmy-post-888888abcdef")

    TestClient.last_post_id.should eq("888888abcdef")
  end
end

M src/actions/articles/show.cr => src/actions/articles/show.cr +18 -4
@@ 2,10 2,10 @@ require "json"

class Articles::Show < BrowserAction
  fallback do
    maybe_post_id = post_id(context.request.path)
    case maybe_post_id
    post_id = maybe_post_id(context.request)
    case post_id
    in Monads::Just
      response = client_class.post_data(maybe_post_id.value!)
      response = client_class.post_data(post_id.value!)
      page = PageConverter.new.convert(response.data)
      html ShowPage, page: page
    in Monads::Nothing, Monads::Maybe


@@ 17,13 17,27 @@ class Articles::Show < BrowserAction
    end
  end

  def post_id(request_path : String)
  def maybe_post_id(request : HTTP::Request)
    from_params = post_id_from_params(request.query_params)
    from_path = post_id_from_path(request.path)
    from_path.or(from_params)
  end

  def post_id_from_path(request_path : String)
    Monads::Try(Regex::MatchData)
      .new(->{ request_path.match(/([0-9a-f]+)$/i) })
      .to_maybe
      .fmap(->(matches : Regex::MatchData) { matches[1] })
  end

  def post_id_from_params(params : URI::Params)
    maybe_uri = Monads::Try(String)
      .new(->{ params["redirectUrl"] })
      .to_maybe
      .fmap(->(url : String) { URI.parse(url) })
      .bind(->(uri : URI) { post_id_from_path(uri.path) })
  end

  def client_class
    if Lucky::Env.use_local?
      LocalClient