Blame


1 93390e9f 2024-03-14 o <html>
2 93390e9f 2024-03-14 o <head>
3 93390e9f 2024-03-14 o <meta charset="utf-8">
4 93390e9f 2024-03-14 o <meta name="viewport" content="width=device-width, initial-scale=1">
5 93390e9f 2024-03-14 o <title>Apas: bla bla bla</title>
6 93390e9f 2024-03-14 o <link rel="stylesheet" href="style.css">
7 93390e9f 2024-03-14 o </head>
8 93390e9f 2024-03-14 o
9 93390e9f 2024-03-14 o <body>
10 93390e9f 2024-03-14 o <article>
11 93390e9f 2024-03-14 o <h1 id="apas-activitypub-via-email">Apas: ActivityPub via email</h1>
12 93390e9f 2024-03-14 o <p>By Oliver Lowe &#60;<a href="mailto:o@olowe.co">o@olowe.co</a>&#62; (<a href="https://apas.srcbeat.com/otl/actor.json">otl@apubtest2.srcbeat.com</a>)</p>
13 93390e9f 2024-03-14 o <blockquote>
14 93390e9f 2024-03-14 o <p>Every program attempts to expand until it can read mail.
15 93390e9f 2024-03-14 o Those programs which cannot so expand are replaced by ones which can.</p>
16 93390e9f 2024-03-14 o </blockquote>
17 93390e9f 2024-03-14 o <p>—<a href="https://en.wikipedia.org/wiki/Jamie_Zawinski#Zawinski&#x27;s_Law">Zawinski&#8217;s Law of Software Envelopment</a></p>
18 93390e9f 2024-03-14 o <p><strong><a href="https://git.olowe.co/apub">Source code</a></strong> | <strong><a href="https://godoc.org/olowe.co/apub">GoDoc</a></strong></p>
19 93390e9f 2024-03-14 o <hr/>
20 93390e9f 2024-03-14 o <p>The most popular systems on the <a href="https://en.wikipedia.org/wiki/ActivityPub">ActivityPub</a>-speaking [Fediverse] are imitations of non-federated platforms.
21 93390e9f 2024-03-14 o <a href="https://joinmastodon.org">Mastodon</a> and <a href="https://misskey-hub.net">Misskey</a> are <a href="https://en.wikipedia.org/wiki/Twitter">Twitter</a> clones;
22 93390e9f 2024-03-14 o <a href="https://join-lemmy.org">Lemmy</a> is a <a href="https://en.wikipedia.org/wiki/Reddit">Reddit</a> clone.
23 93390e9f 2024-03-14 o But ActivityPub –
24 93390e9f 2024-03-14 o the protocol connecting all these systems together –
25 93390e9f 2024-03-14 o is often said to be similar to email,
26 93390e9f 2024-03-14 o which involves exchanging messages.
27 93390e9f 2024-03-14 o In the case of at least Mastodon and Lemmy,
28 93390e9f 2024-03-14 o ActivityPub was implemented after the bulk of each sofware was designed.
29 93390e9f 2024-03-14 o Message exchange – federation by ActivityPub – is arguably a second-class citizen for these
30 93390e9f 2024-03-14 o traditional <a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> web applications backed by SQL databases and fronted by web browser UIs.</p>
31 93390e9f 2024-03-14 o <p>Apas is an experiment in exposing ActivityPub in a familiar and popular interface: email.
32 93390e9f 2024-03-14 o Its primary goal is to clarify how ActivityPub and the Fediverse work for the broader community.
33 93390e9f 2024-03-14 o A number of secondary goals are detailed later.</p>
34 93390e9f 2024-03-14 o <h2 id="1.-motivation">1. Motivation</h2>
35 93390e9f 2024-03-14 o <p>As a fan of <a href="http://9p.io/plan9/">Plan 9</a> and a weirdo who likes to fiddle with network protocols for fun,
36 93390e9f 2024-03-14 o I was disappointed with what using Mastodon, Lemmy et al. felt like.</p>
37 93390e9f 2024-03-14 o <p>What excites me is <em>communication!</em>
38 93390e9f 2024-03-14 o Exchanging messages <em>between</em> people, systems, and places we can&#8217;t think of yet!
39 93390e9f 2024-03-14 o It&#8217;s what makes receiving even just a single email from a random person such a viscerally distinct experience from
40 93390e9f 2024-03-14 o thousands reading your post you uploaded somewhere.
41 93390e9f 2024-03-14 o We&#8217;re communicating!</p>
42 93390e9f 2024-03-14 o <p>Implementing a subset of the Mastodon and Lemmy HTTP APIs in a couple of languages was relatively straightforward.
43 93390e9f 2024-03-14 o After writing some small clients and tooling
44 93390e9f 2024-03-14 o it felt like I was just dealing with platforms,
45 93390e9f 2024-03-14 o not a federated universe.
46 93390e9f 2024-03-14 o The pattern was familiar for many software developers:</p>
47 93390e9f 2024-03-14 o <ul>
48 93390e9f 2024-03-14 o <li>You create a post,</li>
49 93390e9f 2024-03-14 o <li>that gets written to a database,</li>
50 93390e9f 2024-03-14 o <li>you get an ID back, indicating success.</li>
51 93390e9f 2024-03-14 o </ul>
52 93390e9f 2024-03-14 o <p>But the whole federation bit is obscured.
53 93390e9f 2024-03-14 o You hope that others can see that post&#8230; somehow&#8230;?
54 93390e9f 2024-03-14 o The platform thinking is evident in the language we see around these systems:
55 93390e9f 2024-03-14 o &#8220;I saw this on Lemmy&#8221;, or &#8220;this is trending on Mastodon&#8221;, or &#8220;find me on Akkoma&#8221;.
56 93390e9f 2024-03-14 o Nobody says &#8220;find me on email&#8221; or &#8220;someone sent this on email&#8221;.</p>
57 93390e9f 2024-03-14 o <p>Interoperability efforts fall flat when expertise in one system does not translate to another.
58 93390e9f 2024-03-14 o Moderation and tooling discussions are artificially limited to a particular system.
59 93390e9f 2024-03-14 o Should a plugin for Friendica filtering posts containing racist language only work with Friendica when all the systems work together?
60 93390e9f 2024-03-14 o Should it even be a plugin tied to one particular system in a particular programming language at all?</p>
61 93390e9f 2024-03-14 o <p>Finally, interoperability and portability is the &#8220;killer feature&#8221; of ActivityPub systems and any significant software system.
62 93390e9f 2024-03-14 o We know software developers can write standalone Twitter clones day-in, day-out.
63 93390e9f 2024-03-14 o But no amount of funding to Instagram or any other incumbent commercial platform
64 93390e9f 2024-03-14 o will ever make it available for
65 93390e9f 2024-03-14 o shitty government systems,
66 93390e9f 2024-03-14 o space stations,
67 93390e9f 2024-03-14 o embedded devices,
68 93390e9f 2024-03-14 o your grandmother,
69 93390e9f 2024-03-14 o charities,
70 93390e9f 2024-03-14 o snail mail,
71 93390e9f 2024-03-14 o VR headsets, and
72 93390e9f 2024-03-14 o automatic vacuum cleaners
73 93390e9f 2024-03-14 o <em>all at once</em>.</p>
74 93390e9f 2024-03-14 o <p>Writing better software systems often means communicating better.
75 93390e9f 2024-03-14 o That means understanding ActivityPub better.</p>
76 93390e9f 2024-03-14 o <h2 id="2.-overview">2. Overview</h2>
77 93390e9f 2024-03-14 o <p><strong>Apas</strong> is mostly inspired by the <a href="http://doc.cat-v.org/bell_labs/upas_mail_system/">upas</a> email system available with <a href="http://9p.io/plan9/">Plan 9</a>;
78 93390e9f 2024-03-14 o a collection of small programs operate on files and streams,
79 93390e9f 2024-03-14 o relaying messages out to the Internet or
80 93390e9f 2024-03-14 o delivering to mailboxes on the filesystem.
81 fb77ab16 2024-03-15 o (But it&#8217;s so much more limited and poorly designed than upas that I was hesitant to even write this bit!)</p>
82 fb77ab16 2024-03-15 o <p>An important difference from existing Fediverse software is that
83 fb77ab16 2024-03-15 o <strong>apas</strong> only represents Activities as messages.
84 fb77ab16 2024-03-15 o There are no application-specific data structures like
85 fb77ab16 2024-03-15 o posts, toots, comments, or pages.
86 fb77ab16 2024-03-15 o Messages can be files in a filesystem,
87 fb77ab16 2024-03-15 o which simplifies implementation significantly.</p>
88 93390e9f 2024-03-14 o <h3 id="2.1-messages">2.1 Messages</h3>
89 93390e9f 2024-03-14 o <p><strong>Apas</strong> marshals ActivityPub objects into <a href="https://www.rfc-editor.org/rfc/rfc5322">RFC5322</a> messages and vice-versa.</p>
90 93390e9f 2024-03-14 o <p>The <a href="https://www.w3.org/TR/activitystreams-vocabulary/#dfn-note">Note Activity</a> is probably the most recognisable object exchanged by ActivityPub servers.
91 93390e9f 2024-03-14 o They are represented as comments by Lemmy, and posts (toots?) by Mastodon.
92 93390e9f 2024-03-14 o For instance, imagine a reply from Alex to Bowie talking about motorcycle tyres.
93 fb77ab16 2024-03-15 o It&#8217;s passed around the Fediverse as JSON-encoded data like this:</p>
94 93390e9f 2024-03-14 o <pre><code>{
95 93390e9f 2024-03-14 o "type": "Note"
96 93390e9f 2024-03-14 o "id": "https:&#47;&#47;apub.example.com&#47;alex&#47;12345678",
97 93390e9f 2024-03-14 o "attributedTo": "https:&#47;&#47;apub.example.com&#47;alex"
98 93390e9f 2024-03-14 o "to": "https:&#47;&#47;apas.test.example&#47;bowie&#47;87654321",
99 93390e9f 2024-03-14 o "cc": "https:&#47;&#47;apas.test.example&#47;bowie&#47;followers",
100 93390e9f 2024-03-14 o "inReplyTo": "https:&#47;&#47;apas.test.example&#47;bowie&#47;87654321",
101 93390e9f 2024-03-14 o "name": "Thoughts on 50&#47;50 tyres"
102 93390e9f 2024-03-14 o "content": "But what if you don&#39;t know when you want to ride off-road?",
103 93390e9f 2024-03-14 o }
104 93390e9f 2024-03-14 o </code></pre>
105 93390e9f 2024-03-14 o <p>For <strong>apas</strong> this is equivalent to the mail message:</p>
106 fb77ab16 2024-03-15 o <pre><code>From: "Alex " &#60;alex@apub.example.com&#62;
107 93390e9f 2024-03-14 o To: "Bowie" &#60;bowie@apas.test.example&#62;
108 93390e9f 2024-03-14 o CC: "Bowie (followers)" &#60;bowie+followers@apas.test.example&#62;
109 93390e9f 2024-03-14 o Message-ID: &#60;https:&#47;&#47;apub.example.com&#47;alex&#47;12345678&#62;
110 93390e9f 2024-03-14 o In-Reply-To: &#60;https:&#47;&#47;apas.test.example&#47;bowie&#47;87654321&#62;
111 93390e9f 2024-03-14 o Subject: Thoughts on 50&#47;50 tyres
112 93390e9f 2024-03-14 o
113 93390e9f 2024-03-14 o But what if you don&#39;t know when you want to ride off-road?
114 93390e9f 2024-03-14 o </code></pre>
115 fb77ab16 2024-03-15 o <p>Unlike other Fediverse software,
116 fb77ab16 2024-03-15 o the message to be distributed is written and read by people; not just machines.
117 93390e9f 2024-03-14 o For developers, administrators, and advanced users, seeing data like
118 fb77ab16 2024-03-15 o this builds familiarity with the behaviour between systems,
119 fb77ab16 2024-03-15 o and facilitates communication.
120 fb77ab16 2024-03-15 o We go from &#8220;why can I see my toot on Kbin but not on Pleroma?&#8221; to
121 fb77ab16 2024-03-15 o &#8220;why didn&#8217;t your Pleroma server receive my message?&#8221;
122 fb77ab16 2024-03-15 o which is a much easier question to answer; it&#8217;s what the systems are actually doing.</p>
123 93390e9f 2024-03-14 o <p>If there was only one thing to take away from <strong>apas</strong>, it&#8217;s that
124 fb77ab16 2024-03-15 o familiarity with data over an API is hugely helpful for
125 fb77ab16 2024-03-15 o troubleshooting. Especially when typical bug reports consist of URLs
126 fb77ab16 2024-03-15 o to irrelevant web apps (or even just screenshots!) trying to explain
127 fb77ab16 2024-03-15 o what was sent versus what was received. That&#8217;s before we we even
128 fb77ab16 2024-03-15 o address what could be in a database, itself requiring its own query
129 fb77ab16 2024-03-15 o language and tightly-controlled administrative access to read.</p>
130 93390e9f 2024-03-14 o <h3 id="2.2.-sending">2.2. Sending</h3>
131 93390e9f 2024-03-14 o <p>Presenting posts, comments, notes, etc. as a mail message immediately
132 93390e9f 2024-03-14 o clarifies a big source of confusion with existing systems:
133 93390e9f 2024-03-14 o why isn&#8217;t my post showing up?
134 93390e9f 2024-03-14 o It becomes easier to reason about this when it is obvious where is a message is sent.
135 93390e9f 2024-03-14 o An email lists recipients explicitly.
136 93390e9f 2024-03-14 o When replying to a Kbin comment via Mastodon,
137 93390e9f 2024-03-14 o it takes knowledge of how each system is implemented to know who the
138 93390e9f 2024-03-14 o recipients are, if any.</p>
139 93390e9f 2024-03-14 o <p>Regular email clients
140 93390e9f 2024-03-14 o (or even any old text editor!)
141 93390e9f 2024-03-14 o provide an interactive way to test other AP systems.
142 93390e9f 2024-03-14 o For instance, we can easily test how the message is received if we address the recipient in the <code>CC</code> field instead of <code>To</code>,
143 fb77ab16 2024-03-15 o or if we list the same recipient 20 times in both fields.
144 fb77ab16 2024-03-15 o <strong>Apas</strong> could report deliverability errors either:</p>
145 93390e9f 2024-03-14 o <ul>
146 93390e9f 2024-03-14 o <li>immediately, or</li>
147 93390e9f 2024-03-14 o <li>as a bounced message</li>
148 93390e9f 2024-03-14 o </ul>
149 fb77ab16 2024-03-15 o <p>At the moment, error messages are returned immediately.
150 93390e9f 2024-03-14 o This has provided a pleasant enough testing experience
151 93390e9f 2024-03-14 o that makes learning ActivityPub an interactive process,
152 fb77ab16 2024-03-15 o directly from any mail client, especially compared with the
153 93390e9f 2024-03-14 o usual drudgery of sifting through logs of big web applications.</p>
154 fb77ab16 2024-03-15 o <p>Sending is involves two programs each playing its own role:</p>
155 fb77ab16 2024-03-15 o <ol>
156 fb77ab16 2024-03-15 o <li>Asubmission program accepts messages from authorised users, and</li>
157 fb77ab16 2024-03-15 o <li>A mailer handles sending messages to the Internet.</li>
158 fb77ab16 2024-03-15 o </ol>
159 93390e9f 2024-03-14 o <p><img src="send.png" alt="" /></p>
160 93390e9f 2024-03-14 o <h4 id="2.2.1.-submission">2.2.1. Submission</h4>
161 93390e9f 2024-03-14 o <p>Messages are submitted to a server running <code>apsubmit</code>.
162 93390e9f 2024-03-14 o <code>apsubmit</code> is a SMTP server.
163 93390e9f 2024-03-14 o It listens for SMTP connections,
164 93390e9f 2024-03-14 o authenticates the session,
165 93390e9f 2024-03-14 o then passes the received message to the mailer <code>apsend</code>.</p>
166 93390e9f 2024-03-14 o <p>SMTP is a widely implemented protocol.
167 93390e9f 2024-03-14 o <code>apsubmit</code> enables
168 93390e9f 2024-03-14 o existing mail clients,
169 93390e9f 2024-03-14 o embededed devices,
170 93390e9f 2024-03-14 o and systems that I don&#8217;t even know exist,
171 93390e9f 2024-03-14 o to publish to the Fediverse.</p>
172 93390e9f 2024-03-14 o <p>For personal use,
173 93390e9f 2024-03-14 o it has been fine using <a href="http://www.mutt.org">mutt</a> via SSH on a Linux server,
174 93390e9f 2024-03-14 o <a href="https://sylpheed.sraoss.jp/en/">Sylpheed</a> on my OpenBSD laptop,
175 93390e9f 2024-03-14 o <a href="https://freron.com">MailMate</a> on a shared iMac,
176 93390e9f 2024-03-14 o and the built-in Mail app on my iPhone for replies.
177 93390e9f 2024-03-14 o I&#8217;ll leave others to come up with more ideas;
178 93390e9f 2024-03-14 o keep in mind weather stations, printers, video records can usually
179 93390e9f 2024-03-14 o send email but definitely cannot speak ActivityPub!</p>
180 fb77ab16 2024-03-15 o <p>For fast feedback,
181 93390e9f 2024-03-14 o <code>apsubmit</code> takes advantage of the <code>RCPT</code> stage of the SMTP transaction.
182 93390e9f 2024-03-14 o It verifies that listed recipients exist and have inboxes we can target.
183 93390e9f 2024-03-14 o This is in contrast with e.g. Mastodon,
184 93390e9f 2024-03-14 o which will always accept creating the following post:</p>
185 93390e9f 2024-03-14 o <pre><code>@john@nowhere.invalid @deleteduser@example.org what do you think?
186 93390e9f 2024-03-14 o </code></pre>
187 93390e9f 2024-03-14 o <p>There&#8217;s several possible error conditions here. For <code>john</code>, perhaps:</p>
188 93390e9f 2024-03-14 o <ul>
189 93390e9f 2024-03-14 o <li>their server is down and messages are undeliverable,</li>
190 93390e9f 2024-03-14 o <li>their Actor is misconfigured and is missing an <code>inbox</code> endpoint,</li>
191 93390e9f 2024-03-14 o <li>the address is totally invalid</li>
192 93390e9f 2024-03-14 o </ul>
193 93390e9f 2024-03-14 o <p>For <code>deleteduser</code>, perhaps the account no longer exists.
194 93390e9f 2024-03-14 o Mastodon never notifies of any delivery errors.
195 93390e9f 2024-03-14 o We could ask the server administrators to trawl through the server&#8217;s logs for us,
196 93390e9f 2024-03-14 o or ask <code>johnny</code> and <code>deleteduser</code> out-of-band if they got our message.
197 fb77ab16 2024-03-15 o Accounting for some common errors at submission time obviates that extra work.</p>
198 93390e9f 2024-03-14 o <h4 id="2.2.2-mailer">2.2.2 Mailer</h4>
199 93390e9f 2024-03-14 o <p>Sending messages is performed by a command-line utility called <code>apsend</code>.
200 93390e9f 2024-03-14 o <code>apsend</code> reads a message from standard input and disposes of it based on the recipients.
201 fb77ab16 2024-03-15 o If the above message from Alex to Bowie was in a file called &#8220;note.eml&#8221;,
202 93390e9f 2024-03-14 o we could send it with the following shell command:</p>
203 93390e9f 2024-03-14 o <pre><code>apsend -t &#60; file.eml
204 93390e9f 2024-03-14 o </code></pre>
205 fb77ab16 2024-03-15 o <p>In general, <code>apsend</code> is not intended to be executed directly.
206 fb77ab16 2024-03-15 o Instead, a frontend like an email client (sending via SMTP)
207 fb77ab16 2024-03-15 o or a tool like Plan 9&#8217;s <a href="https://9p.io/magic/man2html?man=marshal&amp;sect=1">marshal(1)</a>
208 fb77ab16 2024-03-15 o should be used which take care of adding entries to and formatting the
209 fb77ab16 2024-03-15 o header correctly.</p>
210 93390e9f 2024-03-14 o <h3 id="2.3-receiving">2.3 Receiving</h3>
211 fb77ab16 2024-03-15 o <p>Core to <strong>apas</strong> is handling ActivityPub objects as files in a filesystem.
212 fb77ab16 2024-03-15 o This reveals there are many different ways to retrieve Activitity from the Fediverse
213 fb77ab16 2024-03-15 o beyond the typical process of servers sending Activity to an Actor&#8217;s inbox.
214 fb77ab16 2024-03-15 o <strong>Apas</strong> of course supports this (see 2.3.2),
215 fb77ab16 2024-03-15 o but it&#8217;s worth mentioning other techniques to show how flexible
216 fb77ab16 2024-03-15 o working with the Fediverse can be.
217 fb77ab16 2024-03-15 o It may also help clarify discussions on user privacy.</p>
218 fb77ab16 2024-03-15 o <h4 id="2.3.1-direct">2.3.1 Direct</h4>
219 fb77ab16 2024-03-15 o <p>This was the first implementation of receiving ActivityPub objects for <strong>apas</strong>.
220 fb77ab16 2024-03-15 o The command <code>apget</code> fetches the Activity at a URL, then writes it to the standard output.
221 fb77ab16 2024-03-15 o Throughout testing, I ran the tool in shell scripts like the below to deliver messages to my inbox:</p>
222 fb77ab16 2024-03-15 o <pre><code>apget https:&#47;&#47;apub.example.com&#47;alex&#47;12345678 | apsend otl
223 fb77ab16 2024-03-15 o </code></pre>
224 fb77ab16 2024-03-15 o <p>Little shell scripts can fetch a series of posts:</p>
225 fb77ab16 2024-03-15 o <pre><code>for i in `seq 12345671 12345678`
226 fb77ab16 2024-03-15 o do
227 fb77ab16 2024-03-15 o apget -m https:&#47;&#47;apub.example.com&#47;alex&#47;$i
228 fb77ab16 2024-03-15 o done
229 fb77ab16 2024-03-15 o </code></pre>
230 fb77ab16 2024-03-15 o <p>Obviously this is inefficient compared to other methods,
231 fb77ab16 2024-03-15 o but we&#8217;re not Google.
232 fb77ab16 2024-03-15 o Handy ad-hoc testing.</p>
233 fb77ab16 2024-03-15 o <h4 id="2.3.2-targeting-the-activitypub-inbox">2.3.2 Targeting the ActivityPub inbox</h4>
234 fb77ab16 2024-03-15 o <p>This is the typical ActivityPub process.
235 fb77ab16 2024-03-15 o For example, someone could mention us in a Mastodon post:</p>
236 fb77ab16 2024-03-15 o <pre><code>@bowie@apas.test.example hope apas is going OK!
237 fb77ab16 2024-03-15 o </code></pre>
238 fb77ab16 2024-03-15 o <p>Which results in the Mastodon server sending Activity to bowie&#8217;s Actor inbox.
239 fb77ab16 2024-03-15 o In <strong>apas</strong>,
240 fb77ab16 2024-03-15 o <code>apserve</code> provides a typical HTTP server for a minimal ActivityPub service.
241 93390e9f 2024-03-14 o It is responsible for:</p>
242 93390e9f 2024-03-14 o <ul>
243 93390e9f 2024-03-14 o <li>receiving Activity over HTTP (ActivityPub inbox)</li>
244 93390e9f 2024-03-14 o <li>serving users&#8217; sent Activity for other servers to fetch (ActivityPub outbox)</li>
245 93390e9f 2024-03-14 o <li>serving each user&#8217;s Actor</li>
246 93390e9f 2024-03-14 o <li>resolving WebFinger lookups</li>
247 93390e9f 2024-03-14 o </ul>
248 93390e9f 2024-03-14 o <p><img src="receive.png" alt="" /></p>
249 93390e9f 2024-03-14 o <p>Delivery is not handled by <code>apserve</code>.
250 93390e9f 2024-03-14 o Instead, <code>apserve</code> converts Activities to mail messages,
251 93390e9f 2024-03-14 o and passes them on to <code>apsend</code> for delivery.</p>
252 fb77ab16 2024-03-15 o <h4 id="2.3.2-following">2.3.2 Following</h4>
253 fb77ab16 2024-03-15 o <p><a href="https://www.w3.org/TR/activitystreams-vocabulary/#dfn-follow">Follows</a> can be sent using <code>apsend</code>.
254 fb77ab16 2024-03-15 o Because Follows are not represented clearly as mail,
255 fb77ab16 2024-03-15 o the Follow needs to be written as JSON directly.
256 fb77ab16 2024-03-15 o For example, for user bowie to follow alex:</p>
257 fb77ab16 2024-03-15 o <pre><code>{
258 fb77ab16 2024-03-15 o "@context": "https:&#47;&#47;www.w3.org&#47;ns&#47;activitystreams"
259 fb77ab16 2024-03-15 o "actor": "https:&#47;&#47;apas.example.org&#47;bowie",
260 fb77ab16 2024-03-15 o "type": "Follow",
261 fb77ab16 2024-03-15 o "object": "https:&#47;&#47;apub.example.com&#47;alex"
262 fb77ab16 2024-03-15 o }
263 fb77ab16 2024-03-15 o </code></pre>
264 fb77ab16 2024-03-15 o <p>then piped to <code>apsend</code>:</p>
265 fb77ab16 2024-03-15 o <pre><code>apsend -j alex@apub.example.com &#60; follow.json
266 fb77ab16 2024-03-15 o </code></pre>
267 fb77ab16 2024-03-15 o <p>Wrapped up in X-line shell script named <code>apfollow</code>,
268 fb77ab16 2024-03-15 o following and unfollowing is equivalent to running the commands:</p>
269 fb77ab16 2024-03-15 o <pre><code>apfollow alex@apub.example.com
270 fb77ab16 2024-03-15 o apfollow -u alex@apub.example.com
271 fb77ab16 2024-03-15 o </code></pre>
272 fb77ab16 2024-03-15 o <h4 id="2.3.3-rssatom-feeds">2.3.3 RSS&#47;Atom feeds</h4>
273 fb77ab16 2024-03-15 o <p>Many ActivityPub servers also make content available via <a href="https://www.rfc-editor.org/rfc/rfc4287">web feeds</a>.
274 fb77ab16 2024-03-15 o This could be an efficient way to fetch content using a battle-tested format
275 fb77ab16 2024-03-15 o from resource-constrained servers.</p>
276 fb77ab16 2024-03-15 o <p>One possible tool is something that manages reading new entries in a feed.
277 fb77ab16 2024-03-15 o For each entry, it extracts the ActivityPub object ID from the
278 fb77ab16 2024-03-15 o <code>&#60;guid&#62;</code> or <code>&#60;link&#62;</code> tag for RSS and Atom respectively.</p>
279 fb77ab16 2024-03-15 o <pre><code>&#60;entry&#62;
280 fb77ab16 2024-03-15 o &#60;title&#62;Atom-Powered Robots Run Amok&#60;&#47;title&#62;
281 fb77ab16 2024-03-15 o &#60;link href="https:&#47;&#47;apub.example.com&#47;alex&#47;12345678"&#47;&#62;
282 fb77ab16 2024-03-15 o &#60;id&#62;urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a&#60;&#47;id&#62;
283 fb77ab16 2024-03-15 o &#60;updated&#62;2023-12-13T18:30:02Z&#60;&#47;updated&#62;
284 fb77ab16 2024-03-15 o &#60;summary&#62;hello, world!&#60;&#47;summary&#62;
285 fb77ab16 2024-03-15 o &#60;&#47;entry&#62;
286 fb77ab16 2024-03-15 o </code></pre>
287 fb77ab16 2024-03-15 o <h4 id="2.3.4-fediverse-software-http-apis">2.3.4 Fediverse software HTTP APIs</h4>
288 fb77ab16 2024-03-15 o <p>Many existing systems provide a HTTP API which provides a convenient
289 fb77ab16 2024-03-15 o way of finding content based on some application-specific logic e.g.
290 fb77ab16 2024-03-15 o a group, full-text search, or time created.</p>
291 fb77ab16 2024-03-15 o <p>An early <strong>apas</strong> prototype was really just a Python script which
292 fb77ab16 2024-03-15 o synchronised my <a href="like%20Mastodon">GoToSocial</a> timeline with a directory on disk.
293 fb77ab16 2024-03-15 o In short:</p>
294 fb77ab16 2024-03-15 o <pre><code>for status in timeline():
295 fb77ab16 2024-03-15 o note = apget(status.source_id)
296 fb77ab16 2024-03-15 o with open(status.id) as f:
297 fb77ab16 2024-03-15 o apub2email(f, note)
298 fb77ab16 2024-03-15 o </code></pre>
299 fb77ab16 2024-03-15 o <h4 id="2.3.5-takeaway">2.3.5 Takeaway</h4>
300 fb77ab16 2024-03-15 o <p>As mentioned already,
301 fb77ab16 2024-03-15 o core to <strong>apas</strong> is handling ActivityPub objects
302 fb77ab16 2024-03-15 o as text streams and
303 fb77ab16 2024-03-15 o files in a filesystem.
304 fb77ab16 2024-03-15 o It&#8217;s not meant to be the most performant system (not to say that it&#8217;s slow),
305 fb77ab16 2024-03-15 o but it lets us develop an understanding of the ActivityPub protocol
306 fb77ab16 2024-03-15 o and focus on the data over APIs via quick prototyping.</p>
307 fb77ab16 2024-03-15 o <h4 id="2.x-todo-filtering-spam">2.x TODO Filtering, spam?</h4>
308 fb77ab16 2024-03-15 o <ul>
309 fb77ab16 2024-03-15 o <li>text streams</li>
310 fb77ab16 2024-03-15 o <li>small portable programs instead of plugins to growing systems</li>
311 fb77ab16 2024-03-15 o </ul>
312 fb77ab16 2024-03-15 o <h3 id="2.4-reading">2.4 Reading</h3>
313 fb77ab16 2024-03-15 o <p>Messages are stored in the <a href="https://en.wikipedia.org/wiki/Maildir">Maildir</a> format; one message per file.
314 fb77ab16 2024-03-15 o This is not an important part of the system.
315 fb77ab16 2024-03-15 o Maildir is used only because of the easy implementation for <code>apsend</code>;
316 fb77ab16 2024-03-15 o it just neads to create create files.</p>
317 fb77ab16 2024-03-15 o <p>How messages are presented to users –
318 fb77ab16 2024-03-15 o no matter how they are stored –
319 fb77ab16 2024-03-15 o is a job for which software has been written for decades already.</p>
320 fb77ab16 2024-03-15 o <p>Here are some that are being used or</p>
321 fb77ab16 2024-03-15 o <h4 id="2.4.1-">2.4.1 <code>read()</code></h4>
322 fb77ab16 2024-03-15 o <p>No, really.</p>
323 fb77ab16 2024-03-15 o <p>During development, being able to just run cat(1) on a file to debug Content-Type encoding bug
324 fb77ab16 2024-03-15 o was a breath of fresh air when compared to what is more common in web development.</p>
325 fb77ab16 2024-03-15 o <p>That is, running a unit test which queries a relational database running in a container in a virtual machine hopefully all configured correctly, then marshalling that into the application&#8217;s unique data structure, to ActivityPub, then finally JSON-encoded (half-joking).</p>
326 fb77ab16 2024-03-15 o <h4 id="2.4.2-existing-solutions">2.4.2 Existing solutions</h4>
327 fb77ab16 2024-03-15 o <p><strong>Maildir</strong>. Some clients can interact with Maildir directly, like <a href="http://www.mutt.org">mutt</a>.</p>
328 fb77ab16 2024-03-15 o <p><strong>IMAP</strong>. The obvious and most popular method for accessing mailboxes over the network. Dovecot works well. IMAP is very widely supported by mail clients.</p>
329 fb77ab16 2024-03-15 o <p><strong>NNTP&#47;Usenet</strong>.
330 fb77ab16 2024-03-15 o Throughout this document I&#8217;ve referred to &#8220;mail messages&#8221;.
331 fb77ab16 2024-03-15 o But the so-called &#8220;Internet Message Format&#8221; described in RFC 5322 is also used by
332 fb77ab16 2024-03-15 o <a href="https://en.wikipedia.org/wiki/Usenet">Usenet</a> via a protocol known as <a href="https://datatracker.ietf.org/doc/html/rfc3977">NNTP</a>.
333 fb77ab16 2024-03-15 o The protocol is a simple line-based text protocol
334 fb77ab16 2024-03-15 o with many open-source libraries available.
335 fb77ab16 2024-03-15 o Serving Fediverse messages from a filesystem over NNTP would be a fun project.
336 fb77ab16 2024-03-15 o Similar to how the Linux Kernel Mailing list is available over NNTP at <code>nntp.lore.kernel.org</code>.</p>
337 fb77ab16 2024-03-15 o <p><strong>Mailing list archive web interfaces</strong>.
338 fb77ab16 2024-03-15 o Finally yet another opportunity to give those old Perl scripts another lease of life.</p>
339 fb77ab16 2024-03-15 o <p><strong>upasfs(4)</strong>.
340 fb77ab16 2024-03-15 o <a href="http://doc.cat-v.org/bell_labs/upas_mail_system/">upas</a> is the system I studied to implement <strong>apas</strong>.
341 fb77ab16 2024-03-15 o Messages could be relayed from <code>apsend</code> to <code>upas&#47;send</code>,
342 fb77ab16 2024-03-15 o or the Maildir could be converted to mdir(6).
343 fb77ab16 2024-03-15 o Then we would have a <em>real</em> filesystem interface over 9P.
344 fb77ab16 2024-03-15 o Another project for another time.</p>
345 93390e9f 2024-03-14 o <h2 id="3.-workarounds-limitations">3. Workarounds &#38; limitations</h2>
346 93390e9f 2024-03-14 o <p>The mapping between Activity objects, mail messages,
347 93390e9f 2024-03-14 o ActivityPub HTTP methods, and SMTP transactions
348 93390e9f 2024-03-14 o has a number of limitations.
349 93390e9f 2024-03-14 o <strong>Apas</strong> uses some workarounds internally to fill some gaps.</p>
350 93390e9f 2024-03-14 o <p>The <a href="https://www.w3.org/TR/activitystreams-vocabulary/#microsyntaxes">Mention</a> Activity,
351 93390e9f 2024-03-14 o used by Mastodon for notifications,
352 93390e9f 2024-03-14 o is implemented by reading the To field of submitted messages.
353 93390e9f 2024-03-14 o Recipients in <code>To</code> are added as Mentions.
354 93390e9f 2024-03-14 o For example, the message:</p>
355 93390e9f 2024-03-14 o <pre><code>To: "Oliver Lowe" &#60;otl@hachyderm.io&#62;
356 93390e9f 2024-03-14 o
357 93390e9f 2024-03-14 o Hello!
358 93390e9f 2024-03-14 o </code></pre>
359 93390e9f 2024-03-14 o <p>results in an entry in <code>tags</code> in an ActivityPub Note:</p>
360 93390e9f 2024-03-14 o <pre><code>{
361 93390e9f 2024-03-14 o "type": "Note"
362 93390e9f 2024-03-14 o ...
363 93390e9f 2024-03-14 o "tags": {[
364 93390e9f 2024-03-14 o "type": "Mention",
365 93390e9f 2024-03-14 o "href": "https:&#47;&#47;hachyderm.io&#47;users&#47;otl",
366 93390e9f 2024-03-14 o "name": "@otl@hachyderm.io"
367 93390e9f 2024-03-14 o ]}
368 93390e9f 2024-03-14 o }
369 93390e9f 2024-03-14 o </code></pre>
370 93390e9f 2024-03-14 o <p>There is not an easy way to address an Actor&#8217;s followers using the <code>acct:</code> mail address syntax.
371 93390e9f 2024-03-14 o <code>apas</code> understands a non-standard syntax using &#8220;plus addressing&#8221;.
372 93390e9f 2024-03-14 o For example to address the followers of <a href="mailto:user@example.com">user@example.com</a>
373 93390e9f 2024-03-14 o the address <a href="mailto:user+followers@example.com">user+followers@example.com</a> may be used.
374 93390e9f 2024-03-14 o These followers addresses cannot be resolved by WebFinger.</p>
375 93390e9f 2024-03-14 o <p>Likes and Dislikes are silently dropped by <code>apserve</code>.
376 93390e9f 2024-03-14 o The reader can decide whether this is a workaround, feature, or bug.</p>
377 fb77ab16 2024-03-15 o <p>Accept and Rejects from Follow requests can be received via ActivityPub
378 fb77ab16 2024-03-15 o and delivered as mail but for notifications only.
379 fb77ab16 2024-03-15 o The reverse does not work;
380 fb77ab16 2024-03-15 o <strong>apas</strong> cannot read a Follow request from a mail message.</p>
381 93390e9f 2024-03-14 o <p>To simplifly delivery to local mailboxes,
382 93390e9f 2024-03-14 o Actors served by <code>apserve</code> have no shared inbox&#47;outbox.
383 93390e9f 2024-03-14 o Fortunately shared inbox endpoints are inteded as a performance opimitisation for
384 93390e9f 2024-03-14 o servers hosting many Actors, which is beyond the scope of <strong>apas</strong>.</p>
385 93390e9f 2024-03-14 o </article>
386 93390e9f 2024-03-14 o </body>
387 93390e9f 2024-03-14 o </html>