~vesto/gists

e7b3259b813994f944d797ee756dd35a2bb60d71 — Steve Gattuso 2 months ago 6056b2f main
add mastodon_comments.rb
1 files changed, 64 insertions(+), 0 deletions(-)

A mastodon_comments.rb
A mastodon_comments.rb => mastodon_comments.rb +64 -0
@@ 0,0 1,64 @@
# This plugin scans through all pages of your Jekyll site looking for a
# `mastodon_url` key in the frontmatter. When this key is populated with a
# Mastodon toot URL, it will fetch the replies and store them in
# `page.mastodon_activity`, which can then be rendered into your template
# however you see fit.
#
# You can install this into your Jekyll instance by downloading this file into
# the _plugins/ directory within your Jekyll site.
#
# Note that, in order to work correctly, you'll have to add a
# `mastodon_access_token` to your _config.yaml file. See the docs[^0] for
# details
#
# [0]: https://docs.joinmastodon.org/methods/oauth/#token
require "http"
require "uri"

DAY_AGO = 1000 * 60 * 60 * 24

def inject_comments!(page)
  return if !page.data.key?("mastodon_url")

  url = URI(page.data["mastodon_url"])
  status_id = url.path.split("/")[-1]
  status_url = "#{url.scheme}://#{url.host}/api/v1/statuses/#{status_id}/context"

  cache = Jekyll::Cache.new("MastodonComments")

  activity = nil
  if cache.key?(status_url) && Time.now.to_i - cache[status_url][:last_fetched_at] < DAY_AGO
    puts("Using cached activity for #{page.data["title"]}")
    activity = cache[status_url][:payload]
  else
    puts("Fetching Mastodon activity for #{page.data["title"]}")
    resp = HTTP
      .auth("Bearer #{page.site.config["mastodon_access_token"]}")
      .get(status_url)
    activity = JSON.parse(resp.to_s)

    cache[status_url] = {
      last_fetched_at: Time.now.to_i,
      payload: activity,
    }
  end

  # Ensure we don't accidentally expose private replies
  def is_public?(status)
    ["public", "unlisted"].include? status["visibility"]
  end
  activity["ancestors"].select! { |status| is_public?(status) }
  activity["descendants"].select! { |status| is_public?(status) }

  page.data["mastodon_activity"] = activity
end

Jekyll::Hooks.register :site, :pre_render do |site|
  site.posts.docs.each do |post|
    inject_comments!(post)
  end
  site.pages.each do |page|
    inject_comments!(page)
  end
end