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
- .config_for(site) ⇒ Object
- .enabled?(site) ⇒ Boolean
-
.network_config(site, name) ⇒ Object
Network-specific config sub-hash with the per-network defaults folded in.
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
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 |