Skip to content

Commit c2cd098

Browse files
committed
Update feed documentation: refine table formatting, outline fediverse integration plan, and detail future ActivityPub support.
1 parent d7de6b5 commit c2cd098

1 file changed

Lines changed: 49 additions & 12 deletions

File tree

docs/feed.md

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,52 @@ is distinguishable from one that does not.
7575
The `<guid>` deliberately does **not** carry them. Bridges dedupe on the guid, so anything that moves with
7676
a campaign name would repost every member to every follower.
7777

78-
## Next steps
79-
80-
1. **Point an RSS→ActivityPub bridge at a country feed** and watch the `utm_campaign` numbers. No code —
81-
[RSS Parrot](https://rss-parrot.net/) is self-serve and one-way, which is exactly the scope we want: from
82-
[@compassmeet@mastodon.social](https://mastodon.social/@compassmeet), post a toot mentioning
83-
`@birb@rss-parrot.net` with the feed URL (`https://www.compassmeet.com/feed.xml?country=Italy`), and it
84-
replies with the account it created for that feed — which then has to be followed for anything to appear
85-
in a timeline. It reads `<description>`, so what members see is exactly the projection above.
86-
Prerequisite: the migration applied and web deployed, so the URL actually answers.
87-
2. Only if that converts: a native read-only actor (WebFinger, actor, outbox, accepting `Follow` and
88-
`Undo`, nothing else). Inbound DMs are deliberately out of scope — a federated sender arrives with no
89-
email, no profile and no history, which imports the scam problem, and Compass messages are encrypted.
78+
## Getting into the fediverse
79+
80+
**No RSS→ActivityPub bridge.** A bridge (RSS Parrot and friends) is one toot and no code, but it fails on
81+
the two things that decide whether this works: a bridge account cannot post hashtags, which is most of how
82+
anything is discovered on the fediverse, and its followers belong to the bridge — they cannot be carried
83+
over to a `@compass@compassmeet.com` actor later. A null result from a bridge would have measured the
84+
bridge, not the idea.
85+
86+
\*\*Plan: post each new profile from [@compassmeet@mastodon.social](https://mastodon.social/@compassmeet),
87+
three days after signup.
88+
89+
Why three days rather than on signup:
90+
91+
- Syndication cannot be recalled. Three days is the window in which a member can fill their profile in,
92+
notice the setting, switch it off, or go members-only — all before anything leaves the site.
93+
- A profile at signup is usually empty. About a third of the entries in the live feed have no headline, no
94+
city and no keywords; posting those yields "New on Compass: verlish" and helps nobody.
95+
96+
What it would reuse rather than reinvent:
97+
98+
| Piece | Existing pattern to follow |
99+
| -------------------------- | ----------------------------------------------------------------------------------------------------- |
100+
| Content and privacy levels | `get-profile-feed` — one projection, two transports |
101+
| Posting | `sendDiscordMessage` in `common/src/discord/core.ts`, but `POST /api/v1/statuses` with a Bearer token |
102+
| Scheduling | `internalOutreachJob` in `backend/api/src/app.ts` (Cloud Scheduler + `x-api-key`) |
103+
| Not posting twice | the send-ledger pattern from `outreach_sends` / `search_alert_sends` |
104+
105+
Hashtags come from `keywords`, which is why they sit at the `basic` level. Cap them (~3): excessive
106+
hashtags read as spam on most instances. Mark the account as a bot.
107+
108+
Accepted trade-off: posting from the main `@compassmeet` account rather than a separate bot account means a
109+
moderation complaint against a profile post lands on the announcement channel too. Deliberate — worth
110+
revisiting only if volume grows.
111+
112+
## After that: a native actor at `compassmeet.com`
113+
114+
Only worth it once the Mastodon account has followers to inherit — and they _do_ transfer, via
115+
`alsoKnownAs` + a `Move` activity, which is the reason for posting from an account we own rather than a
116+
bridge's.
117+
118+
Scope: read-only. WebFinger, an actor document, an outbox, and an inbox that accepts `Follow` and `Undo`
119+
and ignores everything else. Roughly 500–700 lines hand-rolled, or ~200 with a library like
120+
[Fedify](https://fedify.dev/) (which brings WebFinger, actor dispatch, HTTP Signatures, a delivery queue
121+
and NodeInfo). Only `/.well-known/webfinger` has to be served from `compassmeet.com`; the actor, inbox and
122+
outbox can live on the API, reached through a Vercel rewrite.
123+
124+
A full instance — every member as their own actor — is a different category of undertaking (per-member
125+
keypairs, inbound replies, remote blocks and reports, moderation duties). If it is ever wanted, run
126+
GoToSocial or Mastodon alongside rather than write it?

0 commit comments

Comments
 (0)