Module: Abqari::Syndication

Defined in:
lib/abqari/syndication.rb

Overview

Syndication — Milestone B of the IndieWeb work.

POSSE = "Publish on your Own Site, Syndicate Elsewhere." On each build, for every post not yet syndicated, post a short summary + canonical URL to the configured destinations (Mastodon, Bluesky). The originating posts on those networks point back at the site's canonical version — search engines see your site as the source of truth, while readers who only follow you on Mastodon/Bluesky still discover new work.

Each destination is a separate class under Syndication::Networks, implementing two methods:

* `configured?` — has the operator filled in the required tokens?
* `post(text:, url:)` — POST the syndicated snippet, return the
resulting URL of the syndicated post (or nil on failure).

The dispatcher walks recent posts, formats the snippet for each network (different length limits), and tracks every successful post in vendor/syndication/sent.yml so re-builds never double- syndicate.

Config (syndication: block in config/site.yml):

syndication:
  enabled: true                     # master switch
  window_days: 14                   # only syndicate posts published
                                    #   within the last N days (older
                                    #   posts predate syndication setup)
  mastodon:
    enabled: true
    instance: https://mastodon.social
    access_token: "..."             # from your instance's app settings
    visibility: public              # public | unlisted | private
  bluesky:
    enabled: true
    handle: yourname.bsky.social    # the full handle, with .bsky.social
    app_password: "..."             # app password, NOT account password

Defined Under Namespace

Modules: Formatter, Networks Classes: Dispatcher

Constant Summary collapse

USER_AGENT =
"abqari-syndication/#{Abqari::VERSION}"
MAX_RESPONSE_BYTES =

Per-response body cap for Mastodon / Bluesky API calls. API responses for a single status are <10 KB; 2 MB is far above the worst case and exists so a misbehaving instance can't OOM the build by streaming an unbounded body.

2 * 1024 * 1024
LIMITS =

Hard caps per network. Mastodon allows configurable instance max (default 500) — we use the conservative default so the same snippet posts cleanly to any instance. Bluesky enforces 300.

{ 'mastodon' => 500, 'bluesky' => 300 }.freeze

Class Method Summary collapse

Class Method Details

.config_for(site) ⇒ Object



64
65
66
# File 'lib/abqari/syndication.rb', line 64

def self.config_for(site)
  site.config['syndication'] || {}
end

.enabled?(site) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
71
# File 'lib/abqari/syndication.rb', line 68

def self.enabled?(site)
  cfg = config_for(site)
  cfg['enabled'] == true
end

.network_config(site, name) ⇒ Object

Network-specific config sub-hash with the per-network defaults folded in. enabled defaults to true within a network block — configuring it at all means you want it on, unless explicitly off.



76
77
78
# File 'lib/abqari/syndication.rb', line 76

def self.network_config(site, name)
  (config_for(site)[name] || {}).merge('name' => name)
end