<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/rss-style.xsl" type="text/xsl"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	     xmlns:dc="http://purl.org/dc/elements/1.1/"
	   xmlns:atom="http://www.w3.org/2005/Atom"
	     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	  xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>ActivityPub &#8211; Terence Eden’s Blog</title>
	<atom:link href="https://shkspr.mobi/blog/tag/activitypub/feed/" rel="self" type="application/rss+xml" />
	<link>https://shkspr.mobi/blog</link>
	<description>Regular nonsense about tech and its effects 🙃</description>
	<lastBuildDate>Sat, 10 Oct 2026 12:01:12 +0000</lastBuildDate>
	<language>en-GB</language>
	<copyright>© Terence Eden. 🄯 CC BY-SA. See https://shkspr.mobi/blog/copyright-and-copyleft/</copyright>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://shkspr.mobi/blog/wp-content/uploads/2023/07/cropped-avatar-32x32.jpeg</url>
	<title>ActivityPub &#8211; Terence Eden’s Blog</title>
	<link>https://shkspr.mobi/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title><![CDATA[I paid people to try and follow my README]]></title>
		<link>https://shkspr.mobi/blog/2026/10/i-paid-people-to-try-and-follow-my-readme/</link>
					<comments>https://shkspr.mobi/blog/2026/10/i-paid-people-to-try-and-follow-my-readme/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Sun, 11 Oct 2026 11:34:39 +0000</pubDate>
		<category><![CDATA[ActivityBot]]></category><category><![CDATA[ActivityPub]]></category><category><![CDATA[developers]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=76333</guid>

					<description><![CDATA[Developers suck at writing documentation. We like to say RTFM but often there ain&#039;t no FM to R. At best we have a half-arsed collection of notes, some obsolete tips, and a link to a desolate forum full of people asking the same questions again and again. That&#039;s no way to treat our users.  I naïvely believe there&#039;s a better way. As I&#039;ve written before, you should sit down and actually test your …]]></description>
										<content:encoded>&lt;p&gt;Developers suck at writing documentation. We like to say RTFM but often there ain't no FM to R. At best we have a half-arsed collection of notes, some obsolete tips, and a link to a desolate forum full of people asking the same questions again and again. That's no way to treat our users.&lt;/p&gt;

&lt;p&gt;I naïvely believe there's a better way. As I've written before, you should sit down and &lt;a href="https://shkspr.mobi/blog/2025/10/how-to-actually-test-your-readme/"&gt;&lt;em&gt;actually&lt;/em&gt; test your readme&lt;/a&gt;. Spin up a fresh Virtual Machine, go through what you've written, and see if it makes sense.&lt;/p&gt;

&lt;p&gt;But it is &lt;em&gt;really&lt;/em&gt; hard to ignore your own biases. Of course you know that certain commands require &lt;code&gt;sudo&lt;/code&gt; and obviously when you wrote &lt;code&gt;-foo&lt;/code&gt; you meant &lt;code&gt;--foo&lt;/code&gt; and everyone knows that you have to reboot afterwards.&lt;/p&gt;

&lt;p&gt;How do you get rid of those biases? I paid people!&lt;/p&gt;

&lt;p&gt;As part of my &lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/"&gt;NLnet grant application for ActivityBot&lt;/a&gt;, I said I wanted to test the install experience with real users and I was prepared to pay them €25 for an hour of their time. I stuck out the call on Mastodon, gathered a few people, and had a video call with them.&lt;/p&gt;

&lt;p&gt;The format was simple. I explained that I was looking for feedback on the first-run experience. I knew that it wasn't perfect and actively wanted constructive criticism. I asked the volunteer to share their screen and, crucially, to speak aloud. Tell me what they were doing. What they didn't understand, what confused them, what delighted them, what frustrated them, etc.&lt;/p&gt;

&lt;p&gt;I took notes by hand (fuck feeding the machine) and spent several hours being told what incorrect assumptions I'd made.&lt;/p&gt;

&lt;p&gt;Amongst the highlights I discovered were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The link to the demo tool was wrong.&lt;/li&gt;
&lt;li&gt;Some people read a README in the terminal.&lt;/li&gt;
&lt;li&gt;What does it actually mean to rename a file?&lt;/li&gt;
&lt;li&gt;How do you rename a hidden file?&lt;/li&gt;
&lt;li&gt;Should a demo tool be available on the web or just the user's local machine?&lt;/li&gt;
&lt;li&gt;Why does some text explicitly need to be quoted and some not?&lt;/li&gt;
&lt;li&gt;My jokes aren't funny and are actively confusing.&lt;/li&gt;
&lt;li&gt;Some of the technical terminology needed explaining.&lt;/li&gt;
&lt;li&gt;The ordering of the different sections was confusing.&lt;/li&gt;
&lt;li&gt;I hadn't actually explained what the software would do.&lt;/li&gt;
&lt;li&gt;A whole section which was technically interesting to me was utterly confusing to everyone else.&lt;/li&gt;
&lt;li&gt;Not all web servers use permissions in the same way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And on it went!&lt;/p&gt;

&lt;p&gt;After each session I updated the README based on what people found difficult, then I re-tested it with the next person.&lt;/p&gt;

&lt;p&gt;In total, I paid out around €150 to have a bunch of people criticise me to my face. Hey, cheaper than therapy, right?&lt;/p&gt;

&lt;p&gt;I know someone is going to say "why not just ask an LLM to simulate a range of users?" The answer is very simple - I want to speak to real people. People are brilliant! They can make you laugh, you can see their cat when it wanders on to the call, they bring a unique perspective to the problem, and they're really happy when you give them a €25 voucher. Some will gladly do it for free and make &lt;em&gt;you&lt;/em&gt; happy!&lt;/p&gt;

&lt;!--👋👋👋👋👋👋👋 Welcome to Comment Club! Shhhh! Only cool people can read this bit of the post.

I did have a serious think about using an LLM for this. Ethics aside (and you can never really put ethics aside) I just didn't feel like I could trust their judgement. I get the argument that it is not much different from using a spellcheck - but I fundamentally don't want to feed the beast.

Anyway, the three rules of Comment Club are…

1. You must not tell anyone about Comment Club - let them find out about it themselves.
2. You *must* add some Comment Club Content to at least one of your blog posts. Doesn't have to be much, just a little note will do.
3. You should drop an email to anyone whose comments you've read. Start by sending me a friendly message at comment.club@shkspr.mobi

Keep your eyes peeled for more comments in future blog posts 😃

Be seeing you 👌👁
--&gt;

&lt;p&gt;When I was doing technical writing for GOV.UK, all my beautiful prose was given a second-eye by another human. They eviscerated all my flowery phrases and turned the document into something more readable. They were the ones who caught the mistakes that no spell chequer could. They were able to have a proper conversation with me. More importantly, I could &lt;em&gt;hear&lt;/em&gt; the frustration in their voice - that's the thing which lets you know a mistake needs to be corrected.&lt;/p&gt;

&lt;p&gt;I don't claim that &lt;a href="https://gitlab.com/edent/activity-bot/-/blob/main/README.md?ref_type=heads"&gt;ActivityBot's README&lt;/a&gt; is now perfect - far from it - but it is now demonstrably easier to follow. Developers need to talk to &lt;em&gt;real&lt;/em&gt; people. You don't have to pay them if you can't afford it - but find a few people who will talk aloud while they try to follow your instructions. I guarantee you that your README will become much better for it.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=76333&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/10/i-paid-people-to-try-and-follow-my-readme/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Some quick thoughts on Unit Testing ActivityPub]]></title>
		<link>https://shkspr.mobi/blog/2026/10/some-thoughts-on-unit-testing-activitypub/</link>
					<comments>https://shkspr.mobi/blog/2026/10/some-thoughts-on-unit-testing-activitypub/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Sat, 10 Oct 2026 11:34:15 +0000</pubDate>
		<category><![CDATA[ActivityBot]]></category><category><![CDATA[ActivityPub]]></category><category><![CDATA[PHP]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=75774</guid>

					<description><![CDATA[I&#039;ll be radically honest here - I never really got the idea of &#34;Test Driven Development&#34;. I&#039;m much more of a &#34;telnet into production and damn the consequences&#34; kind of guy. Look, it&#039;s much more fun and my cardiologist recommends severe shocks every now and again.  The essence of unit testing is pretty simple:   Feed a function some data See how it responds   Send it good data and if it returns…]]></description>
										<content:encoded>&lt;p&gt;I'll be radically honest here - I never really got the idea of "Test Driven Development". I'm much more of a "telnet into production and damn the consequences" kind of guy. Look, it's much more fun and my cardiologist recommends severe shocks every now and again.&lt;/p&gt;

&lt;p&gt;The essence of unit testing is pretty simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Feed a function some data&lt;/li&gt;
&lt;li&gt;See how it responds&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Send it good data and if it returns "true" the test passes. Send it bad data and make sure it returns false. Easy peasy lemon squeezy.&lt;/p&gt;

&lt;p&gt;As part of my &lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/"&gt;NLnet funded work on ActivityBot&lt;/a&gt;, I'm writing some proper tests for my bot framework. I am hopeful that some of them will be useful to other projects doing similar things.&lt;/p&gt;

&lt;p&gt;There are four major classes of tests - here are the problems I've found while writing them.&lt;/p&gt;

&lt;h2 id="basic-text-validation"&gt;&lt;a href="https://shkspr.mobi/blog/2026/10/some-thoughts-on-unit-testing-activitypub/#basic-text-validation"&gt;Basic text validation&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;A basic test might be how to validate that an ActivityPub username is valid. Typically it would be something like &lt;code&gt;@edent@mastodon.social&lt;/code&gt; - what assumptions do we make with that? It starts with an &lt;code&gt;@&lt;/code&gt; and has another &lt;code&gt;@&lt;/code&gt; somewhere in it, dividing into two parts, the user and the server.  The server has to be a valid domain name - but that can include non-ASCII Internationalised Domain Names and Emoji domains.&lt;/p&gt;

&lt;p&gt;What about the user part? Is it just A-Z and 0-9? Can it have dots? What about apostrophes like an email address?&lt;/p&gt;

&lt;p&gt;Basically, how easy is it find the specifications for all the various component parts of ActivityPub? Not very!&lt;/p&gt;

&lt;h2 id="message-validation"&gt;&lt;a href="https://shkspr.mobi/blog/2026/10/some-thoughts-on-unit-testing-activitypub/#message-validation"&gt;Message validation&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;What does a &lt;a href="https://www.rfc-editor.org/info/rfc7033/"&gt;WebFinger response&lt;/a&gt; look like? Which parts are mandatory and what values can they contain?&lt;/p&gt;

&lt;p&gt;With any message that your project generates, how can you be sure that other ActivityPub servers will understand it?&lt;/p&gt;

&lt;p&gt;Similarly, when we receive a follow message from an external server, what should it look like?&lt;/p&gt;

&lt;p&gt;There are some &lt;a href="https://github.com/steve-bate/fediverse-jsonschema"&gt;JSON Schemas&lt;/a&gt; which can be used to validate some type of messages.&lt;/p&gt;

&lt;p&gt;But, again, there are &lt;em&gt;many&lt;/em&gt; scattered specifications.&lt;/p&gt;

&lt;h2 id="signature-verification"&gt;&lt;a href="https://shkspr.mobi/blog/2026/10/some-thoughts-on-unit-testing-activitypub/#signature-verification"&gt;Signature verification&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;As I've written about before, &lt;a href="https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/"&gt;HTTP Signatures are difficult&lt;/a&gt;. There are two main problems. The first is verifying signatures.&lt;/p&gt;

&lt;p&gt;In order to do that, you need to gather a bunch of signatures and then find a way to replay them into the test. So I'm in the process of saving signatures which I can then share with others.&lt;/p&gt;

&lt;p&gt;The second problem is &lt;em&gt;generating&lt;/em&gt; signatures.  Sure, you can run tests on the signatures - but there's only one &lt;em&gt;real&lt;/em&gt; way to test whether they're acceptable…&lt;/p&gt;

&lt;h2 id="communicating-with-others"&gt;&lt;a href="https://shkspr.mobi/blog/2026/10/some-thoughts-on-unit-testing-activitypub/#communicating-with-others"&gt;Communicating with others&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Passing tests means nothing if you can't communicate with others and they can't communicate with you.&lt;/p&gt;

&lt;p&gt;Some tests are easier than others. Sending a signed request should be easy and repeatable. But receiving messages isn't easily automated. It requires being able to control an external server and asking that to send messages.&lt;/p&gt;

&lt;p&gt;With the &lt;a href="https://docs.joinmastodon.org/client/intro/"&gt;Mastodon API&lt;/a&gt; it is possible to make requests which will interact with your server - but only if it is a &lt;em&gt;public&lt;/em&gt; server.&lt;/p&gt;

&lt;h2 id="putting-it-all-together"&gt;&lt;a href="https://shkspr.mobi/blog/2026/10/some-thoughts-on-unit-testing-activitypub/#putting-it-all-together"&gt;Putting it all together&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;I'm putting &lt;a href="https://gitlab.com/edent/activity-bot/-/tree/main/tests?ref_type=heads"&gt;all my tests online&lt;/a&gt;. I'm also sharing a &lt;a href="https://gitlab.com/edent/activity-bot/-/tree/main/tests/headers?ref_type=heads"&gt;collection of messages and signatures&lt;/a&gt; which you can use in your tests.&lt;/p&gt;

&lt;p&gt;I'd love to know if you find them useful.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=75774&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/10/some-thoughts-on-unit-testing-activitypub/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[ActivityPub - How to send an updated user profile to Mastodon and the Fediverse]]></title>
		<link>https://shkspr.mobi/blog/2026/09/activitypub-how-to-send-an-updated-user-profile-to-mastodon-and-the-fediverse/</link>
					<comments>https://shkspr.mobi/blog/2026/09/activitypub-how-to-send-an-updated-user-profile-to-mastodon-and-the-fediverse/#respond</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Sat, 12 Sep 2026 11:34:02 +0000</pubDate>
		<category><![CDATA[ActivityBot]]></category><category><![CDATA[ActivityPub]]></category><category><![CDATA[fediverse]]></category><category><![CDATA[mastodon]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=74470</guid>

					<description><![CDATA[Let&#039;s suppose you&#039;ve updated the description of your ActivityPub account from &#34;World&#039;s Number 1 Taylor Swift Fan&#34; to &#34;This account is now a Nickleback Truther&#34;. How do you let the rest of the Fediverse know that you&#039;ve changed your allegiance?  By default, most Mastodon instances won&#039;t periodically poll your account information just to see if you&#039;ve updated it. So how does the information get…]]></description>
										<content:encoded>&lt;p&gt;Let's suppose you've updated the description of your ActivityPub account from "World's Number 1 Taylor Swift Fan" to "This account is now a Nickleback Truther". How do you let the rest of the Fediverse know that you've changed your allegiance?&lt;/p&gt;

&lt;p&gt;By default, most Mastodon instances won't periodically poll your account information just to see if you've updated it. So how does the information get from your server to your followers' servers?&lt;/p&gt;

&lt;p&gt;This wasn't immediately obvious to me, but I got a clue from reading &lt;a href="https://shkspr.mobi/blog/2026/09/book-review-activitypub-by-evan-prodromou/"&gt;Evan Prodromou's book on ActivityPub&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The Update activity type is for updating the properties of an object represented by the object property.&lt;/p&gt;

&lt;p&gt;The most common types of objects that can be updated are content objects, like Note or Image. Actor types (like Person) and Question activity types can also be updated.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Aha!&lt;/p&gt;

&lt;p&gt;You need to craft an &lt;code&gt;Update&lt;/code&gt; message which has as its object the &lt;em&gt;new&lt;/em&gt; user information. That needs to be sent to the inbox of all your followers.&lt;/p&gt;

&lt;p&gt;Something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-json"&gt;{
    "@context": "https://www.w3.org/ns/activitystreams",
    "actor": "https://example.com/user",
    "id": "6a9162a6-a8e5-ca0f-9c08-8e6b814acef8",
    "published": "2026-08-31T12:34:56+01:00",
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "type": "Update",
    "object": {
        "@context": [
            "https://www.w3.org/ns/activitystreams",
            "https://w3id.org/security/v1"
        ],
        "id": "https://example.com/user",
        "name": "My new name",
        "summary": "A brand new description!",
        …
    },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Obviously the &lt;em&gt;full&lt;/em&gt; user information is a bit more than that - it will include inbox details, public keys, avatars, etc. The &lt;code&gt;published&lt;/code&gt; property in the Update activity should be when you changed your details - not when the account was created.&lt;/p&gt;

&lt;p&gt;Once that was sent, Mastodon immediately reflected the changes.&lt;/p&gt;

&lt;h2 id="thanks-to-nlnet"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-how-to-send-an-updated-user-profile-to-mastodon-and-the-fediverse/#thanks-to-nlnet"&gt;Thanks to NLnet&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;This blog post was funded in part by the work I'm doing for my NLnet NGI0 grant to develop &lt;a href="https://gitlab.com/edent/activity-bot"&gt;ActivityBot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nlnet.nl/project/ActivityBot/"&gt;&lt;img src="https://shkspr.mobi/blog/wp-content/uploads/2026/08/NGI-logos.webp" alt="NLnet logo." width="900" height="200" class="aligncenter"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=74470&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/09/activitypub-how-to-send-an-updated-user-profile-to-mastodon-and-the-fediverse/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[ActivityPub - Is it worth defending against replay attacks and message/signature time skew?]]></title>
		<link>https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/</link>
					<comments>https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Tue, 08 Sep 2026 11:34:51 +0000</pubDate>
		<category><![CDATA[ActivityBot]]></category><category><![CDATA[ActivityPub]]></category><category><![CDATA[HTTP]]></category><category><![CDATA[security]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=74622</guid>

					<description><![CDATA[Here&#039;s a problem that I&#039;ve found with ActivityBot - my little ActivityPub server. Sometimes it receives messages which were originally sent months ago. Why does that happen and is it risky to accept and process them?  My tl;dr is that it probably isn&#039;t worth worrying about. But I&#039;d love someone to tell me why I&#039;m wrong.  Here&#039;s my thinking:  Table of ContentsCausesIs that a problem?What are we…]]></description>
										<content:encoded>&lt;p&gt;Here's a problem that I've found with &lt;a href="https://gitlab.com/edent/activity-bot/"&gt;ActivityBot&lt;/a&gt; - my little ActivityPub server. Sometimes it receives messages which were originally sent &lt;em&gt;months&lt;/em&gt; ago. Why does that happen and is it risky to accept and process them?&lt;/p&gt;

&lt;p&gt;My tl;dr is that it &lt;em&gt;probably&lt;/em&gt; isn't worth worrying about. But I'd love someone to tell me why I'm wrong.&lt;/p&gt;

&lt;p&gt;Here's my thinking:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;nav role="doc-toc"&gt;&lt;menu&gt;&lt;li&gt;&lt;h2 id="table-of-contents"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#table-of-contents"&gt;Table of Contents&lt;/a&gt;&lt;/h2&gt;&lt;menu&gt;&lt;li&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#causes"&gt;Causes&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#is-that-a-problem"&gt;Is that a problem?&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#what-are-we-trying-to-protect-against"&gt;What are we trying to protect against?&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#putting-it-all-together"&gt;Putting it all together&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#no-youre-wrong-and-i-can-prove-it"&gt;No! You're wrong and I can prove it!&lt;/a&gt;&lt;/li&gt;&lt;/menu&gt;&lt;/li&gt;&lt;/menu&gt;&lt;/nav&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2 id="causes"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#causes"&gt;Causes&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;All ActivityPub messages should have a "published" timestamp in their body. Some will have an "updated" timestamp. That tells you, unsurprisingly, when the message is alleged to have been originally published or updated. That time might be very different to the time you receive the message.&lt;/p&gt;

&lt;p&gt;There are, I think, three different reasons why a server might receive a message which has an out-of-date timestamp.&lt;/p&gt;

&lt;p&gt;The first is that sometimes servers are just slow. Processing thousands of messages at the same time means that some of those messages take a while to send.  &lt;a href="https://shkspr.mobi/blog/2023/09/how-far-did-my-post-go-on-the-fediverse/"&gt;ActivityPub is one big chain-mail&lt;/a&gt; so it can take several minutes for a message to be sent to all your followers.&lt;/p&gt;

&lt;p&gt;Similarly, your server might be slow. If it doesn't acknowledge receipt of a message, the original server will try sending it again. Sometimes that can take a while.&lt;/p&gt;

&lt;p&gt;Finally, some servers take a relaxed view of standards. They send an update to an old message but keep the original publication date. Ideally, they'd use an "updated" timestamp but quite often they don't.&lt;/p&gt;

&lt;p&gt;For the purposes of checking the legitimacy of the message, &lt;strong&gt;you do not need to check when a message says it was published or updated&lt;/strong&gt;. You might want to check it isn't an &lt;em&gt;obviously&lt;/em&gt; bogus date like far in the future or impossibly far in the past - but that's up to you.&lt;/p&gt;

&lt;p&gt;It is normal that your server receives messages which appear to have been published at a totally different time from now.&lt;/p&gt;

&lt;h2 id="is-that-a-problem"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#is-that-a-problem"&gt;Is that a problem?&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Probably&lt;/em&gt; not.&lt;/p&gt;

&lt;p&gt;As described above, there are various reasons why a message may be delayed in transit - or may appear to come from the distant past.&lt;/p&gt;

&lt;p&gt;What we &lt;em&gt;can&lt;/em&gt; check is when the message was cryptographically signed by the sending server. This is independent of its published or updated timestamp.&lt;/p&gt;

&lt;p&gt;HTTP requests to your server will have a &lt;code&gt;date&lt;/code&gt; header which looks like &lt;code&gt;Tue, 01 Sep 2026 15:54:21 GMT&lt;/code&gt; - this is in the slightly peculiar and Anglocentric &lt;a href="https://www.rfc-editor.org/info/rfc5322/#section-3.3"&gt;RFC 5322 format&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;New style RFC 9421 headers will also have a &lt;code&gt;signature-input&lt;/code&gt; header which will contain something like &lt;code&gt;created=1788278061&lt;/code&gt;. That uses the slightly obscure &lt;a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_16"&gt;UNIX / POSIX time&lt;/a&gt; which counts seconds since the "Epoch" of 1st January 1970.&lt;/p&gt;

&lt;p&gt;If you &lt;a href="https://www.epochconverter.com/"&gt;convert the UNIX time&lt;/a&gt; to something more modern, you should get an &lt;em&gt;identical&lt;/em&gt; value to the &lt;code&gt;date&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;But that isn't always the case. For example, &lt;a href="https://www.rfc-editor.org/rfc/rfc9421.html#:~:text=Tue%2C%2020%20Apr%202021%2002%3A07%3A55%20GMT,-Content%2DType"&gt;the RFC 9421 standard gives this example&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-_"&gt;Date: Tue, 20 Apr 2021 02:07:55 GMT
"@signature-params": ("@method" "@authority" "@path" \
  "content-digest" "content-length" "content-type")\
  ;created=1618884473;keyid="test-key-rsa-pss"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Converting &lt;code&gt;1618884473&lt;/code&gt; to normal time gives Tue, 20 Apr 2021 02:07:&lt;strong&gt;53&lt;/strong&gt; - a two second difference.&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;date&lt;/code&gt; and &lt;code&gt;created&lt;/code&gt; values differ significantly - that may indicate that the message is untrustworthy. Or that there was a delay between the signing and the sending.&lt;/p&gt;

&lt;p&gt;The spec says:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The Date header field value represents the timestamp of the HTTP message. However, the creation time of the signature itself is encoded in the created signature parameter. These two values can be different, depending on how the signature and the HTTP message are created and serialized. Applications processing signatures for valid time windows should use the created signature parameter for such calculations. An application could also put limits on how much skew there is between the Date field and the created signature parameter, in order to limit the application of a generated signature to different HTTP messages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9421.html#section-7.2.4"&gt;7.2.4. Choosing Signature Parameters and Derived Components over HTTP Fields&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;But, of course, it doesn't tell you how much skew is problematic. It's up to you how much skew you're prepared to accept.&lt;/p&gt;

&lt;p&gt;So that's the difference between the sent time and the signed time. The next time to check is your own. As we've discussed, sometimes servers are slow sending things out. Would you accept a request that was signed five minutes ago? Five days ago? Five months ago? What amount of difference is dangerous?&lt;/p&gt;

&lt;p&gt;Here's what various services and sages have to say:&lt;/p&gt;

&lt;h3 id="mastodon"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#mastodon"&gt;Mastodon&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;&lt;p&gt;The request contains a Date header. Compare it with current date and time within a reasonable time window to prevent replay attacks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/"&gt;How to make friends and verify requests&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;What is "reasonable"? The &lt;a href="https://github.com/mastodon/mastodon/blob/89bc0eb42609463d4b11e1604dacc37332a0f5ab/app/lib/signed_request.rb#L5"&gt;source code&lt;/a&gt; suggests one hour.&lt;/p&gt;

&lt;h3 id="grishka"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#grishka"&gt;Grishka&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;&lt;p&gt;Time in the Date header must differ from the recipient server’s clock by no more than 30 seconds&lt;/p&gt;

&lt;p&gt;&lt;a href="https://grishka.me/blog/activitypub-from-scratch/"&gt;A bare-minimum ActivityPub server from scratch&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;h3 id="evan-prodromou"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#evan-prodromou"&gt;Evan Prodromou&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;static #maxDateDiff = 5 * 60 * 1000 // 5 minutes&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/evanp/activitypub-bot/blob/main/lib%2Fhttpsignatureauthenticator.js#L8"&gt;activitypub-bot&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;h3 id="swicg"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#swicg"&gt;SWICG&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;&lt;p&gt;The standards don't give a concrete time window to use for this comparison. In practice, an hour plus a few minutes buffer in either direction may be a good value, to account for both clock skew and differences in time zone/daylight savings time configuration across systems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://swicg.github.io/activitypub-http-signature/#how-to-verify-a-signature"&gt;How To Verify a Signature&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;h3 id="others"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#others"&gt;Others&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Without naming names, it looks like a bunch of popular servers don't check whether there's a significant difference between the date the request was signed and the date it was received.&lt;/p&gt;

&lt;h3 id="summary"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#summary"&gt;Summary&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Various documents and implementations recommend anything between 30 seconds to "a bit more than 60 minutes". Or they just ignore any date difference.&lt;/p&gt;

&lt;p&gt;What's the right answer? What happens if the signed date is significantly different from the current date?&lt;/p&gt;

&lt;h2 id="what-are-we-trying-to-protect-against"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#what-are-we-trying-to-protect-against"&gt;What are we trying to protect against?&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Replay Attacks. Suppose someone is listening to the communications between the sending server and your server. They copy the message that is sent to you. Later they send it again!&lt;/p&gt;

&lt;p&gt;At this point, you might be thinking "so what?" and… I'm inclined to agree with you!&lt;/p&gt;

&lt;p&gt;What's the worst that could happen if you received the same message multiple times? Two things that I can think of.&lt;/p&gt;

&lt;p&gt;Firstly, it might &lt;em&gt;not&lt;/em&gt; be the same message. It is possible to send a new message but with old headers. An attacker could make someone post "I hate Taylor Swift" against their will and watch as legions of fans disembowel the victim.&lt;/p&gt;

&lt;p&gt;Except, I don't think this is likely. The signature in the header contains a hash of the message being sent. If you are properly validating the signature, a changed message will have a different hash from the one in the original message. You don't need to check timestamps, you just need to check if the hashes match.&lt;/p&gt;

&lt;p&gt;Secondly, &lt;a href="https://www.freecodecamp.org/news/idempotence-explained"&gt;idempotence&lt;/a&gt;. That's a fancy word for "pressing the button multiple times should only result in one action".&lt;/p&gt;

&lt;p&gt;What happens if a user appears to send you multiple "like" messages for a single post? You only record one like.&lt;/p&gt;

&lt;p&gt;What if they send multiple messages with the same content? Well, each will have a unique ID in the message - so you only post it once.&lt;/p&gt;

&lt;p&gt;What if they send multiple &lt;em&gt;anythings&lt;/em&gt;? I can't think of any ActivityPub action which would not be idempotent.&lt;/p&gt;

&lt;p&gt;About the worst thing I can think of is this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alice sends a message to you saying "I want to follow Bob".&lt;/li&gt;
&lt;li&gt;Mallory intercepts this message.&lt;/li&gt;
&lt;li&gt;You record Alice is now following Bob.&lt;/li&gt;
&lt;li&gt;Alice sends a message to you saying "I want to &lt;em&gt;unfollow&lt;/em&gt; Bob".&lt;/li&gt;
&lt;li&gt;You record the severed relationship.&lt;/li&gt;
&lt;li&gt;Mallory replays the original follow message.&lt;/li&gt;
&lt;li&gt;You record Alice is now following Bob.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's also possible the following could happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alice posts a message saying "I love The Beatles".&lt;/li&gt;
&lt;li&gt;You record Alice's message and display it on the timeline.&lt;/li&gt;
&lt;li&gt;Alice updates her post to say "I love the Rolling Stones".&lt;/li&gt;
&lt;li&gt;Mallory intercepts this message.&lt;/li&gt;
&lt;li&gt;You record Alice's updated message and display the new version on the timeline.&lt;/li&gt;
&lt;li&gt;Alice updates her post yet again to say "I love the Spice Girls".&lt;/li&gt;
&lt;li&gt;You record Alice's updated message and display the new version on the timeline.&lt;/li&gt;
&lt;li&gt;Mallory replays the original update message.&lt;/li&gt;
&lt;li&gt;You now display that Alice loves the Stones rather than Spice Girls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perhaps the same can happen with like/unlike, block/unblock, boost/unboost.&lt;/p&gt;

&lt;p&gt;But none of that is significantly prevented by checking the date.&lt;/p&gt;

&lt;p&gt;Ultimately, it is up to your sever to check the unique ID of each message and refuse to action any repeated messages. You may not want to trust the unique ID which is sent with the message. If that's the case, you can calculate your own - perhaps using a hash of the contents, the signature, or some other process which will generate an ID based on the message.&lt;/p&gt;

&lt;h2 id="putting-it-all-together"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#putting-it-all-together"&gt;Putting it all together&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Here's what you need to do to prevent replay attacks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Independently calculate the hash of the message received.&lt;/li&gt;
&lt;li&gt;Validate that your calculated hash matches the hash sent in the message's HTTP headers.

&lt;ul&gt;
&lt;li&gt;If not, this is a potential replay attack and the message must be ignored.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Verify that the signature received in the message's HTTP headers includes the message hash and is cryptographically valid.

&lt;ul&gt;
&lt;li&gt;If not, the signature is invalid  and the message must be ignored.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Has the received message's unique ID already been processed?

&lt;ul&gt;
&lt;li&gt;If so, refuse to process it again.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I don't see what checking the timestamp of the HTTP signature has to do with anything. Someone who has access to the original messages and their headers could send them milliseconds after the original delivery.&lt;/p&gt;

&lt;p&gt;I think it is probably &lt;em&gt;pragmatic&lt;/em&gt; to give messages 60ish minutes grace before dropping them. Delays happen, but anything more significant than an hour &lt;em&gt;might&lt;/em&gt; indicate a attack. But, equally, might just mean that the Internet is having a slow day.&lt;/p&gt;

&lt;p&gt;If you are correctly checking signatures and hashes, I don't think you need to worry about skew between signature date and delivery date.&lt;/p&gt;

&lt;h2 id="no-youre-wrong-and-i-can-prove-it"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/#no-youre-wrong-and-i-can-prove-it"&gt;No! You're wrong and I can prove it!&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Please tell me where I have erred! Stick a comment in the box or drop me an email. If I've made a massive or subtle mistake, I'd love to know what.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=74622&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/09/activitypub-is-it-worth-defending-against-replay-attacks-and-message-signature-time-skew/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[A reasonably practical guide to validating RFC 9421 HTTP Signatures for ActivityPub in PHP]]></title>
		<link>https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/</link>
					<comments>https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Thu, 03 Sep 2026 11:34:12 +0000</pubDate>
		<category><![CDATA[ActivityBot]]></category><category><![CDATA[ActivityPub]]></category><category><![CDATA[mastodon]]></category><category><![CDATA[PHP]]></category><category><![CDATA[WebDev]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=74429</guid>

					<description><![CDATA[If you&#039;re reading this, you&#039;ve probably been hitting your head against a brick wall trying to parse and decipher the new HTTP Signatures sent by Mastodon and other Fediverse servers.  This is a basic and somewhat incomplete guide to accepting these signatures. I&#039;m sure there are various gotchas, but it works with the signatures I&#039;ve seen in the wild.  Shut Up And Show Me The Code!  OK, wow, no…]]></description>
										<content:encoded>&lt;p&gt;If you're reading this, you've probably been hitting your head against a brick wall trying to parse and decipher the new HTTP Signatures sent by Mastodon and other Fediverse servers.&lt;/p&gt;

&lt;p&gt;This is a basic and somewhat incomplete guide to accepting these signatures. I'm sure there are various gotchas, but it works with the signatures I've seen in the wild.&lt;/p&gt;

&lt;h2 id="shut-up-and-show-me-the-code"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/#shut-up-and-show-me-the-code"&gt;Shut Up And Show Me The Code!&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;OK, wow, no need to be a dick about it! Here's how I validated a real signature that my server received. This requires PHP 8.4 or newer.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-php"&gt;$verified = openssl_verify(
    data:       '"@method": POST
"@target-uri": https://example.viii.fi/inbox
"content-digest": sha-256=:tFdB/ENGczHMlZMDb66pXoUi2d0OqH2iBHdnN/WV1mc=:
"@signature-params": ("@method" "@target-uri" "content-digest");created=1787780262;keyid="https://mastodon.social/users/Edent#main-key"',
    signature:  base64_decode( "sIfmNsM/Q8iG6AJlne1IkZVjQSVFDEYIPsnoSOXQY+W3Eb4+SOn9o4J5SQmFOP+Jecjf3ioFwUdsrFjAGkUUOHPvSbNWkGKtNuGm+C6r3aI3JBCFGPqX3ITgZYV76CF7JJJ5hPGaG8YH/XdmxVIeFfD3M39FQCncMyyq7xJJvwKKP1mzS5s1vNQie8hbQ9owRjtqvoWcmM9GEYCUHNcMPLjZc+CBrj8sfBbNTYgIFI4UtirOaRJvYymxXjmXuzeVYxQujMjAjgobxQ8QFv0zlYsHk+gS5EYyafpJG9zmfCFSoF9+ZwqKNADmuADbISD9LZIH/bmkPoNXhxaeFPqYog==" ),
    public_key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsYMEs4waqk/6gaS+xn1T\nYygElTtNIFNkBcEdEBMaeoGVhyZiVKtSjJCS4z+X+394PKvcfSTcFILIt2GI2jOB\nHD0M2fFgxc8mmdSdCQkgEh9jF3bFI3kopDvzYf726iioYKlHXKpfPKvFt7EJgKH7\naCtS25NQkek3YUd6y3VBcT3R6Xhze9P3QNoZMIsFXklgXDKj+EllfbUqLf1vxt3s\nmD9ETxy2bJi9FheE0uY2WhARn49XAvwczM5Wzt+zqxVEtgpi5v2+ZZAVKhDnJkiC\nCCuI6hrSnKNIx/5mSlX0a0S5h5d03djrCkYsqmwelu01rhOXP2grsz4BXp0y2wrO\n3QIDAQAB\n-----END PUBLIC KEY-----\n",
    algorithm:  "sha256"
);

echo $verified;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Copy and paste that into PHP and you should see that &lt;code&gt;$verified&lt;/code&gt; is true.&lt;/p&gt;

&lt;h2 id="now-explain-the-code"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/#now-explain-the-code"&gt;NOW EXPLAIN THE CODE&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Say please.&lt;/p&gt;

&lt;h2 id="please"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/#please"&gt;PLEASE!!!&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Along with the message sent to your server, you will have received HTTP headers like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-_"&gt;content-digest: sha-256=:tFdB/ENGczHMlZMDb66pXoUi2d0OqH2iBHdnN/WV1mc=:
signature: sig1=:sIfmNsM/Q8iG6AJlne1IkZVjQSVFDEYIPsnoSOXQY+W3Eb4+SOn9o4J5SQmFOP+Jecjf3ioFwUdsrFjAGkUUOHPvSbNWkGKtNuGm+C6r3aI3JBCFGPqX3ITgZYV76CF7JJJ5hPGaG8YH/XdmxVIeFfD3M39FQCncMyyq7xJJvwKKP1mzS5s1vNQie8hbQ9owRjtqvoWcmM9GEYCUHNcMPLjZc+CBrj8sfBbNTYgIFI4UtirOaRJvYymxXjmXuzeVYxQujMjAjgobxQ8QFv0zlYsHk+gS5EYyafpJG9zmfCFSoF9+ZwqKNADmuADbISD9LZIH/bmkPoNXhxaeFPqYog==:
signature-input: sig1=("@method" "@target-uri" "content-digest");created=1787780262;keyid="https://mastodon.social/users/Edent#main-key"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;signature-input&lt;/code&gt; tells you how to construct a "Signature Base". You have to build a text string which places the various components in the order specified and separated with a newline:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-_"&gt;"@method": POST
"@target-uri": https://example.viii.fi/inbox
"content-digest": sha-256=:tFdB/ENGczHMlZMDb66pXoUi2d0OqH2iBHdnN/WV1mc=:
"@signature-params": ("@method" "@target-uri" "content-digest");created=1787780262;keyid="https://mastodon.social/users/Edent#main-key"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Where &lt;code&gt;@method&lt;/code&gt; is the HTTP method used to send data to your server (usually &lt;code&gt;GET&lt;/code&gt; or &lt;code&gt;POST&lt;/code&gt;), and &lt;code&gt;@target-uri&lt;/code&gt; is the URl the message was sent to (usually your inbox).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;publicKey&lt;/code&gt; is slightly trickier. As you can see, the &lt;code&gt;signature-input&lt;/code&gt; ends with &lt;code&gt;keyid="https://mastodon.social/users/Edent#main-key&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you make a signed request to that URl, you'll get back an ActivityPub Actor document. It will look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-json"&gt;{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://w3id.org/security/v1",
  ],
  "id": "https://mastodon.social/users/Edent",
  "webfinger": "Edent@mastodon.social",
  "type": "Person",
  "name": "Terence Eden",
  "publicKey": {
    "id": "https://mastodon.social/users/Edent#main-key",
    "owner": "https://mastodon.social/users/Edent",
    "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsYMEs4waqk/6gaS+xn1T\nYygElTtNIFNkBcEdEBMaeoGVhyZiVKtSjJCS4z+X+394PKvcfSTcFILIt2GI2jOB\nHD0M2fFgxc8mmdSdCQkgEh9jF3bFI3kopDvzYf726iioYKlHXKpfPKvFt7EJgKH7\naCtS25NQkek3YUd6y3VBcT3R6Xhze9P3QNoZMIsFXklgXDKj+EllfbUqLf1vxt3s\nmD9ETxy2bJi9FheE0uY2WhARn49XAvwczM5Wzt+zqxVEtgpi5v2+ZZAVKhDnJkiC\nCCuI6hrSnKNIx/5mSlX0a0S5h5d03djrCkYsqmwelu01rhOXP2grsz4BXp0y2wrO\n3QIDAQAB\n-----END PUBLIC KEY-----\n"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;publicKeyPem&lt;/code&gt; is the string you need. There's no need to convert the &lt;code&gt;\n&lt;/code&gt; to literal newlines.&lt;/p&gt;

&lt;h2 id="is-that-it"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/#is-that-it"&gt;Is that it?&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Not quite! All we've done so far is verify the headers. It is possible that these are genuine headers but attached to a fraudulent body.&lt;/p&gt;

&lt;p&gt;This takes us back to the header &lt;code&gt;"content-digest": sha-256=:tFdB/ENGczHMlZMDb66pXoUi2d0OqH2iBHdnN/WV1mc=:&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That says that the body of the message sent has a Base64 encoded SHA256 hash of &lt;code&gt;tFdB/ENGczHMlZMDb66pXoUi2d0OqH2iBHdnN/WV1mc=&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To calculate your own content digest in PHP:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-php"&gt;$input = file_get_contents( "php://input" );
$digestCalculated = base64_encode(
    hash(
        algo: "sha256",
        data: $input,
        binary: true
    )
);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Does your digest match the one sent along with the headers? If not, something dodgy is going on.&lt;/p&gt;

&lt;h2 id="putting-it-all-together"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/#putting-it-all-together"&gt;Putting it all together&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;The steps are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get the headers.&lt;/li&gt;
&lt;li&gt;Get the body.&lt;/li&gt;
&lt;li&gt;From the headers' &lt;code&gt;content-digest&lt;/code&gt; extract the algorithm and hash.&lt;/li&gt;
&lt;li&gt;Using the body, calculate your own hash using the algorithm from &lt;code&gt;content-digest&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Does your hash match the sent hash? If not, stop. If so, proceed.&lt;/li&gt;
&lt;li&gt;From the headers' &lt;code&gt;signature&lt;/code&gt; extract the base64 encoded signature.&lt;/li&gt;
&lt;li&gt;From the headers' &lt;code&gt;signature-input&lt;/code&gt; extract the signature-input string.&lt;/li&gt;
&lt;li&gt;From the signature-input string extract the order of the Signature Base.&lt;/li&gt;
&lt;li&gt;Construct the Signature Base.&lt;/li&gt;
&lt;li&gt;From the signature-input string extract the keyid.&lt;/li&gt;
&lt;li&gt;Get the Public Key from the keyid.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;openssl_verify()&lt;/code&gt; to verify the Signature Base and the base64 decoded signature, against the Public Key using SHA256.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note, &lt;a href="https://docs.joinmastodon.org/spec/security/#http-message-signatures"&gt;Mastodon &lt;em&gt;only&lt;/em&gt; uses SHA256&lt;/a&gt;.  I think it should explicitly say which algorithm it is using &lt;a href="https://github.com/mastodon/mastodon/issues/29905#issuecomment-5440336919"&gt;and have raised the issue&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id="in-code-form"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/#in-code-form"&gt;In Code Form&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;This is how you do it in PHP. Please read this carefully as there are some hard-coded assumptions.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-php"&gt;&amp;lt;?php

//  Validate the Digest.
//  It is the hash of the raw input string, in binary, encoded as base64.

//  The format is content-digest =&amp;gt; &amp;lt;algorithm&amp;gt;=:&amp;lt;base64 encoded hash&amp;gt;:
$digestString = $headers["content-digest"];
//  The Base64 encoding may have multiple `=` at the end. So split this at the first `=`.
$digestData = explode( separator: "=", string: $digestString, limit: 2 );

//  Hashes are in lowercase, but have a `-` in their name.
//  This is not what hash_algos() expects.
$digestAlgorithm = str_replace( search: "-", replace: "", subject: $digestData[0] );

//  The hash is surrounded by `:` characters.
$digestHash = str_replace( search: ":", replace: "", subject: $digestData[1] );

//  Check if the hash algorithm is one known about to PHP.
//  If not, reject and record an error.
if ( !in_array( needle:$digestAlgorithm, haystack: hash_algos() ) ) {
    return false;
}

//  Manually calculate the digest based on the data sent.
$digestCalculated = base64_encode( hash( algo: $digestAlgorithm, data: $input, binary: true ) );

//  Does our calculation match what was sent?
if ( !( $digestCalculated == $digestHash ) ) {
    return false;
}

//  The signature format is signature =&amp;gt; &amp;lt;signature name&amp;gt;=:&amp;lt;base64 encoded hash&amp;gt;:
$signatureString = $headers["signature"];
//  The Base64 encoding may have multiple `=` at the end. So split this at the first `=`.
$signatureData = explode( separator: "=", string: $signatureString, limit: 2 );
$signatureName = $signatureData[0];

//  The signature is surrounded by `:` characters.
$signatureB64 = str_replace( search: ":", replace: "", subject: $signatureData[1] );

//  The signature-input format is complicated!
$signatureInputString = $headers["signature-input"];

//  Get the parameters. Assume there is only one signature.
$signatureParamsString = explode( separator: "=", string: $signatureInputString, limit: 2 )[1];

//  Get the different elements of the signature.
$signatureInputData = explode( separator: ";", string: $signatureInputString );

//  Construct the data.
$signatureInput = [];
foreach( $signatureInputData as $signatureInputParts ) {
    $partsData = explode( separator: "=", string: $signatureInputParts );
    //  Strip quotes from keyid and parentheses from sig1.
    if ( "keyid" == $partsData[0] ) {
        $partsData[1] = str_replace( search: "\"", replace: "", subject: $partsData[1] );
    }

    if ( $signatureName == $partsData[0] ) {
        $partsData[1] = str_replace( search: ["(", ")"], replace: "", subject: $partsData[1] );
    }

    $signatureInput[ $partsData[0] ] = $partsData[1] ;
}

$signatureStructure = $signatureInput[$signatureName];
$signatureKeyID     = $signatureInput["keyid"];

//  Remove quotes.
$signatureStructure = str_replace( search: "\"", replace: "", subject: $signatureStructure );
$signatureStructureData = explode( separator: " ", string: $signatureStructure );

//  https://www.rfc-editor.org/info/rfc9421/#section-2.5
$signatureBase = "";
foreach ( $signatureStructureData as $signatureStructureParts ) {
    if ( "@method" == $signatureStructureParts ) {
        //  https://www.rfc-editor.org/info/rfc9421/#name-method
        $signatureBase .= "\"@method\": " . $_SERVER["REQUEST_METHOD"] . "\n";
    }
    if ( "@target-uri" == $signatureStructureParts ) {
        //  https://www.rfc-editor.org/info/rfc9421/#section-2.2.2
        //  Change the domain name to your own.
        $signatureBase .= "\"@target-uri\": https://EXAMPLE.COM" . $_SERVER["REQUEST_URI"] . "\n";
    }
    if ( "content-digest" == $signatureStructureParts ) {
        $signatureBase .= "\"content-digest\": $digestString\n";
    }
}

//  https://victoronsoftware.com/posts/http-message-signatures/#how-the-signature-is-created
$signatureBase .= "\"@signature-params\": $signatureParamsString";

//  Get the signing user's public key.
//  This is usually in the form `https://example.com/user/username#main-key`
//  This is to differentiate if the user has multiple keys.
//  This may need to be a signed request. You will need to write your own getDataFromURl() function to get the sending user's key.
$userData  = getDataFromURl( $signatureKeyID );
$publicKey = $userData["publicKey"]["publicKeyPem"];

//  Verify the request
$verified = openssl_verify(
    data:       $signatureBase,
    signature:  base64_decode( $signatureB64 ),
    public_key: $publicKey,
    algorithm:  $digestAlgorithm
);

//  Convert the result to boolean.
if ( $verified === 1 ) {
    $verified = true;
} elseif ( $verified === 0 ) {
    $verified = false;
} else {
    $verified = null;
}

return $verified;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="further-reading"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/#further-reading"&gt;Further Reading&lt;/a&gt;&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/info/rfc9421/"&gt;RFC 9421 HTTP Message Signatures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://victoronsoftware.com/posts/http-message-signatures/"&gt;Understanding HTTP message signatures: A developer's guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.otoroshi.io/docs/tutorials/http-message-signatures-rfc9421/"&gt;Sign and verify HTTP messages (RFC 9421)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://darutk.medium.com/verification-of-http-message-signatures-501bbdc7dfec"&gt;Verification of HTTP Message Signatures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/macgirvin/HTTP-Message-Signer"&gt;HTTP-Message-Signer in PHP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="thanks-to-nlnet"&gt;&lt;a href="https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/#thanks-to-nlnet"&gt;Thanks to NLnet&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;This blog post was funded in part by the work I'm doing for my NLnet NGI0 grant. Thanks!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nlnet.nl/project/ActivityBot/"&gt;&lt;img src="https://shkspr.mobi/blog/wp-content/uploads/2026/08/NGI-logos.webp" alt="NLnet logo." width="900" height="200" class="aligncenter"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=74429&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/09/a-reasonably-practical-guide-to-validating-rfc-9421-http-signatures-for-activitypub-in-php/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Book Review: ActivityPub by Evan Prodromou ★★★★⯪]]></title>
		<link>https://shkspr.mobi/blog/2026/09/book-review-activitypub-by-evan-prodromou/</link>
					<comments>https://shkspr.mobi/blog/2026/09/book-review-activitypub-by-evan-prodromou/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Tue, 01 Sep 2026 11:34:18 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[Book Review]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=74414</guid>

					<description><![CDATA[As part of my grant from NLnet to improve my Fediverse bot project, I&#039;m spending time making sure I understand all the fundamentals of ActivityPub. The problem with Internet standards is they&#039;re scattered all over the place. Abandoned forums, half-maintained wikis, mailing lists with obscure rules, and monolithic blocks of text.  Sometimes you just want one book which collates all the info and…]]></description>
										<content:encoded>&lt;img src="https://shkspr.mobi/blog/wp-content/uploads/2026/08/activitypub.jpg" alt="Book cover with a parrot on it." width="200" class="alignleft"&gt;

&lt;p&gt;As part of &lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/"&gt;my grant from NLnet&lt;/a&gt; to improve my Fediverse bot project, I'm spending time making sure I understand all the fundamentals of ActivityPub. The problem with Internet standards is they're scattered all over the place. Abandoned forums, half-maintained wikis, mailing lists with obscure rules, and monolithic blocks of text.&lt;/p&gt;

&lt;p&gt;Sometimes you just want one book which collates all the info and presents it in a consistent format. This is &lt;em&gt;nearly&lt;/em&gt; that book.&lt;/p&gt;

&lt;p&gt;Evan Prodromou has the unenviable task of making the whole ecosystem easy to understand. Thankfully he does that well. Things are logically laid out, there are comprehensive descriptions of even the most obscure parts of the spec, and it builds up nicely from the fundamentals. Oh, it's also surprisingly light-hearted.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;This principle is so important and long-winded that web architects have given it an acronym, HATEOAS. (We often pronounce it “HATE-ee-OH-us,” which sounds like a breakfast cereal nobody wants to eat. This is one reason web architects aren’t allowed to name breakfast cereals.)&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;There's an excellent checklist for all the steps needed when building a minimal ActivityPub server.&lt;/p&gt;

&lt;p&gt;As with all O'Reilly books, it is a beautifully typeset ePub. Even better, it was supplied DRM-free through Kobo.&lt;/p&gt;

&lt;p&gt;About the only significant thing missing is details of how to verify RFC 9421 HTTP Signatures. That's understandable as they're pretty new, but a bit annoying as that's what a lot of servers are sending now. Similarly, there's a good write up of how to publish a poll, but not much about voting or publishing the results.&lt;/p&gt;

&lt;p&gt;The "Far Horizons" chapter is particularly exciting - giving a speculative overview of what AP &lt;em&gt;could&lt;/em&gt; be used for. I, for one, am particularly looking forward to putting my Internet Connected Fridge on social media 😆&lt;/p&gt;

&lt;p&gt;Ultimately ActivityPub is a living and evolving set of standards. No book can possibly keep up with all the changes happening to it - but Evan does a brilliant job of bringing together all the moving parts and creating a coherent picture of the standard.&lt;/p&gt;

&lt;p&gt;Highly recommended if you're interested in understanding the fundamentals of the Fediverse!&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=74414&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/09/book-review-activitypub-by-evan-prodromou/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[ActivityBot is the recipient of an NLnet grant!]]></title>
		<link>https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/</link>
					<comments>https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Sun, 30 Aug 2026 11:34:55 +0000</pubDate>
		<category><![CDATA[ActivityBot]]></category><category><![CDATA[ActivityPub]]></category><category><![CDATA[fediverse]]></category><category><![CDATA[NLnet]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=74406</guid>

					<description><![CDATA[Back in February, I applied for NLnet&#039;s Next Generation Zero grant. They were looking for Fediverse projects to help rewild the social media landscape. Or, as they describe it:  Reclaim the public nature of the internet  Small and medium-sized R&#38;D grants between 5.000 and 50.000 euro, with the possibility to scale up.  I run ActivityBot - it is a single-file ActivityPub server suitable for…]]></description>
										<content:encoded>&lt;p&gt;Back in February, I applied for &lt;a href="https://nlnet.nl/NGI0/"&gt;NLnet's Next Generation Zero grant&lt;/a&gt;. They were looking for Fediverse projects to help rewild the social media landscape. Or, as they describe it:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Reclaim the public nature of the internet&lt;/p&gt;

&lt;p&gt;Small and medium-sized R&amp;amp;D grants between 5.000 and 50.000 euro, with the possibility to scale up.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I run &lt;a href="https://gitlab.com/edent/activity-bot"&gt;ActivityBot&lt;/a&gt; - it is a single-file ActivityPub server suitable for launching automated accounts and designed as a learning tool for those who want to understand how the protocol works. Several people have told me how useful it is, but I haven't had the time to make it better. So I decided to stick in a last-minute application to the fund.&lt;/p&gt;

&lt;p&gt;I really didn't know how much to apply for - or even if my project would be suitable for funding - so I cheekily asked for €10,000. After a few months of back-and-forth, I'm delighted to announce that I was successful!&lt;/p&gt;

&lt;p&gt;In the spirit of openness, this blog post details how the NLnet grant process worked for me and what I'll be using the money for.&lt;/p&gt;

&lt;img src="https://shkspr.mobi/blog/wp-content/uploads/2026/08/NGI-logos.webp" alt="NLnet logo." width="900" height="200" class="aligncenter"&gt;

&lt;h2 id="the-process"&gt;&lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/#the-process"&gt;The Process&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;The application was delightfully simple. Here's what it asked for, along with my answers. If you apply, please don't copy these verbatim; use your own words.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Abstract    : A single file server for ActivityPub. Designed for write-only bots. Allows any project to quickly and easily start publishing automated content to the Fediverse. Uses PHP, no other dependencies.
&lt;/li&gt;&lt;li&gt;Experience  : I am the sole developer of Single File ActivityPub - https://gitlab.com/edent/activitypub-single-php-file&lt;br&gt;I was formerly the UK Government's representative to the W3C and have contributed to various ActivityPub projects and specifications.
&lt;/li&gt;&lt;li&gt;Amount      : € 10000
&lt;/li&gt;&lt;li&gt;Use         : The fund will be used for development, testing, promotional activity (including conference travel).&lt;br&gt;I anticipate this will fund 6 months of development. I have funded all previous development.&lt;br&gt;
&lt;/li&gt;&lt;li&gt;Comparison  : Most ActivityPub services are complex. They implement a full specification and are designed for multi-user environments. Other projects allow reading and writing. ActivityBot is deliberately designed to be as simple as possible. A single file to upload, one user, publish only.&lt;br&gt;This will enable more projects to be able to instantly start publishing with low development cost and close to zero hosting cost.
&lt;/li&gt;&lt;li&gt;Challenges  : Formal spec verification and a security audit will be the main technical challenges. The ActivityBot software has been running well for over a year. The funding will allow for better compatibility and security.
&lt;/li&gt;&lt;li&gt;Ecosystem   : The project has mostly targeted individuals who want to run small bots. After further development, the project will engage with IoT providers, smaller publishers, open source projects who wish to publish updates, and other relevant parties.
&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;I was told there was intense competition. After a couple of months, I received word that I'd made it to the 2nd round.&lt;/p&gt;

&lt;p&gt;What then followed was a &lt;em&gt;very&lt;/em&gt; polite interrogation about my ideas, how I would develop the project, what I would use the money for, and what my AI usage policy was.  They also wanted a breakdown of the main tasks - with the understanding that this would be a provisional document subject to change.&lt;/p&gt;

&lt;p&gt;I was on &lt;a href="https://shkspr.mobi/blog/2026/07/another-ridiculous-interrail-holiday-6379km-and-13-countries-over-7-weeks/"&gt;a train through Europe&lt;/a&gt; when I wrote this. I don't claim it to be a brilliant document - but it got the job done!&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;1. User Research

&lt;/p&gt;&lt;p&gt;Recruit 2 - 5 potential users. Offer an incentive (approx £20ea) to participate in a user research session. Study design will take 1 - 2 days. Each interview and write up to take 1 day. Consolidation and report 2 days.

&lt;/p&gt;&lt;p&gt;Total effort 3 - 4 weeks.

&lt;/p&gt;&lt;p&gt;2. Standards Research

&lt;/p&gt;&lt;p&gt;Participate in ActivityPub user communities and standardisation groups. Attend virtual conferences (or any local to the UK). Approx 1 day per week for 6 months.

&lt;/p&gt;&lt;p&gt;3. Test Driven Development

&lt;/p&gt;&lt;p&gt;Create modern test harness, write test suite, iterate design based on tests. Anticipated effort 2 days per week for approx 3 months.

&lt;/p&gt;&lt;p&gt;4. Security Testing

&lt;/p&gt;&lt;p&gt;Work with the community and security professionals to test the resultant code. This will use human testers and normal fuzzers - this will not use AI tools. Anticipated effort 2 days per week for approx 2 months.

&lt;/p&gt;&lt;p&gt;5. User Acceptance Testing

&lt;/p&gt;&lt;p&gt;Recruit 2 - 5 potential users (ideally different to the research participants). Offer an incentive (approx £20ea) to participate in a user acceptance session. Study design will take 1 - 2 days. Each interview and write up to take 1 day. Consolidation and report 2 days.

&lt;/p&gt;&lt;p&gt;Total effort 3 - 4 weeks.

&lt;/p&gt;&lt;p&gt;6. Updates Based on Research, Testing, and Security

&lt;/p&gt;&lt;p&gt;While it would be lovely to anticipate getting everything right first time, the reality is that changes will need to be made based on the findings of the above. This will take up the remainder of the allocated time.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Again, there was a little more back and forth. But a few weeks later I was informed that I was at the final stage, pending review. And, a few weeks after that, I was told my project had been given the green light.&lt;/p&gt;

&lt;p&gt;I was invited to a group call where the very friendly team discussed the practicalities of the grant, what it could and couldn't fund. I also met a bunch of other people who'd also won.&lt;/p&gt;

&lt;p&gt;The final stage was writing a proper Memorandum of Understanding. With the help of one of the team (thanks Victoria!) I was able to turn my scrappy plan into something a bit more formal. The project tool NLnet uses made it easy to build up a plan and put € amounts by each task.&lt;/p&gt;

&lt;p&gt;The idea is that I will invoice against the grant whenever I have completed a task or sub-task. Obviously I don't want to leave invoicing until the end of the project, but I also need to be mindful of the foreign exchange fees charged by my bank for receiving Euro payments.&lt;/p&gt;

&lt;h2 id="final-project-plan"&gt;&lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/#final-project-plan"&gt;Final Project Plan&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;This is the plan I submitted. It represents what I hope to accomplish and how I'll draw down on the grant. I suspect this will change as the months go on.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;ActivityBot is an Open Source project which aims to develop, maintain, and improve a minimum viable ActivityPub server in a single PHP file.&lt;/p&gt;

&lt;p&gt;The project is run by Terence Eden (trading as @edent); a developer residing in England.&lt;/p&gt;

&lt;p&gt;This project is expected to run for approximately 6 months. All of the deliverables will be openly licenced using either an OSI approved software licence or a Creative Commons licence.&lt;/p&gt;

&lt;p&gt;The high-level aims of the project are for ActivityBot to be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A fully compliant ActivityPub server, running in a single PHP file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A teaching tool to help developers understand the practical aspects of creating an ActivityPub server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A practical method of publishing automated messages to the Fediverse.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A promotional tool to show how simple and easy ActivityPub development can be.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A secure and usable tool written in modern PHP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Written by humans, with no AI/LLM generated code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In light of NLnet's non-profit status, costs assume a discounted rate of €330 per day (£280). Incidentals such as hardware, software, travel, or sundries will be charged at cost with receipts provided.&lt;/p&gt;

&lt;h2 id="prepare-for-initial-release"&gt;&lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/#prepare-for-initial-release"&gt;Prepare for initial release&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Ensure that the project is in a suitable state for initial release and future development.&lt;/p&gt;

&lt;p&gt;Deliverable: Updates published to GitLab.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;€495 Prepare initial release. Clarify licencing, solicit community engagement, include example usage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€495 Standards Research. Collation of standards websites. Ensure code comments refer to specific standards. Publish blog post(s) about findings for others to reference.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="user-research"&gt;&lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/#user-research"&gt;User Research&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Recruit up to 10 participants for a user-research study. Participants should represent the diversity of the Fediverse.&lt;/p&gt;

&lt;p&gt;Investigate what participants want from a tool like ActivityPub. The project plan may be adapted following the results of this study.&lt;/p&gt;

&lt;p&gt;Deliverable: Study plan and results will be published and given a Creative Commons licence. Changes based on the results will be pushed to GitLab.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;€660 Study Design and recruitment of participants (blog post published as deliverable).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€990 Two days of user interviews, write up and publish results as blog post.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="test-driven-development"&gt;&lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/#test-driven-development"&gt;Test Driven Development&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Create a modern test harness, write test suite, iterate design based on tests.&lt;/p&gt;

&lt;p&gt;Deliverable: Tests published to GitLab. Blog posts published about the process and results.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;€330 Set up test suite&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€330 Write tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€330 Fixes based on test results&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="security-testing"&gt;&lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/#security-testing"&gt;Security Testing&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Working with NLnet's security offering, ensure that the project meets modern security requirements.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;€720 Work with security team to assess security risks and possible mitigations. Fixes based on security team feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deliverable: Updates published to GitLab. Blogs published about the process and results.&lt;/p&gt;

&lt;h2 id="user-acceptance-testing"&gt;&lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/#user-acceptance-testing"&gt;User Acceptance Testing&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Recruit up to 10 participants for a user-acceptance study. Participants should represent the diversity of the Fediverse.&lt;/p&gt;

&lt;p&gt;Investigate whether participants are able to use ActivityBot. See which aspects need improvement. The project plan may be adapted following the results of this study.&lt;/p&gt;

&lt;p&gt;Deliverable: Study plan and results will be published and given a Creative Commons licence. Changes based on feedback will be published to GitLab.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;€660 Study Design and recruitment of participants (blog post published as deliverable).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€990 Two days of user interviews, write up and publish results as blog post.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="conferences-and-standards-work"&gt;&lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/#conferences-and-standards-work"&gt;Conferences and Standards Work&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Open Source participation often depends on attending conferences, either in person or virtually. Getting involved in the standardisation process ensures that future versions of ActivityPub and associated standards will be suitable for the community.&lt;/p&gt;

&lt;p&gt;Deliverables: Presentations material (slideware), speaking at conferences (may be published as video), conference outputs. Where possible, these will be available under a suitable Creative Commons licence.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;€700 Travel and accommodation to one EU conference&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€330 Publishing blog posts about ActivityPub standards work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€330 Publishing blog posts about ActivityPub standards work.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="final-release"&gt;&lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/#final-release"&gt;Final release&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Creating a final release for this phase of the ActivityBot project. This will involve incorporating all feedback received so far, improving documentation, and publishing code.&lt;/p&gt;

&lt;p&gt;Deliverable: Updates published to GitLab. Blog post written. Release announcements.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;€330 Phase 1: Process and implement feedback from users&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€330 Phase 2: Bug fixes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€330 Phase 3: Features&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€330 Phase 4: Bug fixes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€330 Phase 5: Features&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€330 Phase 6: Remedial work&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€330 Process and implement feedback from accessibility scan&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;€330 Final release&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="next-steps"&gt;&lt;a href="https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/#next-steps"&gt;Next Steps&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;I've already begun work on updating the code. If you'd like to get involved, or have suggestions or bug reports - please &lt;a href="https://gitlab.com/edent/activity-bot"&gt;take a look at ActivityBot on GitLab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'll be putting out a call for user-research participants once I've had a chance to catch my breath 😆&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=74406&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/08/activitybot-is-the-recipient-of-an-nlnet-grant/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[[RSS Club] I got an NLnet grant!]]></title>
		<link>https://shkspr.mobi/blog/2026/08/rss-club-i-got-an-nlnet-grant/</link>
					<comments>https://shkspr.mobi/blog/2026/08/rss-club-i-got-an-nlnet-grant/#respond</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Sat, 08 Aug 2026 11:34:15 +0000</pubDate>
		<category><![CDATA[ActivityBot]]></category><category><![CDATA[ActivityPub]]></category><category><![CDATA[RSS Club]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=73757</guid>

					<description><![CDATA[Pssst! This post is only available to RSS/Atom subscribers. Tell your friends to subscribe  😊.  Just a quick one today, a more detailed blog coming soon - but I thought I&#039;d give RSS Club Members (you!) a sneak peek.  A few months ago I saw a post on Mastodon from NLnet - they were looking for Open Source projects to apply for grant funding. The deadline was less than 24 hours away, so I rushed in …]]></description>
										<content:encoded>&lt;p&gt;&lt;mark&gt;Pssst! This post is only available to RSS/Atom subscribers. Tell your friends to subscribe &lt;/mark&gt; 😊.&lt;/p&gt;

&lt;p&gt;Just a quick one today, a more detailed blog coming soon - but I thought I'd give RSS Club Members (you!) a sneak peek.&lt;/p&gt;

&lt;p&gt;A few months ago I saw a post on Mastodon from &lt;a href="https://social.nlnet.nl/@nlnet"&gt;NLnet&lt;/a&gt; - they were looking for Open Source projects to apply for grant funding. The deadline was less than 24 hours away, so I rushed in an application.&lt;/p&gt;

&lt;p&gt;There was a ping-pong of emails where I detailed more about what I planned to do, and where they kept me abreast of their timescales.&lt;/p&gt;

&lt;p&gt;Finally, after about 6 months, I received the most delightful email confirming my place in the programme!&lt;/p&gt;

&lt;p&gt;I'm officially part of the &lt;a href="https://nlnet.nl/thema/NGI0CommonsFund.html"&gt;NGI0 Commons Fund&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, what's the project? Regular readers will remember that I created &lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/"&gt;ActivityBot&lt;/a&gt; as a lightweight, single-file, fully featured ActivityPub server. The grant will enable me to improve the code, test the usability, have a security audit, do some accessibility work, and make it more robust.&lt;/p&gt;

&lt;p&gt;I'm also going to need a logo 🤖&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://nlnet.nl/project/ActivityBot/"&gt;read more about the project on the NLnet site&lt;/a&gt;.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;Because this is an RSS-only post, it doesn't support comments. You can &lt;a href="https://edent.tel/"&gt;get in touch with me&lt;/a&gt; if you'd like to say something nice.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=73757&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/08/rss-club-i-got-an-nlnet-grant/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Scattered thoughts on social geolocation]]></title>
		<link>https://shkspr.mobi/blog/2026/07/scattered-thoughts-on-social-geolocation/</link>
					<comments>https://shkspr.mobi/blog/2026/07/scattered-thoughts-on-social-geolocation/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Wed, 22 Jul 2026 11:34:12 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[BlueSky]]></category><category><![CDATA[fediverse]]></category><category><![CDATA[FourSquare]]></category><category><![CDATA[GeoLocation]]></category><category><![CDATA[JSON]]></category><category><![CDATA[Open Standards]]></category><category><![CDATA[OpenStreetMap]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=73050</guid>

					<description><![CDATA[I want to be able to share my location with my friends on social media. Twitter (RIP) had a way to attach an optional location to a post. Facebook still lets me check in to venues. But neither ActivityPub (Mastodon) nor AT Protocol (BlueSky) allow me to do that.  I&#039;ve been banging on about this for a while so was delighted to be invited to chat with the GeoSocial Task Force on their monthly call. …]]></description>
										<content:encoded>&lt;p&gt;I want to be able to &lt;a href="https://shkspr.mobi/blog/2026/04/why-is-it-so-hard-to-passively-stalk-my-friends-locations/"&gt;share my location with my friends&lt;/a&gt; on social media. Twitter (RIP) had a way to attach an optional location to a post. Facebook still lets me check in to venues. But neither ActivityPub (Mastodon) nor AT Protocol (BlueSky) allow me to do that.&lt;/p&gt;

&lt;p&gt;I've been &lt;a href="https://shkspr.mobi/blog/2024/01/rebuilding-foursquare-for-activitypub-using-openstreetmap/"&gt;banging on about this for a while&lt;/a&gt; so was delighted to be invited to chat with the &lt;a href="https://github.com/swicg/geosocial"&gt;GeoSocial Task Force&lt;/a&gt; on &lt;a href="https://www.w3.org/events/meetings/ed630a3d-7581-4053-9978-75949ad42f2a/"&gt;their monthly call&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But, before I start, please remember that these proposals are not mandatory. If you don't want to share your location, then please don't share your location. This is an optional feature which shouldn't be used by people with a strong need for privacy.&lt;/p&gt;

&lt;p&gt;We were primarily discussing the nascent &lt;a href="https://swicg.github.io/geosocial/microsyntax.html"&gt;Geographical Microsyntax proposals&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Firstly, I &lt;em&gt;love&lt;/em&gt; the idea of being able to share my location. I want my friends to know I'm in town for a gig. I want people to think I'm cool because I'm seeing some experimental theatre. I want to virtue signal that I'm giving blood.&lt;/p&gt;

&lt;p&gt;Similarly, I want to be able to find social media posts by location. What's happening right now in Paris? Did anyone else hear that sonic boom in London? Which cool people are also at this gig with me?&lt;/p&gt;

&lt;p&gt;But, I do think these proposals have some issues which need to be addressed.&lt;/p&gt;

&lt;h2 id="user-research"&gt;&lt;a href="https://shkspr.mobi/blog/2026/07/scattered-thoughts-on-social-geolocation/#user-research"&gt;User Research&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;The primary thing missing from the proposal is any form of understanding what users want to do with a geotagged post.&lt;/p&gt;

&lt;p&gt;You see a post like:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Hanging out with friends. I just checked in to &lt;u&gt;Leicester Square&lt;/u&gt;.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;What do you expect to happen when you click that link?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;See who is at the location?&lt;/li&gt;
&lt;li&gt;Read more information about the place being discussed?&lt;/li&gt;
&lt;li&gt;Find all posts at that specific address?&lt;/li&gt;
&lt;li&gt;Discover posts which are &lt;em&gt;close&lt;/em&gt; to there?&lt;/li&gt;
&lt;li&gt;Something else?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What other things do people want to do with geotagged posts?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find all posts within 5Km of me?&lt;/li&gt;
&lt;li&gt;Discover users who have posted near me?&lt;/li&gt;
&lt;li&gt;Get emergency alerts for the city I'm in?&lt;/li&gt;
&lt;li&gt;See what's trending in a specific country?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without knowing what people might want to do with this information, it's rather hard to design a service which meets their needs.&lt;/p&gt;

&lt;h2 id="to-micro-or-not-to-micro"&gt;&lt;a href="https://shkspr.mobi/blog/2026/07/scattered-thoughts-on-social-geolocation/#to-micro-or-not-to-micro"&gt;To micro or not to micro?&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Where I disagree with the proposals is the idea of using inline text as a form of microsyntax.&lt;/p&gt;

&lt;p&gt;Proposals like "I am in /London/ eating ice-cream" or "Checked in to Leicester Square L:N123456" fail for a couple of reasons.&lt;/p&gt;

&lt;p&gt;Things like #hashtags and @mentions developed organically on social networks before they were eventually adopted by the platforms themselves. It is rare that a top-down diktat can be used to tell people how they &lt;em&gt;should&lt;/em&gt; be formatting their posts.&lt;/p&gt;

&lt;p&gt;More importantly, people are &lt;em&gt;crap&lt;/em&gt; at formatting things consistently! Every event I go to has people using &lt;code&gt;#Event&lt;/code&gt; alongside &lt;code&gt;#Event2026&lt;/code&gt; or &lt;code&gt;#Event26&lt;/code&gt; or a hundred variations.&lt;/p&gt;

&lt;p&gt;Even if users could format it consistently, names are ambiguous. Is &lt;code&gt;🌐:Paris&lt;/code&gt; the one in France or &lt;a href="https://en.wikipedia.org/wiki/Paris,_Texas_(film)"&gt;Texas&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;I'm strongly of the opinion that text is for text, not syntax.&lt;/p&gt;

&lt;h2 id="openness-%f0%9f%86%9a-centralisation"&gt;&lt;a href="https://shkspr.mobi/blog/2026/07/scattered-thoughts-on-social-geolocation/#openness-%f0%9f%86%9a-centralisation"&gt;Openness 🆚 Centralisation&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Saying that you're on a specific point on the globe doesn't always provide useful information. Even with altitude, it isn't always possible to work out if your in the Starbucks or the Costa next door. Do you want to say you're in a train station, or a distinct platform, or even a specific train journey?&lt;/p&gt;

&lt;p&gt;There are various services which offer unique IDs per loosely-defined place.&lt;/p&gt;

&lt;p&gt;Google Maps provides a &lt;a href="https://developers.google.com/maps/documentation/places/web-service/place-id"&gt;Place ID&lt;/a&gt; for every thing that it knows about. There's a similar service from &lt;a href="https://foursquare.com/products/places-api/"&gt;FourSquare&lt;/a&gt;.  But both of those are closed and proprietary systems - they can only be updated by the company that creates them.&lt;/p&gt;

&lt;p&gt;Wikipedia's Wikidata has &lt;a href="https://www.wikidata.org/wiki/Q676755"&gt;IDs for lots of places&lt;/a&gt;, similarly OpenStreetMap has &lt;a href="https://wiki.openstreetmap.org/wiki/Key:place"&gt;nodes with names&lt;/a&gt; which can be used to identify locations.&lt;/p&gt;

&lt;p&gt;But all of these suffer from the same flaw; they are centralised.&lt;/p&gt;

&lt;p&gt;If &lt;a href="https://killedbygoogle.com/"&gt;Google kills its service&lt;/a&gt; then all those Place IDs die.&lt;/p&gt;

&lt;p&gt;This has happened before. Yahoo used to run the &lt;a href="https://en.wikipedia.org/wiki/WOEID"&gt;Where On Earth IDentifier&lt;/a&gt; service but discontinued it.&lt;/p&gt;

&lt;p&gt;While OSM and Wikipedia are great projects, they're still centralised. If you're banned from OSM, you can't create a new node.&lt;/p&gt;

&lt;p&gt;So, to my mind, the &lt;em&gt;primary&lt;/em&gt; way of identifying a place has to use a fully open, globally agreed, and unrestricted standard.&lt;/p&gt;

&lt;h2 id="location-plus-plus"&gt;&lt;a href="https://shkspr.mobi/blog/2026/07/scattered-thoughts-on-social-geolocation/#location-plus-plus"&gt;Location Plus Plus&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;The obvious choice is latitude and longitude as defined by &lt;a href="https://www.linz.govt.nz/guidance/geodetic-system/coordinate-systems-used-new-zealand/geodetic-datums/world-geodetic-system-1984-wgs84"&gt;WGS 84&lt;/a&gt;. It allows for arbitrary precision anywhere on the planet.&lt;/p&gt;

&lt;p&gt;No one can stop you issuing lat/long just because a country is under sanctions. The standards community can't revoke your access to it. The co-ordinates are well understood by almost all software.&lt;/p&gt;

&lt;p&gt;There are some alternatives. Google's &lt;a href="https://maps.google.com/pluscodes/"&gt;Plus.Codes&lt;/a&gt; build on top of lat/long to make something more human readable. But, crucially, human readability is &lt;em&gt;not&lt;/em&gt; the issue here. This is metadata which should never be shown to a human. If a user interface wants to format a lat/long they can do so as a Plus.Code or any other format.&lt;/p&gt;

&lt;h2 id="geojson"&gt;&lt;a href="https://shkspr.mobi/blog/2026/07/scattered-thoughts-on-social-geolocation/#geojson"&gt;GeoJSON&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;There are dozens of &lt;a href="https://wiki.ietf.org/en/group/geopriv/LocationFormats"&gt;competing ways to mark up a location&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It seems sensible to me that, given most major social media protocols use JSON, adding &lt;a href="https://geojson.org/"&gt;GeoJSON&lt;/a&gt; would be the simplest way to add geographic information to a post's metadata.&lt;/p&gt;

&lt;p&gt;At its most basic, a single "Point" can be shared like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-json"&gt;{
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [-0.13005,51.5103]
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It can have as much or as little precision as needed.&lt;/p&gt;

&lt;p&gt;If the place being checked into has a name, it can also be added - this could be used for display purposes within the message&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-json"&gt;{
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [-0.13005,51.5103]
    },
    "properties": {
        "name": "Leicester Square"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;properties&lt;/code&gt; can be as complex as the sender wants. For example it could add Wikidata references, OpenStreetMap IDs, telephone numbers, or some cool new thing which hasn't been invented yet.&lt;/p&gt;

&lt;p&gt;Here's a maximalist example of checking in to a park:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-json"&gt;{
    "type": "Feature",
    "geometry": {
        "type": "Polygon",
        "coordinates": [
        [
                [-0.1303791,51.5099976],
                [-0.1295305,51.5100444],
                [-0.1297077,51.510947 ],
                [-0.1308786,51.5105859],
                [-0.1308893,51.5105793],
                [-0.1303791,51.5099976]
            ]
        ]
    },
    "properties": {
        "name": "Leicester Square",
        "WikiData": "Q848912",
        "OSM": "4082589",
        "GooglePlaceID": "ChIJPcTFENIEdkgR94E58rgB69o",
        "PlusCode": "9C3XGV69+4X",
        "Quinfrob": "🌐89451_𰻝",
        "address": {
            "road": "Leicester Square",
            "neighbourhood": "St. James's",
            "quarter": "East Marylebone",
            "suburb": "Covent Garden",
            "city": "City of Westminster",
            "ISO3166-2-lvl8": "GB-WSM",
            "state": "England",
            "ISO3166-2-lvl4": "GB-ENG",
            "postcode": "WC2H 7NA",
            "country": "United Kingdom",
            "country_code": "gb"
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="whats-next"&gt;&lt;a href="https://shkspr.mobi/blog/2026/07/scattered-thoughts-on-social-geolocation/#whats-next"&gt;What's Next&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;My personal opinion is that the following needs to happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Talk to some users - find out what they might use this for.&lt;/li&gt;
&lt;li&gt;Work with privacy advocates to reduce possible harms (for example, being able to redact a location from a previously shared post).&lt;/li&gt;
&lt;li&gt;Discuss with developers about how they'd work with this metadata.&lt;/li&gt;
&lt;li&gt;Clients should start adding GeoJSON metadata to their posts, even if it can't be displayed yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can &lt;a href="https://hedgedoc.socialweb.coop/hNLDxDqoQPaFlOf4aJ4E8g?view"&gt;read the minutes of the meeting&lt;/a&gt; and I'd encourage you to &lt;a href="https://www.w3.org/events/meetings/ed630a3d-7581-4053-9978-75949ad42f2a/"&gt;join the next call&lt;/a&gt;.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=73050&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/07/scattered-thoughts-on-social-geolocation/feed/</wfw:commentRss>
			<slash:comments>15</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Some updates to ActivityBot]]></title>
		<link>https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/</link>
					<comments>https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Mon, 16 Mar 2026 12:34:57 +0000</pubDate>
		<category><![CDATA[ActivityBot]]></category><category><![CDATA[ActivityPub]]></category><category><![CDATA[mastodon]]></category><category><![CDATA[PHP]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=68592</guid>

					<description><![CDATA[I couple of years ago, I developed ActivityBot - the simplest way to build Mastodon Bots. It is a single PHP file which can run an entire ActivityPub server and it is less than 80KB.  It works! You can follow @openbenches@bot.openbenches.org to see the latest entries on OpenBenches.org, and @colours@colours.bots.edent.tel for a slice of colour in your day, and @solar@solar.bots.edent.tel to see…]]></description>
										<content:encoded>&lt;p&gt;I couple of years ago, I developed &lt;a href="https://shkspr.mobi/blog/2024/11/introducing-activitybot-the-simplest-way-to-build-mastodon-bots/"&gt;ActivityBot - the simplest way to build Mastodon Bots&lt;/a&gt;. It is a &lt;em&gt;single&lt;/em&gt; PHP file which can run an entire ActivityPub server and it is less than 80KB.&lt;/p&gt;

&lt;p&gt;It works! You can follow &lt;code&gt;@openbenches@bot.openbenches.org&lt;/code&gt; to see the latest entries on OpenBenches.org, and &lt;code&gt;@colours@colours.bots.edent.tel&lt;/code&gt; for a slice of colour in your day, and &lt;code&gt;@solar@solar.bots.edent.tel&lt;/code&gt; to see what my solar panels are up to.&lt;/p&gt;

&lt;p&gt;This is &lt;em&gt;so&lt;/em&gt; easy to use. Copy the PHP file (and a &lt;code&gt;.env&lt;/code&gt; and &lt;code&gt;.htaccess&lt;/code&gt;) to literally any web host running PHP 8.5 and you have a fully-fledged bot which can post to Mastodon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gitlab.com/edent/activity-bot/"&gt;Grab the code and start today&lt;/a&gt;!&lt;/p&gt;

&lt;h2 id="features"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#features"&gt;Features&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Over the years I've added a few more features to it, so I thought I'd run through what they are. Note, this is all hand-written. No sycophantic plagiarism machines were involved in this code or blog post. I just really like emoji, OK⁉️&lt;/p&gt;

&lt;h3 id="%f0%9f%94%8d-be-discovered-on-the-fediverse"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%94%8d-be-discovered-on-the-fediverse"&gt;🔍 Be discovered on the Fediverse&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;This is the big one, you can find &lt;code&gt;@example@example.viii.fi&lt;/code&gt; on your favourite Fediverse client.  This is thanks to its WebFinger support.&lt;/p&gt;

&lt;h3 id="%f0%9f%91%89-be-followed-by-other-accounts"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%91%89-be-followed-by-other-accounts"&gt;👉 Be followed by other accounts&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;No point being discovered if you can't be followed. This accepts follow requests and sends back a signed accept.&lt;/p&gt;

&lt;h3 id="%f0%9f%9a%ab-be-unfollowed-by-accounts"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%9a%ab-be-unfollowed-by-accounts"&gt;🚫 Be unfollowed by accounts&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Sometimes people want to unfollow. Too bad, so sad. Again, this will accept the undo request and delete the unfollowing user's information.&lt;/p&gt;

&lt;h3 id="%f0%9f%93%a9-send-messages-to-the-fediverse"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%93%a9-send-messages-to-the-fediverse"&gt;📩 Send messages to the Fediverse&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;If a bot can be followed, but never posts, does it make a sound? This sends a post to all of your followers' (shared) inboxes. Includes some HTML formatting.&lt;/p&gt;

&lt;h3 id="%f0%9f%92%8c-send-direct-messages-to-users"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%92%8c-send-direct-messages-to-users"&gt;💌 Send direct messages to users&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Not every message is for the wider public. If you want a bot which sends you a private message, this'll set the visibility correctly.&lt;/p&gt;

&lt;h3 id="%f0%9f%93%b7-attach-images-alt-text-to-a-message-%f0%9f%86%95%f0%9f%86%95"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%93%b7-attach-images-alt-text-to-a-message-%f0%9f%86%95%f0%9f%86%95"&gt;📷 Attach images &amp;amp; alt text to a message 🆕🆕&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;A picture is worth a thousand words. But those pictures are meaningless without alt text. Attach as many images as you like. Note, most Mastodon services only accept a maximum of four.&lt;/p&gt;

&lt;h3 id="%f0%9f%8d%bf-video-upload-%f0%9f%86%95%f0%9f%86%95"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%8d%bf-video-upload-%f0%9f%86%95%f0%9f%86%95"&gt;🍿 Video Upload 🆕🆕&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;No transcoding or anything fancy. Upload a video and it'll be sent to your followers.&lt;/p&gt;

&lt;h3 id="%f0%9f%94%8a-audio-upload-%f0%9f%86%95%f0%9f%86%95"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%94%8a-audio-upload-%f0%9f%86%95%f0%9f%86%95"&gt;🔊 Audio Upload 🆕🆕&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Same as video. Raw audio posted to your followers' feeds.&lt;/p&gt;

&lt;h3 id="%f0%9f%95%b8%ef%b8%8f-autolink-urls-hashtags-and-mentions"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%95%b8%ef%b8%8f-autolink-urls-hashtags-and-mentions"&gt;🕸️ Autolink URls, hashtags, and @ mentions&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Including URls, tags, and mentions are &lt;em&gt;mostly&lt;/em&gt; autolinked correctly. There's a lot of fuzziness in how it works.&lt;/p&gt;

&lt;h3 id="%f0%9f%a7%b5-threads"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%a7%b5-threads"&gt;🧵 Threads&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;You can reply to specific messages in order to create a thread.&lt;/p&gt;

&lt;h3 id="%f0%9f%91%88-follow-unfollow-block-and-unblock-other-accounts"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%91%88-follow-unfollow-block-and-unblock-other-accounts"&gt;👈 Follow, Unfollow, Block, and Unblock other accounts&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;It might be useful for you to remove followers or follow specific accounts.&lt;/p&gt;

&lt;h3 id="%f0%9f%97%91%ef%b8%8f-delete-posted-messages-and-their-attachments-%f0%9f%86%95%f0%9f%86%95"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%97%91%ef%b8%8f-delete-posted-messages-and-their-attachments-%f0%9f%86%95%f0%9f%86%95"&gt;🗑️ Delete posted messages and their attachments 🆕🆕&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;We all make mistakes. This will delete your post along with any attachments and send that delete message to everyone. Note, because of the federated nature of the Fediverse, you cannot guarantee that a remote server will delete anything.&lt;/p&gt;

&lt;h3 id="%e2%9c%8f%ef%b8%8f-edit-posts-%f0%9f%86%95%f0%9f%86%95"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%e2%9c%8f%ef%b8%8f-edit-posts-%f0%9f%86%95%f0%9f%86%95"&gt;✏️ Edit Posts 🆕🆕&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;If you don't want to delete and re-post, you can edit your existing posts.&lt;/p&gt;

&lt;h3 id="%f0%9f%a6%8b-bridge-to-bluesky-with-your-domain-name-via-bridgy-fed"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%a6%8b-bridge-to-bluesky-with-your-domain-name-via-bridgy-fed"&gt;🦋 Bridge to BlueSky with your domain name via Bridgy Fed&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Not everyone is on the Fediverse. If you want to bridge to BlueSky, you can use the &lt;a href="https://fed.brid.gy/"&gt;Bridgy Fed service&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id="%f0%9f%9a%9a-move-followers-from-an-old-account-and-to-a-new-account-%f0%9f%86%95%f0%9f%86%95"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%9a%9a-move-followers-from-an-old-account-and-to-a-new-account-%f0%9f%86%95%f0%9f%86%95"&gt;🚚 Move followers from an old account and to a new account 🆕🆕&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Perhaps you started as &lt;code&gt;@electric@sex.pants&lt;/code&gt; but now you want to become &lt;code&gt;@chaste@nunslife.biz&lt;/code&gt; - no worries! You can tell followers you've moved and what your new name is.&lt;/p&gt;

&lt;p&gt;Similarly, if ActivityBot is no longer right for you, it's simple to tell your existing follower to move to your new account.&lt;/p&gt;

&lt;h3 id="%f0%9f%97%a8%ef%b8%8f-allow-quote-posts-%f0%9f%86%95%f0%9f%86%95"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%97%a8%ef%b8%8f-allow-quote-posts-%f0%9f%86%95%f0%9f%86%95"&gt;🗨️ Allow quote posts 🆕🆕&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Rather than just reposting your message, this sets the quote policy to allow people to share your message and attach some commentary of your own.&lt;/p&gt;

&lt;h3 id="%f0%9f%91%80-show-followers"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%91%80-show-followers"&gt;👀 Show followers&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Your follower count isn't just a number, it is a living list of &lt;em&gt;who&lt;/em&gt; chooses to follow you.&lt;/p&gt;

&lt;h3 id="%e2%9a%a0%ef%b8%8f-content-warnings-%f0%9f%86%95%f0%9f%86%95"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%e2%9a%a0%ef%b8%8f-content-warnings-%f0%9f%86%95%f0%9f%86%95"&gt;⚠️ Content Warnings 🆕🆕&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Perhaps you want to hide a bit of what you're saying. Add a content warning to hide part of your message.&lt;/p&gt;

&lt;h3 id="%f0%9f%94%8f-verify-cryptographic-signatures"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%94%8f-verify-cryptographic-signatures"&gt;🔏 Verify cryptographic signatures&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://shkspr.mobi/blog/2024/03/i-made-a-mistake-in-verifying-http-message-signatures/"&gt;HTTP Message Signatures is &lt;em&gt;hard&lt;/em&gt;&lt;/a&gt;. I think I've mostly got it sorted.&lt;/p&gt;

&lt;h3 id="%f0%9f%aa%b5-log-sent-messages-and-errors"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%aa%b5-log-sent-messages-and-errors"&gt;🪵 Log sent messages and errors&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;This is primarily a learning aide, so have a rummage through the logs and see what's going on.&lt;/p&gt;

&lt;h3 id="%f0%9f%9a%ae-clear-logs-when-there-are-too-many"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%9a%ae-clear-logs-when-there-are-too-many"&gt;🚮 Clear logs when there are too many&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;ActivityPub is a &lt;em&gt;chatty&lt;/em&gt; protocol. Your server can easily fill up with hundreds of thousands of messages from others. This regularly prunes down to something more manageable.&lt;/p&gt;

&lt;h3 id="%ef%b8%8f%e2%83%a3-hashed-passwords-for-posting-%f0%9f%86%95%f0%9f%86%95"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%ef%b8%8f%e2%83%a3-hashed-passwords-for-posting-%f0%9f%86%95%f0%9f%86%95"&gt;#️⃣ Hashed passwords for posting 🆕🆕&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Bit of a guilty moment here. I was originally storing the password in plaintext. Naughty! Passwords are now salted and hashed.&lt;/p&gt;

&lt;h3 id="%f0%9f%92%bb-basic-website-for-showing-posts"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%92%bb-basic-website-for-showing-posts"&gt;💻 Basic website for showing posts&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;A nice-enough looking front end if people want to view the posts directly on your domain.&lt;/p&gt;

&lt;h2 id="some-deficiencies"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#some-deficiencies"&gt;Some Deficiencies&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Not every piece of software is perfect. ActivityBot is less perfect than most things. Here are some of the things it can't do and, perhaps, will never do.  If you'd like to help tackle any of these, &lt;a href="https://gitlab.com/edent/activity-bot/"&gt;fork the code from my git repo&lt;/a&gt;!&lt;/p&gt;

&lt;h3 id="%e2%8f%b3-retry-failed-messages"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%e2%8f%b3-retry-failed-messages"&gt;⏳ Retry Failed Messages&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;A &lt;em&gt;proper&lt;/em&gt; Mastodon server will keep trying to send messages to unresponsive hosts. ActivityBot is one-and-done. If a remote server didn't respond in time, or was offline, or something else went wrong - it may not get the message.&lt;/p&gt;

&lt;h3 id="%f0%9f%94%84-reposts-announce-quote"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%94%84-reposts-announce-quote"&gt;🔄 Reposts / Announce / Quote&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;You cannot boost other posts, or even your own. Nor can you send quote posts.&lt;/p&gt;

&lt;h3 id="%f0%9f%a4%96-act-on-instructions"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%a4%96-act-on-instructions"&gt;🤖 Act On Instructions&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;This is a basic bot. It contains no logic. If you send it a message asking it to take action, it will not. You will need to build something else to make it truly interactive.&lt;/p&gt;

&lt;h3 id="%f0%9f%93%a5-receive-messages"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%93%a5-receive-messages"&gt;📥 Receive Messages&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;In fact, other than the follow / unfollow stuff, the bot can't receive any messages from the Fediverse. It doesn't know when a post has been replied to, liked, or reposted.&lt;/p&gt;

&lt;h3 id="%f0%9f%98%8e-set-post-visibility"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%98%8e-set-post-visibility"&gt;😎 Set Post Visibility&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Your posts are either public or a DM. There's no support for things like quiet followers.&lt;/p&gt;

&lt;h3 id="%f0%9f%93%8a-create-polls"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%93%8a-create-polls"&gt;📊 Create Polls&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Everyone loves to vote on meaningless polls - but this is quite a hard problem for ActivityBot. It would need to keep track of votes, prevent double voting, and probably some other difficult stuff.&lt;/p&gt;

&lt;h3 id="%f0%9f%97%a8%ef%b8%8f-change-quote-post-visibility"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%97%a8%ef%b8%8f-change-quote-post-visibility"&gt;🗨️ Change Quote Post Visibility&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;As quote posts are still quite new to Mastodon, I'm not sure how best to implement this.&lt;/p&gt;

&lt;h3 id="%f0%9f%94%97-proper-html-markdown-support"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%94%97-proper-html-markdown-support"&gt;🔗 Proper HTML / Markdown Support&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Autolinking names, hashtags, and links just about works - but not very reliably. In theory the bot &lt;em&gt;could&lt;/em&gt; parse Markdown and create richly formatted HTML from it. But that may require an external library which would bloat the size. Perhaps posting raw HTML could work?&lt;/p&gt;

&lt;h3 id="%f0%9f%96%bc%ef%b8%8f-focus-points-for-images"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%f0%9f%96%bc%ef%b8%8f-focus-points-for-images"&gt;🖼️ Focus Points for Images&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Perhaps of less use now, but still of interest to people?&lt;/p&gt;

&lt;h3 id="%e2%9d%93-other-stuff"&gt;&lt;a href="https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/#%e2%9d%93-other-stuff"&gt;❓ Other Stuff&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;I don't know what I don't know. Maybe some stuff is total broken? Maybe it is wildly out of spec? If you spot something dodgy, please let me know or &lt;a href="https://gitlab.com/edent/activity-bot/"&gt;raise a Pull Request&lt;/a&gt;.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=68592&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/03/some-updates-to-activitybot/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Now witness the power of this fully operational Fediverse!]]></title>
		<link>https://shkspr.mobi/blog/2025/11/now-witness-the-power-of-this-fully-operational-fediverse/</link>
					<comments>https://shkspr.mobi/blog/2025/11/now-witness-the-power-of-this-fully-operational-fediverse/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Sun, 23 Nov 2025 12:34:35 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[BlueSky]]></category><category><![CDATA[fediverse]]></category><category><![CDATA[mastodon]]></category><category><![CDATA[statistics]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=63716</guid>

					<description><![CDATA[How can you measure the popularity of a social network site? Perhaps by counting the number of active accounts, or the quality of the discourse, or even how many people reply to your witty memes.  Me? I prefer to look at how many people visit my blog from each site. It is an imperfect measure - and a vain one - but lets me know where I should be spending my time. No point posting on a network…]]></description>
										<content:encoded>&lt;p&gt;How can you measure the popularity of a social network site? Perhaps by counting the number of active accounts, or the quality of the discourse, or even how many people reply to your witty memes.&lt;/p&gt;

&lt;p&gt;Me? I prefer to look at how many people visit my blog from each site. It is an imperfect measure - and a vain one - but lets me know where I should be spending my time. No point posting on a network which is just bots talking to each other, right?&lt;/p&gt;

&lt;p&gt;Earlier this year &lt;a href="https://shkspr.mobi/blog/2025/09/reasonably-accurate-privacy-conscious-cookieless-visitor-tracking-for-wordpress/"&gt;I built a stats-counter for my blog&lt;/a&gt;. Every time someone clicks from a website which links to my blog, it records that visit in a database. I get to see which blog posts are doing numbers, and where those numbers came from.&lt;/p&gt;

&lt;p&gt;Until fairly recently, the Mastodon social network didn't send referer details. I thought that reduced the visibility of the network and &lt;a href="https://shkspr.mobi/blog/2024/12/mastodon-now-sends-referer-headers-hurrah/"&gt;lobbied for it to change&lt;/a&gt;. As various Mastodon servers upgrade, and admins opt-in, it is becoming more apparent just how much traffic originates from the Fediverse.&lt;/p&gt;

&lt;p&gt;Over the last few weeks, here's how many people have clicked &lt;em&gt;from&lt;/em&gt; BlueSky and Mastodon &lt;em&gt;to&lt;/em&gt; one of my blog posts.&lt;/p&gt;

&lt;table class="edent_stats_column"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class="totals"&gt;Total&lt;/th&gt;&lt;th&gt;Source&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;1,607&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=bsky.app"&gt;&lt;a href="https://bsky.app"&gt;bsky.app&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;752&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=mastodon.social"&gt;&lt;a href="https://mastodon.social"&gt;mastodon.social&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;At first glance, it doesn't look good for our elephantine friends, does it? The butterfly sends over twice the traffic. Game over!&lt;/p&gt;

&lt;p&gt;But, of course, while Mastodon.social is the biggest instance - it is far from the only one. What happens if we slide down the long tail? Here's all the Mastodon-ish instances which sent me over 10 clicks.&lt;/p&gt;

&lt;table class="edent_stats_column"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class="totals"&gt;Total&lt;/th&gt;&lt;th&gt;Source&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;193&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=phanpy.social"&gt;&lt;a href="https://phanpy.social"&gt;phanpy.social&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;120&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=joinmastodon.org"&gt; android-app://org.joinmastodon.android/&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;106&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=infosec.exchange"&gt;&lt;a href="https://infosec.exchange"&gt;infosec.exchange&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;62&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=mas.to"&gt;&lt;a href="https://mas.to"&gt;mas.to&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;59&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=mstdn.social"&gt;&lt;a href="https://mstdn.social"&gt;mstdn.social&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;55&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=social.vivaldi.net"&gt;&lt;a href="https://social.vivaldi.net"&gt;social.vivaldi.net&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;49&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=wandering.shop"&gt;&lt;a href="https://wandering.shop"&gt;wandering.shop&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;48&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=fosstodon.org"&gt;&lt;a href="https://fosstodon.org"&gt;fosstodon.org&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;33&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=mathstodon.xyz"&gt;&lt;a href="https://mathstodon.xyz"&gt;mathstodon.xyz&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;27&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=mastodon.online"&gt;&lt;a href="https://mastodon.online"&gt;mastodon.online&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;26&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=mastodon.scot"&gt;&lt;a href="https://mastodon.scot"&gt;mastodon.scot&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;24&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=app.wafrn.net"&gt;&lt;a href="https://app.wafrn.net"&gt;app.wafrn.net&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;19&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=indieweb.social"&gt;&lt;a href="https://indieweb.social"&gt;indieweb.social&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;18&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=social.lol"&gt;&lt;a href="https://social.lol"&gt;social.lol&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;17&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=tech.lgbt"&gt;&lt;a href="https://tech.lgbt"&gt;tech.lgbt&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;17&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=toot.wales"&gt;&lt;a href="https://toot.wales"&gt;toot.wales&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;16&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=en.osm.town"&gt;&lt;a href="https://en.osm.town"&gt;en.osm.town&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;16&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=feditrends.com"&gt;&lt;a href="https://feditrends.com"&gt;feditrends.com&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;14&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=mstdn.ca"&gt;&lt;a href="https://mstdn.ca"&gt;mstdn.ca&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;14&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=piefed.social"&gt;&lt;a href="https://piefed.social"&gt;piefed.social&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;12&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=wetdry.world"&gt;&lt;a href="https://wetdry.world"&gt;wetdry.world&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;11&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=c.im"&gt;&lt;a href="https://c.im"&gt;c.im&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;11&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=mastodon.nl"&gt;&lt;a href="https://mastodon.nl"&gt;mastodon.nl&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;51&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=mastodon.social"&gt; Sites sending &amp;lt; 10 clicks&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Ah! Add them all up and you get a grand total of &lt;strong&gt;1,773 visitors from Mastodon-powered sites&lt;/strong&gt;.  That's &lt;em&gt;more&lt;/em&gt; than BlueSky.&lt;/p&gt;

&lt;p&gt;Now, there are some obvious caveats to the data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I have a smaller follower count on BlueSky than I do on Mastodon.&lt;/li&gt;
&lt;li&gt;My posts may appeal more to one demographic than another.&lt;/li&gt;
&lt;li&gt;People may have strict privacy controls which suppress the true volume of visitors.&lt;/li&gt;
&lt;li&gt;There's no way to measure how long someone spends reading my posts.&lt;/li&gt;
&lt;li&gt;RSS and newsletter visitors aren't counted.&lt;/li&gt;
&lt;li&gt;Clicks from apps may not always show a referer.&lt;/li&gt;
&lt;li&gt;Some people may be on multiple services.&lt;/li&gt;
&lt;li&gt;Fediverse users can follow the post directly, so don't need to visit the site to read it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yet… no matter how you slice it, Fediverse servers are sending as much traffic as BlueSky!&lt;/p&gt;

&lt;p&gt;I think this is brilliant. Web services should be able to scale from small to big - and each ActivityPub-powered site helps power the open Internet.&lt;/p&gt;

&lt;p&gt;Just for completeness, this is how Reddit, Facebook, LinkedIn, Twitter, and Lemmy do over the same period:&lt;/p&gt;

&lt;table class="edent_stats_column"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class="totals"&gt;Total&lt;/th&gt;&lt;th&gt;Source&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;1,158&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=reddit.com"&gt;&lt;a href="https://reddit.com"&gt;reddit.com&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;585&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=reddit.com"&gt; android-app://com.reddit.frontpage/&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;76&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=facebook.com"&gt;&lt;a href="https://facebook.com"&gt;facebook.com&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;76&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=old.reddit.com"&gt;&lt;a href="https://old.reddit.com/r/programming/"&gt;https://old.reddit.com/r/programming/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;56&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=www.reddit.com"&gt;&lt;a href="https://www.reddit.com/r/programming/"&gt;https://www.reddit.com/r/programming/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;52&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=youtube.com"&gt;&lt;a href="https://youtube.com"&gt;youtube.com&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;41&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=t.co"&gt;&lt;a href="https://t.co"&gt;t.co&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;38&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=old.reddit.com"&gt;&lt;a href="https://old.reddit.com/r/todayilearned/comments/1nsw7f4/til_in_mongolia_instead_of_a_street_address_a/"&gt;https://old.reddit.com/r/todayilearned/comments/1nsw7f4/til_in_mongolia_instead_of_a_street_address_a/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;31&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=linkedin.com"&gt;&lt;a href="https://linkedin.com"&gt;linkedin.com&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;27&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=lemmy.world"&gt; android-app://io.syncapps.lemmy_sync/&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;27&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=www.reddit.com"&gt;&lt;a href="https://www.reddit.com/r/todayilearned/comments/1nsw7f4/til_in_mongolia_instead_of_a_street_address_a/"&gt;https://www.reddit.com/r/todayilearned/comments/1nsw7f4/til_in_mongolia_instead_of_a_street_address_a/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;22&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=old.reddit.com"&gt;&lt;a href="https://old.reddit.com/r/programming/comments/1n96ftn/40_years_later_are_bentleys_programming_pearls/"&gt;https://old.reddit.com/r/programming/comments/1n96ftn/40_years_later_are_bentleys_programming_pearls/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;22&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=lemmy.ca"&gt;&lt;a href="https://lemmy.ca"&gt;lemmy.ca&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;17&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=linkedin.com"&gt; android-app://com.linkedin.android/&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;16&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=lemmy.dbzer0.com"&gt;&lt;a href="https://lemmy.dbzer0.com"&gt;lemmy.dbzer0.com&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;14&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=feddit.org"&gt;&lt;a href="https://feddit.org"&gt;feddit.org&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;11&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=www.reddit.com"&gt;&lt;a href="https://www.reddit.com/r/programming/comments/1n96ftn/40_years_later_are_bentleys_programming_pearls/"&gt;https://www.reddit.com/r/programming/comments/1n96ftn/40_years_later_are_bentleys_programming_pearls/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;10&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=discuss.tchncs.de"&gt;&lt;a href="https://discuss.tchncs.de"&gt;discuss.tchncs.de&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;10&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=l.instagram.com"&gt;&lt;a href="https://l.instagram.com"&gt;l.instagram.com&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;8&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=lemmy.blahaj.zone"&gt;&lt;a href="https://lemmy.blahaj.zone"&gt;lemmy.blahaj.zone&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;6&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=www.reddit.com"&gt;&lt;a href="https://www.reddit.com/r/GrapheneOS/comments/1m2l84b/considering_making_the_switch_does_google_pay/"&gt;https://www.reddit.com/r/GrapheneOS/comments/1m2l84b/considering_making_the_switch_does_google_pay/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="stats-count"&gt;6&lt;/td&gt;&lt;td&gt;&lt;img class="pingback-favicon" src="https://shkspr.mobi/favicons/?domain=reddthat.com"&gt;&lt;a href="https://reddthat.com"&gt;reddthat.com&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;If you add up all the Lemmy instances, they send about as much traffic as Facebook and LinkedIn combined. That's not a huge surprise - those platforms hate anyone clicking away to the wider web.&lt;/p&gt;

&lt;p&gt;Twitter is basically &lt;a href="https://en.wikipedia.org/wiki/Dead_Internet_theory"&gt;the Dead Internet&lt;/a&gt;. I'm no longer on there, but I do occasionally search it to see who is sharing my posts. The popular posts I write get shared a &lt;em&gt;lot&lt;/em&gt; - sometimes by accounts with huge followers - yet there are no comments or retweets and barely and clicks.&lt;/p&gt;

&lt;p&gt;I don't do Instagram or Threads, and that might be reflected in their low numbers. But I'm not active on YouTube either - yet people there occasionally link back to me.&lt;/p&gt;

&lt;h2 id="final-thoughts"&gt;&lt;a href="https://shkspr.mobi/blog/2025/11/now-witness-the-power-of-this-fully-operational-fediverse/#final-thoughts"&gt;Final Thoughts&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Firstly, my stats only represent my site. Your site might be very different.&lt;/p&gt;

&lt;p&gt;Secondly, I've ignored search engine traffic, big blogs, newsletters, and other sources.&lt;/p&gt;

&lt;p&gt;Thirdly, and most importantly, this &lt;em&gt;isn't&lt;/em&gt; a competition! The desire for a "winner-takes-all" service is dangerous and disturbing. An ecosystem is at its most vibrant when there are multiple participants each thriving in their own niche.&lt;/p&gt;

&lt;p&gt;I want a thousand sites, running a hundred different software stacks, some of which only serve a dozen people, or even a lone participant.&lt;/p&gt;

&lt;p&gt;Diversity is strength.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=63716&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2025/11/now-witness-the-power-of-this-fully-operational-fediverse/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Getting started with Mastodon's Quote Posts - technical implementation details for servers]]></title>
		<link>https://shkspr.mobi/blog/2025/10/getting-started-with-mastodons-quote-posts-technical-implementation-details-for-servers/</link>
					<comments>https://shkspr.mobi/blog/2025/10/getting-started-with-mastodons-quote-posts-technical-implementation-details-for-servers/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Fri, 03 Oct 2025 11:34:27 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[fediverse]]></category><category><![CDATA[mastodon]]></category><category><![CDATA[MastodonAPI]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=63527</guid>

					<description><![CDATA[Quoting posts on Mastodon is slightly complex. Because of the privacy conscious nature of the platform and its users, reposting isn&#039;t merely a case of sharing a URl.  A user writes a status. The user can choose to make their statuses quotable or not. What happens when a quoter quotes that post?  I&#039;ve read through the specification and tried to simplify it.  Quoting is a multi-step process:   The…]]></description>
										<content:encoded>&lt;p&gt;Quoting posts on Mastodon is &lt;em&gt;slightly&lt;/em&gt; complex. Because of the privacy conscious nature of the platform and its users, reposting isn't merely a case of sharing a URl.&lt;/p&gt;

&lt;p&gt;A user writes a status. The user can choose to make their statuses quotable or not. What happens when a quoter quotes that post?&lt;/p&gt;

&lt;p&gt;I've &lt;a href="https://codeberg.org/fediverse/fep/src/branch/main/fep/044f/fep-044f.md"&gt;read through the specification&lt;/a&gt; and tried to simplify it.  Quoting is a multi-step process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The status &lt;em&gt;must&lt;/em&gt; opt-in to being shared.&lt;/li&gt;
&lt;li&gt;The quoter quotes the status.&lt;/li&gt;
&lt;li&gt;The quoter's server sends a request to the status's server.&lt;/li&gt;
&lt;li&gt;The status's server sends an accept message back to the quoter's server.&lt;/li&gt;
&lt;li&gt;When other servers see the quote, they check with the status's server to see if it is allowed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm going to walk you through each stage as best as I understand them.&lt;/p&gt;

&lt;h2 id="opting-in"&gt;&lt;a href="https://shkspr.mobi/blog/2025/10/getting-started-with-mastodons-quote-posts-technical-implementation-details-for-servers/#opting-in"&gt;Opting In&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;An ActivityPub status message is JSON. In order to opt-in, it needs this additional field.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-JSON"&gt;"interactionPolicy": {
  "canQuote": {
    "automaticApproval": "https://www.w3.org/ns/activitystreams#Public"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That tells ActivityPub clients that anyone is allowed to quote this post. It is also possible to say that only specific users, or only followers, or no-one is allowed.&lt;/p&gt;

&lt;h2 id="the-quoterequest"&gt;&lt;a href="https://shkspr.mobi/blog/2025/10/getting-started-with-mastodons-quote-posts-technical-implementation-details-for-servers/#the-quoterequest"&gt;The QuoteRequest&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Someone has hit the quote post button, typed their own message, and shared their wisdom. Their server sends the following message to the server which hosts the quoted status. This has been edited for brevity.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-JSON"&gt;{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "QuoteRequest":   "https://w3id.org/fep/044f#QuoteRequest"
    }
  ],
  "type": "QuoteRequest",
  "id":     "https://mastodon.test/users/Edent/quote_requests/1234-5678-9101",
  "actor":  "https://mastodon.test/users/Edent",
  "object": "https://example.com/posts/987654321.json",
  "instrument": {
    "id":           "https://mastodon.test/users/Edent/statuses/123456789",
    "url":          "https://mastodon.test/@Edent/123456789",
    "attributedTo": "https://mastodon.test/users/Edent",
    "quote":          "https://example.com/posts/987654321.json",
    "_misskey_quote": "https://example.com/posts/987654321.json",
    "quoteUri":       "https://example.com/posts/987654321.json"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All this says is "I would like permission to quote you."&lt;/p&gt;

&lt;h2 id="the-stamp"&gt;&lt;a href="https://shkspr.mobi/blog/2025/10/getting-started-with-mastodons-quote-posts-technical-implementation-details-for-servers/#the-stamp"&gt;The Stamp&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;The quoted server needs to approve this quote. First, it generates a "stamp".&lt;/p&gt;

&lt;p&gt;This is a file which lives on the quoted server. It is proof that the quote is allowed. If it is deleted, the quote permission is revoked. When the &lt;a href="https://socialhub.activitypub.rocks/t/quote-post-implementation-issues/8032/2?u=eden_t"&gt;stamp's ID is requested the stamp &lt;em&gt;must&lt;/em&gt; be returned&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-JSON"&gt;{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "gts": "https://gotosocial.org/ns#",
      "QuoteAuthorization": {
        "@id": "https://w3id.org/fep/044f#QuoteAuthorization",
        "@type": "@id"
      },
      "interactingObject": {
        "@id": "gts:interactingObject"
      },
      "interactionTarget": {
        "@id": "gts:interactionTarget"
      }
    }
  ],
  "type": "QuoteAuthorization",
  "id":                "https://example.com/quote-987654321.json",
  "attributedTo":      "https://example.com/users/username",
  "interactionTarget": "https://example.com/posts/987654321.json",
  "interactingObject": "https://mastodon.test/users/Edent/statuses/123456789"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If the quoted status is viewed from a different server, that server will query the stamp to make sure the share is allowed.&lt;/p&gt;

&lt;h2 id="the-accept"&gt;&lt;a href="https://shkspr.mobi/blog/2025/10/getting-started-with-mastodons-quote-posts-technical-implementation-details-for-servers/#the-accept"&gt;The Accept&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;This is the message that the quoted server sends to the quoting server. It references the request and the stamp.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-JSON"&gt;{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "QuoteRequest": "https://w3id.org/fep/044f#QuoteRequest"
    }
  ],
  "type": "Accept",
  "to":    "https://mastodon.test/users/Edent",
  "id":    "https://example.com/posts/987654321.json",
  "actor": "https://example.com/account",
  "object": {
    "type": "QuoteRequest",
    "id":         "https://mastodon.test/users/Edent/quote_requests/1234-5678-9101",
    "actor":      "https://mastodon.test/users/Edent",
    "instrument": "https://mastodon.test/users/Edent/statuses/123456789",
    "object":     "https://example.com/posts/987654321.json"
  },
  "result": "https://example.com/quote-987654321.json"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The "result" &lt;em&gt;must&lt;/em&gt; be the same as the stamp's URl.&lt;/p&gt;

&lt;h2 id="and-then"&gt;&lt;a href="https://shkspr.mobi/blog/2025/10/getting-started-with-mastodons-quote-posts-technical-implementation-details-for-servers/#and-then"&gt;And then?&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;You can follow and quote &lt;a href="https://colours.bots.edent.tel/"&gt;@colours@colours.bots.edent.tel&lt;/a&gt; on your favourite Fediverse platform.&lt;/p&gt;

&lt;p&gt;I've written an ActivityPub server in a single file which is designed to teach you have the protocol works. Have a play with &lt;a href="https://gitlab.com/edent/activity-bot"&gt;ActivityBot&lt;/a&gt;.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=63527&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2025/10/getting-started-with-mastodons-quote-posts-technical-implementation-details-for-servers/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Presenting ActivityBot at FOSDEM]]></title>
		<link>https://shkspr.mobi/blog/2025/02/presenting-activitybot-at-fosdem/</link>
					<comments>https://shkspr.mobi/blog/2025/02/presenting-activitybot-at-fosdem/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Sun, 09 Feb 2025 12:34:17 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[FOSDEM]]></category><category><![CDATA[presentation]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=58000</guid>

					<description><![CDATA[Because I&#039;m an optimist, I submitted a few talks to FOSDEM in the hope one might be accepted.  Because I&#039;m lucky, I got two speaking slots. Because I&#039;m an idiot, I decided to do both talks. On the same day. An hour apart. On opposite ends of the venue.  Fool!  My first talk was at the Social Web Birds-of-a-Feather session. I told people about my ActivityBot social networking server and how I…]]></description>
										<content:encoded>&lt;p&gt;Because I'm an optimist, I submitted a few talks to FOSDEM in the hope one might be accepted.  Because I'm lucky, I got two speaking slots. Because I'm an idiot, I decided to do both talks. On the same day. An hour apart. On opposite ends of the venue.&lt;/p&gt;

&lt;p&gt;Fool!&lt;/p&gt;

&lt;p&gt;My first talk was at &lt;a href="https://fosdem.org/2025/schedule/event/fosdem-2025-6617-social-web-bof/"&gt;the Social Web Birds-of-a-Feather&lt;/a&gt; session. I told people about my ActivityBot social networking server and how I built it into a single file. In the spirit of minimalism, I only had 8 minutes to present.  Time for a speed-run!&lt;/p&gt;

&lt;p&gt;Sadly / Luckily there's no audio or video of the session (if you have some, let me know) so you'll have to make do with some slides. Speaker notes are included - read them rapidly for the full effect!&lt;/p&gt;

&lt;h2 id="i-built-an-activitypub-bot-server-in-64kb-of-php-sorry"&gt;&lt;a href="https://shkspr.mobi/blog/2025/02/presenting-activitybot-at-fosdem/#i-built-an-activitypub-bot-server-in-64kb-of-php-sorry"&gt;I built an ActivityPub bot server in 64KB of PHP. Sorry!&lt;/a&gt;&lt;/h2&gt;

&lt;iframe src="https://docs.google.com/presentation/d/e/2PACX-1vQXHq1eURXSUSoMmNZVVQ07HMEUxe39G28HJZGIgKxPJo5Xkhei4BOVTshCXn2ZPi2n4kRvIqebERwr/embed?start=false&amp;amp;loop=false&amp;amp;delayms=30000" frameborder="0" width="1920" height="1080" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true" style="height: auto; aspect-ratio: 16/9;"&gt;&lt;/iframe&gt;

&lt;h2 id="feedback-and-photos"&gt;&lt;a href="https://shkspr.mobi/blog/2025/02/presenting-activitybot-at-fosdem/#feedback-and-photos"&gt;Feedback and Photos&lt;/a&gt;&lt;/h2&gt;

&lt;blockquote class="social-embed" id="social-embed-113934050377736127" lang="en" itemscope="" itemtype="https://schema.org/SocialMediaPosting"&gt;&lt;header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"&gt;&lt;a href="https://hachyderm.io/@ioana" class="social-embed-user" itemprop="url"&gt;&lt;img class="social-embed-avatar" src="https://media.hachyderm.io/accounts/avatars/109/811/317/559/644/637/original/b2d24e089597a462.jpg" alt="" itemprop="image"&gt;&lt;div class="social-embed-user-names"&gt;&lt;p class="social-embed-user-names-name" itemprop="name"&gt;@ioana@hachyderm.io&lt;/p&gt;Ioana&lt;/div&gt;&lt;/a&gt;&lt;img class="social-embed-logo" alt="Mastodon" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-label='Mastodon' role='img' viewBox='0 0 512 512' fill='%23fff'%3E%3Cpath d='m0 0H512V512H0'/%3E%3ClinearGradient id='a' y2='1'%3E%3Cstop offset='0' stop-color='%236364ff'/%3E%3Cstop offset='1' stop-color='%23563acc'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23a)' d='M317 381q-124 28-123-39 69 15 149 2 67-13 72-80 3-101-3-116-19-49-72-58-98-10-162 0-56 10-75 58-12 31-3 147 3 32 9 53 13 46 70 69 83 23 138-9'/%3E%3Cpath d='M360 293h-36v-93q-1-26-29-23-20 3-20 34v47h-36v-47q0-31-20-34-30-3-30 28v88h-36v-91q1-51 44-60 33-5 51 21l9 15 9-15q16-26 51-21 43 9 43 60'/%3E%3C/svg%3E"&gt;&lt;/header&gt;&lt;section class="social-embed-text" itemprop="articleBody"&gt;&lt;p&gt;Best start for the Social BoF with &lt;span class="h-card" translate="no"&gt;&lt;a href="https://mastodon.social/@Edent" class="u-url mention"&gt;@&lt;span&gt;Edent&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; talk! &lt;br&gt;&lt;a href="https://hachyderm.io/tags/Fosdem" class="mention hashtag" rel="tag"&gt;#&lt;span&gt;Fosdem&lt;/span&gt;&lt;/a&gt; &lt;a href="https://hachyderm.io/tags/fosdem2025" class="mention hashtag" rel="tag"&gt;#&lt;span&gt;fosdem2025&lt;/span&gt;&lt;/a&gt; &lt;a href="https://hachyderm.io/tags/fosdem25" class="mention hashtag" rel="tag"&gt;#&lt;span&gt;fosdem25&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="social-embed-media-grid"&gt;&lt;a href="https://media.hachyderm.io/media_attachments/files/113/934/048/014/498/003/original/701d5a1938889538.jpg" class="social-embed-media-link"&gt;&lt;img class="social-embed-media" alt="" src="data:image/webp;base64,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"&gt;&lt;/a&gt;&lt;a href="https://media.hachyderm.io/media_attachments/files/113/934/048/999/136/306/original/552b87a01b48404e.jpg" class="social-embed-media-link"&gt;&lt;img class="social-embed-media" alt="" src="data:image/webp;base64,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"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/section&gt;&lt;hr class="social-embed-hr"&gt;&lt;footer class="social-embed-footer"&gt;&lt;a href="https://hachyderm.io/@ioana/113934050377736127"&gt;&lt;span aria-label="9 likes" class="social-embed-meta"&gt;❤️ 9&lt;/span&gt;&lt;span aria-label="1 replies" class="social-embed-meta"&gt;💬 1&lt;/span&gt;&lt;span aria-label="2 reposts" class="social-embed-meta"&gt;🔁 2&lt;/span&gt;&lt;time datetime="2025-02-02T11:27:21.758Z" itemprop="datePublished"&gt;11:27 - Sun 02 February 2025&lt;/time&gt;&lt;/a&gt;&lt;/footer&gt;&lt;/blockquote&gt;

&lt;blockquote class="social-embed" id="social-embed-113934150415658493" lang="en" itemscope="" itemtype="https://schema.org/SocialMediaPosting"&gt;&lt;header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"&gt;&lt;a href="https://hachyderm.io/@ioana" class="social-embed-user" itemprop="url"&gt;&lt;img class="social-embed-avatar" src="https://media.hachyderm.io/accounts/avatars/109/811/317/559/644/637/original/b2d24e089597a462.jpg" alt="" itemprop="image"&gt;&lt;div class="social-embed-user-names"&gt;&lt;p class="social-embed-user-names-name" itemprop="name"&gt;@ioana@hachyderm.io&lt;/p&gt;Ioana&lt;/div&gt;&lt;/a&gt;&lt;img class="social-embed-logo" alt="Mastodon" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-label='Mastodon' role='img' viewBox='0 0 512 512' fill='%23fff'%3E%3Cpath d='m0 0H512V512H0'/%3E%3ClinearGradient id='a' y2='1'%3E%3Cstop offset='0' stop-color='%236364ff'/%3E%3Cstop offset='1' stop-color='%23563acc'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23a)' d='M317 381q-124 28-123-39 69 15 149 2 67-13 72-80 3-101-3-116-19-49-72-58-98-10-162 0-56 10-75 58-12 31-3 147 3 32 9 53 13 46 70 69 83 23 138-9'/%3E%3Cpath d='M360 293h-36v-93q-1-26-29-23-20 3-20 34v47h-36v-47q0-31-20-34-30-3-30 28v88h-36v-91q1-51 44-60 33-5 51 21l9 15 9-15q16-26 51-21 43 9 43 60'/%3E%3C/svg%3E"&gt;&lt;/header&gt;&lt;section class="social-embed-text" itemprop="articleBody"&gt;&lt;p&gt;&lt;span class="h-card" translate="no"&gt;&lt;a href="https://mastodon.social/@Edent" class="u-url mention"&gt;@&lt;span&gt;Edent&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;Loved the &lt;br&gt;- I do not have time for applause. Please don't clap 😂&lt;br&gt;- I do not have time for reactions&lt;br&gt;- I do not have time for questions &lt;/p&gt;&lt;p&gt;PS for those reading this, it was fun and nice &lt;br&gt;😅&lt;/p&gt;&lt;div class="social-embed-media-grid"&gt;&lt;/div&gt;&lt;/section&gt;&lt;hr class="social-embed-hr"&gt;&lt;footer class="social-embed-footer"&gt;&lt;a href="https://hachyderm.io/@ioana/113934150415658493"&gt;&lt;span aria-label="1 likes" class="social-embed-meta"&gt;❤️ 1&lt;/span&gt;&lt;span aria-label="0 replies" class="social-embed-meta"&gt;💬 0&lt;/span&gt;&lt;span aria-label="0 reposts" class="social-embed-meta"&gt;🔁 0&lt;/span&gt;&lt;time datetime="2025-02-02T11:52:48.208Z" itemprop="datePublished"&gt;11:52 - Sun 02 February 2025&lt;/time&gt;&lt;/a&gt;&lt;/footer&gt;&lt;/blockquote&gt;

&lt;blockquote class="social-embed" id="social-embed-113933997287100597" lang="en" itemscope="" itemtype="https://schema.org/SocialMediaPosting"&gt;&lt;header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"&gt;&lt;a href="https://social.wake.st/@liaizon" class="social-embed-user" itemprop="url"&gt;&lt;img class="social-embed-avatar" src="https://files.mastodon.social/cache/accounts/avatars/000/711/648/original/8920ce43fe0d7a74.png" alt="" itemprop="image"&gt;&lt;div class="social-embed-user-names"&gt;&lt;p class="social-embed-user-names-name" itemprop="name"&gt;@liaizon@social.wake.st&lt;/p&gt;wakest ⁂&lt;/div&gt;&lt;/a&gt;&lt;img class="social-embed-logo" alt="Mastodon" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-label='Mastodon' role='img' viewBox='0 0 512 512' fill='%23fff'%3E%3Cpath d='m0 0H512V512H0'/%3E%3ClinearGradient id='a' y2='1'%3E%3Cstop offset='0' stop-color='%236364ff'/%3E%3Cstop offset='1' stop-color='%23563acc'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23a)' d='M317 381q-124 28-123-39 69 15 149 2 67-13 72-80 3-101-3-116-19-49-72-58-98-10-162 0-56 10-75 58-12 31-3 147 3 32 9 53 13 46 70 69 83 23 138-9'/%3E%3Cpath d='M360 293h-36v-93q-1-26-29-23-20 3-20 34v47h-36v-47q0-31-20-34-30-3-30 28v88h-36v-91q1-51 44-60 33-5 51 21l9 15 9-15q16-26 51-21 43 9 43 60'/%3E%3C/svg%3E"&gt;&lt;/header&gt;&lt;section class="social-embed-text" itemprop="articleBody"&gt;&lt;p&gt;First thing this morning at Social Web &lt;a href="https://social.wake.st/tags/BOF" class="mention hashtag" rel="nofollow noopener" target="_blank"&gt;#&lt;span&gt;BOF&lt;/span&gt;&lt;/a&gt; we have &lt;span class="h-card" translate="no"&gt;&lt;a href="https://mastodon.social/@Edent" class="u-url mention" rel="nofollow noopener" target="_blank"&gt;@&lt;span&gt;Edent&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; presenting their single file php &lt;a href="https://social.wake.st/tags/ActivityPub" class="mention hashtag" rel="nofollow noopener" target="_blank"&gt;#&lt;span&gt;ActivityPub&lt;/span&gt;&lt;/a&gt; project that is entirely contained in one slide!&lt;/p&gt;&lt;div class="social-embed-media-grid"&gt;&lt;a href="https://files.mastodon.social/cache/media_attachments/files/113/933/997/248/931/154/original/22d792a494540dfa.jpg" class="social-embed-media-link"&gt;&lt;img class="social-embed-media" alt="A person stands in front of a projection screen filled with php" src="data:image/webp;base64,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"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/section&gt;&lt;hr class="social-embed-hr"&gt;&lt;footer class="social-embed-footer"&gt;&lt;a href="https://social.wake.st/@liaizon/113933997213561169"&gt;&lt;span aria-label="1 likes" class="social-embed-meta"&gt;❤️ 1&lt;/span&gt;&lt;span aria-label="6 replies" class="social-embed-meta"&gt;💬 6&lt;/span&gt;&lt;span aria-label="11 reposts" class="social-embed-meta"&gt;🔁 11&lt;/span&gt;&lt;time datetime="2025-02-02T11:13:50.000Z" itemprop="datePublished"&gt;11:13 - Sun 02 February 2025&lt;/time&gt;&lt;/a&gt;&lt;/footer&gt;&lt;/blockquote&gt;

&lt;blockquote class="social-embed" id="social-embed-113933987857350668" lang="de" itemscope="" itemtype="https://schema.org/SocialMediaPosting"&gt;&lt;header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"&gt;&lt;a href="https://bonn.social/@Sascha" class="social-embed-user" itemprop="url"&gt;&lt;img class="social-embed-avatar" src="https://files.mastodon.social/cache/accounts/avatars/000/082/561/original/fcd9431c3455ed84.jpg" alt="" itemprop="image"&gt;&lt;div class="social-embed-user-names"&gt;&lt;p class="social-embed-user-names-name" itemprop="name"&gt;@Sascha@bonn.social&lt;/p&gt;Sascha Foerster :bonndigital:&lt;/div&gt;&lt;/a&gt;&lt;img class="social-embed-logo" alt="Mastodon" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-label='Mastodon' role='img' viewBox='0 0 512 512' fill='%23fff'%3E%3Cpath d='m0 0H512V512H0'/%3E%3ClinearGradient id='a' y2='1'%3E%3Cstop offset='0' stop-color='%236364ff'/%3E%3Cstop offset='1' stop-color='%23563acc'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23a)' d='M317 381q-124 28-123-39 69 15 149 2 67-13 72-80 3-101-3-116-19-49-72-58-98-10-162 0-56 10-75 58-12 31-3 147 3 32 9 53 13 46 70 69 83 23 138-9'/%3E%3Cpath d='M360 293h-36v-93q-1-26-29-23-20 3-20 34v47h-36v-47q0-31-20-34-30-3-30 28v88h-36v-91q1-51 44-60 33-5 51 21l9 15 9-15q16-26 51-21 43 9 43 60'/%3E%3C/svg%3E"&gt;&lt;/header&gt;&lt;section class="social-embed-text" itemprop="articleBody"&gt;&lt;p&gt;Wir lachen so viel, wir haben keine Zeit zum Posten. Fantastischer Vortrag über den kleinsten ActivityPub-Bot possible, made by &lt;span class="h-card" translate="no"&gt;&lt;a href="https://mastodon.social/@Edent" class="u-url mention" rel="nofollow noopener" target="_blank"&gt;@&lt;span&gt;Edent&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;.&lt;/p&gt;&lt;div class="social-embed-media-grid"&gt;&lt;a href="https://files.mastodon.social/cache/media_attachments/files/113/933/987/805/710/279/original/a06acab6c90a6d4b.jpg" class="social-embed-media-link"&gt;&lt;img class="social-embed-media" alt="" src="data:image/webp;base64,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"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/section&gt;&lt;hr class="social-embed-hr"&gt;&lt;footer class="social-embed-footer"&gt;&lt;a href="https://bonn.social/@Sascha/113933987520310093"&gt;&lt;span aria-label="1 likes" class="social-embed-meta"&gt;❤️ 1&lt;/span&gt;&lt;span aria-label="1 replies" class="social-embed-meta"&gt;💬 1&lt;/span&gt;&lt;span aria-label="0 reposts" class="social-embed-meta"&gt;🔁 0&lt;/span&gt;&lt;time datetime="2025-02-02T11:11:22.000Z" itemprop="datePublished"&gt;11:11 - Sun 02 February 2025&lt;/time&gt;&lt;/a&gt;&lt;/footer&gt;&lt;/blockquote&gt;

&lt;blockquote class="social-embed" id="social-embed-113935060594615512" lang="en" itemscope="" itemtype="https://schema.org/SocialMediaPosting"&gt;&lt;header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"&gt;&lt;a href="https://mastodon.social/@_elena" class="social-embed-user" itemprop="url"&gt;&lt;img class="social-embed-avatar" src="https://files.mastodon.social/accounts/avatars/109/246/411/862/197/824/original/16b4d03c1b5adeaf.jpeg" alt="" itemprop="image"&gt;&lt;div class="social-embed-user-names"&gt;&lt;p class="social-embed-user-names-name" itemprop="name"&gt;@_elena@mastodon.social&lt;/p&gt;Elena Rossini ⁂&lt;/div&gt;&lt;/a&gt;&lt;img class="social-embed-logo" alt="Mastodon" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-label='Mastodon' role='img' viewBox='0 0 512 512' fill='%23fff'%3E%3Cpath d='m0 0H512V512H0'/%3E%3ClinearGradient id='a' y2='1'%3E%3Cstop offset='0' stop-color='%236364ff'/%3E%3Cstop offset='1' stop-color='%23563acc'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23a)' d='M317 381q-124 28-123-39 69 15 149 2 67-13 72-80 3-101-3-116-19-49-72-58-98-10-162 0-56 10-75 58-12 31-3 147 3 32 9 53 13 46 70 69 83 23 138-9'/%3E%3Cpath d='M360 293h-36v-93q-1-26-29-23-20 3-20 34v47h-36v-47q0-31-20-34-30-3-30 28v88h-36v-91q1-51 44-60 33-5 51 21l9 15 9-15q16-26 51-21 43 9 43 60'/%3E%3C/svg%3E"&gt;&lt;/header&gt;&lt;section class="social-embed-text" itemprop="articleBody"&gt;&lt;p&gt;&lt;span class="h-card" translate="no"&gt;&lt;a href="https://mastodon.social/@Edent" class="u-url mention"&gt;@&lt;span&gt;Edent&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; your BOF talk was absolutely brilliant Terence! 👏👏👏👏👏&lt;/p&gt;&lt;div class="social-embed-media-grid"&gt;&lt;/div&gt;&lt;/section&gt;&lt;hr class="social-embed-hr"&gt;&lt;footer class="social-embed-footer"&gt;&lt;a href="https://mastodon.social/@_elena/113935060594615512"&gt;&lt;span aria-label="0 likes" class="social-embed-meta"&gt;❤️ 0&lt;/span&gt;&lt;span aria-label="1 replies" class="social-embed-meta"&gt;💬 1&lt;/span&gt;&lt;span aria-label="0 reposts" class="social-embed-meta"&gt;🔁 0&lt;/span&gt;&lt;time datetime="2025-02-02T15:44:16.438Z" itemprop="datePublished"&gt;15:44 - Sun 02 February 2025&lt;/time&gt;&lt;/a&gt;&lt;/footer&gt;&lt;/blockquote&gt;

&lt;blockquote class="social-embed" id="social-embed-113976199068587690" lang="en" itemscope="" itemtype="https://schema.org/SocialMediaPosting"&gt;&lt;header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"&gt;&lt;a href="https://typo.social/@redmer" class="social-embed-user" itemprop="url"&gt;&lt;img class="social-embed-avatar" src="https://files.mastodon.social/cache/accounts/avatars/109/364/169/463/476/377/original/bd3d155574eaff72.jpeg" alt="" itemprop="image"&gt;&lt;div class="social-embed-user-names"&gt;&lt;p class="social-embed-user-names-name" itemprop="name"&gt;@redmer@typo.social&lt;/p&gt;Redmer&lt;/div&gt;&lt;/a&gt;&lt;img class="social-embed-logo" alt="Mastodon" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-label='Mastodon' role='img' viewBox='0 0 512 512' fill='%23fff'%3E%3Cpath d='m0 0H512V512H0'/%3E%3ClinearGradient id='a' y2='1'%3E%3Cstop offset='0' stop-color='%236364ff'/%3E%3Cstop offset='1' stop-color='%23563acc'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23a)' d='M317 381q-124 28-123-39 69 15 149 2 67-13 72-80 3-101-3-116-19-49-72-58-98-10-162 0-56 10-75 58-12 31-3 147 3 32 9 53 13 46 70 69 83 23 138-9'/%3E%3Cpath d='M360 293h-36v-93q-1-26-29-23-20 3-20 34v47h-36v-47q0-31-20-34-30-3-30 28v88h-36v-91q1-51 44-60 33-5 51 21l9 15 9-15q16-26 51-21 43 9 43 60'/%3E%3C/svg%3E"&gt;&lt;/header&gt;&lt;section class="social-embed-text" itemprop="articleBody"&gt;&lt;p&gt;&lt;span class="h-card" translate="no"&gt;&lt;a href="https://mastodon.social/@Edent" class="u-url mention" rel="nofollow noopener" target="_blank"&gt;@&lt;span&gt;Edent&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; I have a photo!&lt;/p&gt;&lt;div class="social-embed-media-grid"&gt;&lt;a href="https://files.mastodon.social/cache/media_attachments/files/113/976/199/005/479/268/original/49bd02b853fdc39c.jpeg" class="social-embed-media-link"&gt;&lt;img class="social-embed-media" alt="Photo of Terence Eden in a lecture room in front of a presentation. The slide says:  gitlab.com/exent/activity-bot link. Requires: Docker, Node, MongoDB, Wayland, Glados, Rust, LLM, Adobe Creative Cloud, Maven, React, HAL9000 (absolutely NONE of these!)" src="data:image/webp;base64,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"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/section&gt;&lt;hr class="social-embed-hr"&gt;&lt;footer class="social-embed-footer"&gt;&lt;a href="https://typo.social/@redmer/113976198958422873"&gt;&lt;span aria-label="1 likes" class="social-embed-meta"&gt;❤️ 1&lt;/span&gt;&lt;span aria-label="1 replies" class="social-embed-meta"&gt;💬 1&lt;/span&gt;&lt;span aria-label="0 reposts" class="social-embed-meta"&gt;🔁 0&lt;/span&gt;&lt;time datetime="2025-02-09T22:06:18.000Z" itemprop="datePublished"&gt;22:06 - Sun 09 February 2025&lt;/time&gt;&lt;/a&gt;&lt;/footer&gt;&lt;/blockquote&gt;

&lt;blockquote class="social-embed" id="social-embed-113978387603149933" lang="en" itemscope="" itemtype="https://schema.org/SocialMediaPosting"&gt;&lt;header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"&gt;&lt;a href="https://fosstodon.org/@mala" class="social-embed-user" itemprop="url"&gt;&lt;img class="social-embed-avatar" src="https://files.mastodon.social/cache/accounts/avatars/108/344/944/461/785/366/original/eb3c7e69b284be82.jpeg" alt="" itemprop="image"&gt;&lt;div class="social-embed-user-names"&gt;&lt;p class="social-embed-user-names-name" itemprop="name"&gt;@mala@fosstodon.org&lt;/p&gt;Davide Eynard (+mala)&lt;/div&gt;&lt;/a&gt;&lt;img class="social-embed-logo" alt="Mastodon" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-label='Mastodon' role='img' viewBox='0 0 512 512' fill='%23fff'%3E%3Cpath d='m0 0H512V512H0'/%3E%3ClinearGradient id='a' y2='1'%3E%3Cstop offset='0' stop-color='%236364ff'/%3E%3Cstop offset='1' stop-color='%23563acc'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23a)' d='M317 381q-124 28-123-39 69 15 149 2 67-13 72-80 3-101-3-116-19-49-72-58-98-10-162 0-56 10-75 58-12 31-3 147 3 32 9 53 13 46 70 69 83 23 138-9'/%3E%3Cpath d='M360 293h-36v-93q-1-26-29-23-20 3-20 34v47h-36v-47q0-31-20-34-30-3-30 28v88h-36v-91q1-51 44-60 33-5 51 21l9 15 9-15q16-26 51-21 43 9 43 60'/%3E%3C/svg%3E"&gt;&lt;/header&gt;&lt;section class="social-embed-text" itemprop="articleBody"&gt;&lt;p&gt;&lt;span class="h-card" translate="no"&gt;&lt;a href="https://mastodon.social/@Edent" class="u-url mention" rel="nofollow noopener" target="_blank"&gt;@&lt;span&gt;Edent&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; here’s, sadly, the only photo I took - I regret not having more now and I’d love to see one of those “he is lying to you” moments again! 😂&lt;/p&gt;&lt;div class="social-embed-media-grid"&gt;&lt;a href="https://files.mastodon.social/cache/media_attachments/files/113/978/387/562/133/682/original/d4a09ed617e0002c.jpeg" class="social-embed-media-link"&gt;&lt;img class="social-embed-media" alt="A man talking in front of a presentation slide. The slide shows a “color picker” circle at the top and below it the following text:Colours BotTooting a beautiful new color every few hours.Made by @Edent@mastodon.socialFollowing: 0 | Followers: 1051This software is licensed under AGPL 3.0This site is a basic ActivityPub server designed to be a lightweight […]Terence Eden - Open Ideas Ltd" src="data:image/webp;base64,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"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/section&gt;&lt;hr class="social-embed-hr"&gt;&lt;footer class="social-embed-footer"&gt;&lt;a href="https://fosstodon.org/@mala/113978387535114301"&gt;&lt;span aria-label="1 likes" class="social-embed-meta"&gt;❤️ 1&lt;/span&gt;&lt;span aria-label="1 replies" class="social-embed-meta"&gt;💬 1&lt;/span&gt;&lt;span aria-label="0 reposts" class="social-embed-meta"&gt;🔁 0&lt;/span&gt;&lt;time datetime="2025-02-10T07:22:53.000Z" itemprop="datePublished"&gt;07:22 - Mon 10 February 2025&lt;/time&gt;&lt;/a&gt;&lt;/footer&gt;&lt;/blockquote&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=58000&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2025/02/presenting-activitybot-at-fosdem/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Introducing ActivityBot - the simplest way to build Mastodon Bots]]></title>
		<link>https://shkspr.mobi/blog/2024/11/introducing-activitybot-the-simplest-way-to-build-mastodon-bots/</link>
					<comments>https://shkspr.mobi/blog/2024/11/introducing-activitybot-the-simplest-way-to-build-mastodon-bots/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Sun, 10 Nov 2024 12:34:00 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[bot]]></category><category><![CDATA[fediverse]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=53728</guid>

					<description><![CDATA[As you may have read, BotsIn.Space is closing down, I have lots of automated bot accounts living on the Fediverse - and I want them to continue posting.  Installing and maintaining an entire Mastodon instance sounds like hard work. Paying people to host my stuff feels like putting my fate in someone else&#039;s hands.  Say… didn&#039;t I write my own ActivityPub server? Why, yes! Yes I did!  I took the c…]]></description>
										<content:encoded>&lt;p&gt;As you may have read, &lt;a href="https://muffinlabs.com/posts/2024/10/29/10-29-rip-botsin-space/"&gt;BotsIn.Space is closing down&lt;/a&gt;, I have lots of automated bot accounts living on the Fediverse - and I want them to continue posting.  Installing and maintaining an entire Mastodon instance sounds like hard work. Paying people to host my stuff feels like putting my fate in someone else's hands.&lt;/p&gt;

&lt;p&gt;Say… didn't I write &lt;a href="https://shkspr.mobi/blog/2024/03/updates-to-activitypub-in-a-single-php-file/"&gt;my own ActivityPub server&lt;/a&gt;? Why, yes! Yes I did!&lt;/p&gt;

&lt;p&gt;I took the code and stripped it down to the bare essentials. All you need to do is upload two files&lt;sup id="fnref:env"&gt;&lt;a href="https://shkspr.mobi/blog/2024/11/introducing-activitybot-the-simplest-way-to-build-mastodon-bots/#fn:env" class="footnote-ref" title="You can also upload a .env file for your configuration if you want." role="doc-noteref"&gt;0&lt;/a&gt;&lt;/sup&gt; - &lt;code&gt;index.php&lt;/code&gt; and &lt;code&gt;.htaccess&lt;/code&gt; - fill in your details, and you're done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gitlab.com/edent/activity-bot/"&gt;Get the ActivityBot source code on GitLab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There's no database, no containers, no caching. It is as simple as I could make it&lt;/p&gt;

&lt;p&gt;This bot can do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔍 Be discovered on the Fediverse&lt;/li&gt;
&lt;li&gt;👉 Be followed by other accounts&lt;/li&gt;
&lt;li&gt;🚫 Be unfollowed by accounts&lt;/li&gt;
&lt;li&gt;📩 Send messages to the Fediverse&lt;/li&gt;
&lt;li&gt;💌 Send direct messages to users&lt;/li&gt;
&lt;li&gt;🖼️ Attach an image &amp;amp; alt text to a message&lt;/li&gt;
&lt;li&gt;🕸️ Autolink URls, hashtags, and @ mentions&lt;/li&gt;
&lt;li&gt;🚚 Move followers from an old account&lt;/li&gt;
&lt;li&gt;🔏 Verify cryptographic signatures&lt;/li&gt;
&lt;li&gt;🪵 Log sent messages and error.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it! Here's what it &lt;em&gt;doesn't&lt;/em&gt; do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Receive messages (other than follows and unfollows)&lt;/li&gt;
&lt;li&gt;❌ Thread replies&lt;/li&gt;
&lt;li&gt;❌ Delete or update a post&lt;/li&gt;
&lt;li&gt;❌ Create Polls&lt;/li&gt;
&lt;li&gt;❌ Attach multiple images&lt;/li&gt;
&lt;li&gt;❌ Set focus point for images&lt;/li&gt;
&lt;li&gt;❌ Set sensitivity for images / blur&lt;/li&gt;
&lt;li&gt;❌ Set "Content Warning"&lt;/li&gt;
&lt;li&gt;❌ Accurate support for converting user's text to HTML&lt;/li&gt;
&lt;li&gt;❌ Cannot be discovered by Lemmy instances&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Grab a subdomain (don't buy a whole new domain name!) and &lt;a href="https://gitlab.com/edent/activity-bot/"&gt;stick this code on it&lt;/a&gt;. You'll have an ActivityPub bot running in minutes.&lt;/p&gt;

&lt;p&gt;You can follow one of my bots &lt;code&gt;@colours@colours.bots.edent.tel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Feedback very much welcome.&lt;/p&gt;

&lt;div id="footnotes" role="doc-endnotes"&gt;
&lt;hr aria-label="Footnotes"&gt;
&lt;ol start="0"&gt;

&lt;li id="fn:env"&gt;
&lt;p&gt;You can also upload a &lt;code&gt;.env&lt;/code&gt; file for your configuration if you want.&amp;nbsp;&lt;a href="https://shkspr.mobi/blog/2024/11/introducing-activitybot-the-simplest-way-to-build-mastodon-bots/#fnref:env" class="footnote-backref" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;
&lt;/div&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=53728&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/11/introducing-activitybot-the-simplest-way-to-build-mastodon-bots/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Social Media Blocking Has Always Been A Lie]]></title>
		<link>https://shkspr.mobi/blog/2024/09/social-media-blocking-has-always-been-a-lie/</link>
					<comments>https://shkspr.mobi/blog/2024/09/social-media-blocking-has-always-been-a-lie/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Tue, 24 Sep 2024 11:34:48 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[BlueSky]]></category><category><![CDATA[mastodon]]></category><category><![CDATA[Social Media]]></category><category><![CDATA[twitter]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=53274</guid>

					<description><![CDATA[What does it mean to block someone on a social media site?  Way back in the mists of time, we dealt with trolls on Usenet with the almighty PLONK - PLaced On Newsgroup Killfile.  It meant your newsreader never downloaded their posts. They could rant at you all day long, and you&#039;d never hear from them.  It&#039;s what we would nowadays call &#34;Mute&#34;.  But, whether you&#039;re on Usenet or a modern social…]]></description>
										<content:encoded>&lt;p&gt;What does it mean to block someone on a social media site?&lt;/p&gt;

&lt;p&gt;Way back in the mists of time, we dealt with trolls on Usenet with the almighty PLONK - &lt;a href="https://members.newsdemon.com/what-is-plonk.php"&gt;PLaced On Newsgroup Killfile&lt;/a&gt;.  It meant your newsreader never downloaded their posts. They could rant at you all day long, and you'd never hear from them.  It's what we would nowadays call "Mute".&lt;/p&gt;

&lt;p&gt;But, whether you're on Usenet or a modern social network, muting someone doesn't actually stop them replying to you. The miscreant can still see your posts, interact with them, quote them. And everyone on that service can see their abuse. Perhaps they will also join in?&lt;/p&gt;

&lt;p&gt;Most modern social networks now have the concept of "Block". When Alice blocks Bob, it means Bob cannot see Alice's posts.  The service doesn't deliver her content to him. If he goes looking, he can't find it. She is invisible to him.&lt;/p&gt;

&lt;p&gt;Except, of course, that's a lie. If Bob logs out of his account, he can see Alice's public content. If he logs into an alternative account, he isn't blocked.&lt;/p&gt;

&lt;p&gt;The block is a &lt;em&gt;social signal&lt;/em&gt; backed up with mild technical restrictions.&lt;/p&gt;

&lt;p&gt;What do I mean by that? Ordinarily, you will have no idea that you have been blocked by someone. They will simply vanish from your screens.  You do not receive an alert that you've been blocked. Technical restrictions mean you won't see their posts, nor replies to them.  The only way you might know is if you deliberately look for the person blocking you.&lt;/p&gt;

&lt;p&gt;Seeing that you have been blocked is a "social signal". It lets you know that your behaviour was unwanted, or that your contributions weren't valued, or that someone just doesn't like you.  For most people, that sort of chastisement probably induces a little shame or grief.  For others, it is enraging.&lt;/p&gt;

&lt;p&gt;Again, it isn't impossible for a blocked user to see content - but technical restrictions means it takes &lt;em&gt;effort&lt;/em&gt;.  And, it turns out, for all but the most obsessive abusers - a mild bit of UI friction is all that it takes for them to stop.&lt;/p&gt;

&lt;p&gt;On a centralised social media platform, like Twitter and Facebook, your blocks are private. The only people who know you have blocked Taylor Swift are you, the platform, and T-Swizzle herself.&lt;/p&gt;

&lt;p&gt;On decentralised social media platforms, it is more complicated.&lt;/p&gt;

&lt;p&gt;Mastodon / ActivityPub lets you block a user. In doing so, you have to tell that user's server that you don't want them seeing your messages. That means your server knows about the block, their server know, and the user knows. But, crucially, there's nothing to stop a malicious server ignoring your wishes.  While your server can mute all the interactions from them, there are only &lt;a href="https://fedi.tips/authorized-fetch/"&gt;weak technological restrictions on their behaviour&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;BlueSky / AT Protocol takes a different (and more worrying) approach. BlueSky tells &lt;em&gt;everyone&lt;/em&gt; about your blocks. If Alice blocks Bob - the system lets everyone know. This means that if Bob starts replying to your posts, other clients will know to ignore his interactions with you. I've written more &lt;a href="https://bsky.app/profile/edent.tel/post/3l4rjxx32br2j"&gt;about the dangers of public blocklists over on BSky&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But, crucially, &lt;strong&gt;none of these systems actually block users&lt;/strong&gt;.  This isn't like that &lt;a href="https://black-mirror.fandom.com/wiki/White_Christmas"&gt;Black Mirror episode&lt;/a&gt; where people are literally blurred out from your eyeballs.&lt;/p&gt;

&lt;p&gt;In &lt;em&gt;all&lt;/em&gt; cases, a user can log out and see your public posts. They can sign in with an alternative account. And, in the case of decentralised social media, they can choose to ignore the technological restrictions you impose.&lt;/p&gt;

&lt;p&gt;Social networks have a responsibility to keep their users safe. That means having enough friction to prevent casual abuse.&lt;/p&gt;

&lt;p&gt;But blocking is &lt;em&gt;only&lt;/em&gt; a social signal.  That's all it ever has been. It is a boop on the nose with a rolled up newspaper. It is a message to tell someone that they might want to adjust their attitude.&lt;/p&gt;

&lt;p&gt;You should block - and block often. You should feel empowered to curate an environment that is safe for you. But you should also understand the limitations of the technical controls which underpin these social signals.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=53274&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/09/social-media-blocking-has-always-been-a-lie/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[No, ActivityPub votes aren't anonymous]]></title>
		<link>https://shkspr.mobi/blog/2024/09/no-activitypub-isnt-anonymous/</link>
					<comments>https://shkspr.mobi/blog/2024/09/no-activitypub-isnt-anonymous/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Mon, 09 Sep 2024 11:34:07 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[fediverse]]></category><category><![CDATA[mastodon]]></category><category><![CDATA[privacy]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=52999</guid>

					<description><![CDATA[Several years ago, I posted this poll on Twitter.  Terence Eden is on Mastodon@edentIf the recent Twitter hack had exposed they way you voted on every Twitter poll, how would you feel?(There is no suggestion that this has happened, I&#039;m just curious about people&#039;s relationships to voting and privacy.)Meh. So what?: (167)167Hmph. That&#039;s annoying.: (68)68Umm… This could be bad!: (32)32Delete account …]]></description>
										<content:encoded>&lt;p&gt;Several years ago, I posted this poll on Twitter.&lt;/p&gt;

&lt;blockquote class="social-embed" id="social-embed-1286178187937042432" lang="en" itemscope="" itemtype="https://schema.org/SocialMediaPosting"&gt;&lt;header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"&gt;&lt;a href="https://twitter.com/edent" class="social-embed-user" itemprop="url"&gt;&lt;img class="social-embed-avatar social-embed-avatar-circle" src="data:image/webp;base64,UklGRkgBAABXRUJQVlA4IDwBAACQCACdASowADAAPrVQn0ynJCKiJyto4BaJaQAIIsx4Au9dhDqVA1i1RoRTO7nbdyy03nM5FhvV62goUj37tuxqpfpPeTBZvrJ78w0qAAD+/hVyFHvYXIrMCjny0z7wqsB9/QE08xls/AQdXJFX0adG9lISsm6kV96J5FINBFXzHwfzMCr4N6r3z5/Aa/wfEoVGX3H976she3jyS8RqJv7Jw7bOxoTSPlu4gNbfXYZ9TnbdQ0MNnMObyaRQLIu556jIj03zfJrVgqRM8GPwRoWb1M9AfzFe6Mtg13uEIqrTHmiuBpH+bTVB5EEQ3uby0C//XOAPJOFv4QV8RZDPQd517Khyba8Jlr97j2kIBJD9K3mbOHSHiQDasj6Y3forATbIg4QZHxWnCeqqMkVYfUAivuL0L/68mMnagAAA" alt="" itemprop="image"&gt;&lt;div class="social-embed-user-names"&gt;&lt;p class="social-embed-user-names-name" itemprop="name"&gt;Terence Eden is on Mastodon&lt;/p&gt;@edent&lt;/div&gt;&lt;/a&gt;&lt;img class="social-embed-logo" alt="Twitter" src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%0Aaria-label%3D%22Twitter%22%20role%3D%22img%22%0AviewBox%3D%220%200%20512%20512%22%3E%3Cpath%0Ad%3D%22m0%200H512V512H0%22%0Afill%3D%22%23fff%22%2F%3E%3Cpath%20fill%3D%22%231d9bf0%22%20d%3D%22m458%20140q-23%2010-45%2012%2025-15%2034-43-24%2014-50%2019a79%2079%200%2000-135%2072q-101-7-163-83a80%2080%200%200024%20106q-17%200-36-10s-3%2062%2064%2079q-19%205-36%201s15%2053%2074%2055q-50%2040-117%2033a224%20224%200%2000346-200q23-16%2040-41%22%2F%3E%3C%2Fsvg%3E"&gt;&lt;/header&gt;&lt;section class="social-embed-text" itemprop="articleBody"&gt;If the recent Twitter hack had exposed they way you voted on every Twitter poll, how would you feel?&lt;br&gt;&lt;br&gt;(There is no suggestion that this has happened, I'm just curious about people's relationships to voting and privacy.)&lt;hr class="social-embed-hr"&gt;&lt;label for="poll_1_count"&gt;Meh. So what?: (167)&lt;/label&gt;&lt;br&gt;&lt;meter class="social-embed-meter" id="poll_1_count" min="0" max="100" low="33" high="66" value="60.7"&gt;167&lt;/meter&gt;&lt;br&gt;&lt;label for="poll_2_count"&gt;Hmph. That's annoying.: (68)&lt;/label&gt;&lt;br&gt;&lt;meter class="social-embed-meter" id="poll_2_count" min="0" max="100" low="33" high="66" value="24.7"&gt;68&lt;/meter&gt;&lt;br&gt;&lt;label for="poll_3_count"&gt;Umm… This could be bad!: (32)&lt;/label&gt;&lt;br&gt;&lt;meter class="social-embed-meter" id="poll_3_count" min="0" max="100" low="33" high="66" value="11.6"&gt;32&lt;/meter&gt;&lt;br&gt;&lt;label for="poll_4_count"&gt;Delete account &amp;amp; run away: (8)&lt;/label&gt;&lt;br&gt;&lt;meter class="social-embed-meter" id="poll_4_count" min="0" max="100" low="33" high="66" value="2.9"&gt;8&lt;/meter&gt;&lt;/section&gt;&lt;hr class="social-embed-hr"&gt;&lt;footer class="social-embed-footer"&gt;&lt;a href="https://twitter.com/edent/status/1286178187937042432"&gt;&lt;span aria-label="0 likes" class="social-embed-meta"&gt;❤️ 0&lt;/span&gt;&lt;span aria-label="8 replies" class="social-embed-meta"&gt;💬 8&lt;/span&gt;&lt;span aria-label="0 reposts" class="social-embed-meta"&gt;🔁 0&lt;/span&gt;&lt;time datetime="2020-07-23T05:55:50.000Z" itemprop="datePublished"&gt;05:55 - Thu 23 July 2020&lt;/time&gt;&lt;/a&gt;&lt;/footer&gt;&lt;/blockquote&gt;

&lt;p&gt;Most of the tech world that I interact with has moved to Mastodon and other ActivityPub-based social networks.  Decentralised social media is &lt;em&gt;great&lt;/em&gt;. It allows you to be fully in control of what you post, what you see, and how you interact with others.&lt;/p&gt;

&lt;p&gt;Of course, there are downsides. No centralised authorities means verification is difficult. Abuse (of all sorts) can only be dealt with in a piecemeal fashion. And anonymity takes a bit of a nosedive.&lt;/p&gt;

&lt;p&gt;When you block or mute someone, that information &lt;a href="https://shkspr.mobi/blog/2023/07/fediverse-account-portability-and-blocking/"&gt;might leak to the offending user&lt;/a&gt;. By its nature, you need to send a message to someone else's server in order to interact with them.&lt;/p&gt;

&lt;p&gt;So what about polls on the Fediverse?  This poll, for example, is gathering sensitive personal information.&lt;/p&gt;

&lt;blockquote class="social-embed" id="social-embed-113079948257450773" lang="en" itemscope="" itemtype="https://schema.org/SocialMediaPosting"&gt;&lt;header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"&gt;&lt;a href="https://blackrock.city/@farooqkz" class="social-embed-user" itemprop="url"&gt;&lt;img class="social-embed-avatar" src="https://files.mastodon.social/cache/accounts/avatars/110/487/620/471/518/769/original/8e8c3e9b9b7b122e.png" alt="" itemprop="image"&gt;&lt;div class="social-embed-user-names"&gt;&lt;p class="social-embed-user-names-name" itemprop="name"&gt;@farooqkz@blackrock.city&lt;/p&gt;Farooq Karimi Zadeh&lt;/div&gt;&lt;/a&gt;&lt;img class="social-embed-logo" alt="Mastodon" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-label='Mastodon' role='img' viewBox='0 0 512 512' fill='%23fff'%3E%3Cpath d='m0 0H512V512H0'/%3E%3ClinearGradient id='a' y2='1'%3E%3Cstop offset='0' stop-color='%236364ff'/%3E%3Cstop offset='1' stop-color='%23563acc'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23a)' d='M317 381q-124 28-123-39 69 15 149 2 67-13 72-80 3-101-3-116-19-49-72-58-98-10-162 0-56 10-75 58-12 31-3 147 3 32 9 53 13 46 70 69 83 23 138-9'/%3E%3Cpath d='M360 293h-36v-93q-1-26-29-23-20 3-20 34v47h-36v-47q0-31-20-34-30-3-30 28v88h-36v-91q1-51 44-60 33-5 51 21l9 15 9-15q16-26 51-21 43 9 43 60'/%3E%3C/svg%3E"&gt;&lt;/header&gt;&lt;section class="social-embed-text" itemprop="articleBody"&gt;&lt;p&gt;Let's see how many Muslims are out there on Fediverse. Are you a &lt;a href="https://blackrock.city/tags/muslim" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank"&gt;#&lt;span&gt;muslim&lt;/span&gt;&lt;/a&gt;? &lt;/p&gt;&lt;p&gt;&lt;a href="https://blackrock.city/tags/Islam" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank"&gt;#&lt;span&gt;Islam&lt;/span&gt;&lt;/a&gt; &lt;a href="https://blackrock.city/tags/Religion" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank"&gt;#&lt;span&gt;Religion&lt;/span&gt;&lt;/a&gt; &lt;a href="https://blackrock.city/tags/God" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank"&gt;#&lt;span&gt;God&lt;/span&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Please boost it so we can have more accurate statistics.&lt;/p&gt;&lt;div class="social-embed-media-grid"&gt;&lt;/div&gt;&lt;hr class="social-embed-hr"&gt;&lt;label for="poll_0"&gt;I am a Muslim: (62)&lt;/label&gt;&lt;br&gt;&lt;meter class="social-embed-meter" id="poll_0" min="0" max="100" low="33" high="66" value="1.6"&gt;62&lt;/meter&gt;&lt;br&gt;&lt;label for="poll_1"&gt;Not a Muslim: (3,696)&lt;/label&gt;&lt;br&gt;&lt;meter class="social-embed-meter" id="poll_1" min="0" max="100" low="33" high="66" value="98.4"&gt;3696&lt;/meter&gt;&lt;br&gt;&lt;/section&gt;&lt;hr class="social-embed-hr"&gt;&lt;footer class="social-embed-footer"&gt;&lt;a href="https://blackrock.city/@farooqkz/113079948160094406"&gt;&lt;span aria-label="11 likes" class="social-embed-meta"&gt;❤️ 11&lt;/span&gt;&lt;span aria-label="30 replies" class="social-embed-meta"&gt;💬 30&lt;/span&gt;&lt;span aria-label="874 reposts" class="social-embed-meta"&gt;🔁 874&lt;/span&gt;&lt;time datetime="2024-09-04T15:17:56.000Z" itemprop="datePublished"&gt;15:17 - Wed 04 September 2024&lt;/time&gt;&lt;/a&gt;&lt;/footer&gt;&lt;/blockquote&gt;

&lt;p&gt;In order to vote on the poll, your server sends a message to the poll's server saying "I am user @someone@example.com. I wish to vote for option X. Here is an HTTP signature confirming my message."&lt;/p&gt;

&lt;p&gt;Does the receiving server abide by GDPR? Who knows!&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.w3.org/TR/activitystreams-vocabulary/#questions"&gt;specification around questions&lt;/a&gt; is a little ill-defined and the &lt;a href="https://docs.joinmastodon.org/methods/polls/#vote"&gt;Mastodon documentation&lt;/a&gt; is also a bit vague. Neither of them discuss privacy.&lt;/p&gt;

&lt;p&gt;There is an &lt;a href="https://humberto.io/blog/mastodon_poll_in_activitypub/"&gt;excellent blog post by Humberto Rocha looking at Mastodon Poll in ActivityPub&lt;/a&gt;. It shows quite clearly that a vote is just a normal message which is passed onto the receiving server.&lt;/p&gt;

&lt;p&gt;Services like Mastodon won't let the poll's author see who voted for which option. But that's by convention. There's nothing technical to stop them. Indeed, I understand that &lt;a href="https://outerheaven.club/notice/Aln6q1bVGpyToIx7J2"&gt;the Akkoma social network &lt;em&gt;does&lt;/em&gt; show users how users voted&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Of course, on a centralised service like Facebook or Twitter your vote is still recorded somewhere. It can be subpoenaed or looked at by unscrupulous engineers.&lt;/p&gt;

&lt;p&gt;Privacy is, of course, a social construct. In some communities it might be sensible to have all votes on the public record. In others, it could be deadly.  Some countries have laws mandating strong privacy protections, others less so.&lt;/p&gt;

&lt;p&gt;Conduct yourself with that in mind!&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=52999&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/09/no-activitypub-isnt-anonymous/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Who can reply?]]></title>
		<link>https://shkspr.mobi/blog/2024/06/who-can-reply/</link>
					<comments>https://shkspr.mobi/blog/2024/06/who-can-reply/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Tue, 25 Jun 2024 11:34:08 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[mastodon]]></category><category><![CDATA[Social Media]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=50898</guid>

					<description><![CDATA[Vague thoughts as they enter my brainbox.  The BlueSky social network has introduced &#34;Reply Gating&#34; - it looks like this:   You can write your hot take on Taylor Swift and not be inundated by weirdos replying to you. Nifty!  This is nothing new. Twitter has it. Facebook has the concept of &#34;audiences&#34; to restrict who your post is visible to.    And, of course, blogging has this! There is a comment …]]></description>
										<content:encoded>&lt;p&gt;Vague thoughts as they enter my brainbox.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://bsky.app/"&gt;BlueSky social network&lt;/a&gt; has introduced "Reply Gating" - it looks like this:
&lt;img src="https://shkspr.mobi/blog/wp-content/uploads/2024/06/Bluesky-fs8.png" alt="Who can reply?
Choose &amp;quot;Everybody&amp;quot; or &amp;quot;Nobody&amp;quot; Or combine these options: Mentioned users, Followed users." width="720" height="472" class="aligncenter size-full wp-image-50899"&gt;&lt;/p&gt;

&lt;p&gt;You can write your hot take on Taylor Swift and &lt;em&gt;not&lt;/em&gt; be inundated by weirdos replying to you. Nifty!&lt;/p&gt;

&lt;p&gt;This is nothing new. Twitter has it. Facebook has the concept of "audiences" to restrict who your post is visible to.&lt;/p&gt;

&lt;img src="https://shkspr.mobi/blog/wp-content/uploads/2024/06/Facebook-fs8.png" alt="Facebook's audience page with options to share to select groups." width="720" height="869" class="aligncenter size-full wp-image-50900"&gt;

&lt;p&gt;And, of course, blogging has this! There is a comment form at the bottom of this page - and I moderate it. If you post something stupid, I don't have to subject my audience to your inanities. I can (and do) block users from commenting.&lt;/p&gt;

&lt;p&gt;ActivityPub doesn't have this (yet). It's much more like a public mailing list.  I can block or mute you - which stops me from seeing your abuse - but doesn't stop anyone else from seeing it.&lt;/p&gt;

&lt;p&gt;Should ActivityPub have something similar? Yeah, I reckon so. I'd like to be able to say "Anyone I know want to go to the pub tonight" and only have mutuals reply. I want to prune away spam or repetitive replies.  It would be helpful to have a conversation in public that other people can't interrupt.&lt;/p&gt;

&lt;p&gt;The UI would be complex. And the social model needs a bit of work. And there are some technical challenges around syndicating &lt;em&gt;which&lt;/em&gt; replies should be included.&lt;/p&gt;

&lt;p&gt;But, ultimately, social media should respond to the needs of its users.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=50898&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/06/who-can-reply/feed/</wfw:commentRss>
			<slash:comments>13</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[The Fediverse of Things]]></title>
		<link>https://shkspr.mobi/blog/2024/04/the-fediverse-of-things/</link>
					<comments>https://shkspr.mobi/blog/2024/04/the-fediverse-of-things/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Sun, 07 Apr 2024 11:34:31 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[fediverse]]></category><category><![CDATA[IoT]]></category><category><![CDATA[Social Networks]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=50085</guid>

					<description><![CDATA[One of the most frustrating things in modern technology is the effort spent trying to artificially restrict abundance.  Take, for example, this tale from museum-worker Aaron Cope:  I was out with a friend who worked for Twitter and I asked them whether it would be possible for the museum to “create 200,000 Twitter accounts, one for each object in the Cooper Hewitt’s collection”. My friend looked a…]]></description>
										<content:encoded>&lt;p&gt;One of the most frustrating things in modern technology is the effort spent trying to artificially restrict abundance.&lt;/p&gt;

&lt;p&gt;Take, for example, &lt;a href="https://millsfield.sfomuseum.org/blog/2024/03/12/activitypub/"&gt;this tale from museum-worker Aaron Cope&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;I was out with a friend who worked for Twitter and I asked them whether it would be possible for the museum to “create 200,000 Twitter accounts, one for each object in the Cooper Hewitt’s collection”. My friend looked at me for a moment, laughed, and then simply said: No.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;In that blog post, Aaron reveals that the San Francisco International Airport Museum is using ActivityPub to create automated social-media bot accounts for all its exhibits and, possibly, every object it hold.&lt;/p&gt;

&lt;p&gt;And why not! That would be close to impossible to do on a centralised service. But on a decentralised service under your own control, it is relatively simple.  Perhaps I only want to follow the museum's canteen, or I just want to engage with a specific artefact. The Fediverse makes that possible.&lt;/p&gt;

&lt;p&gt;This reminds me of the &lt;a href="https://www.bbc.co.uk/news/magazine-33560182"&gt;Melbourne "treemail" phenomenon&lt;/a&gt;. Every tree in the city had an email address, ostensibly so residents could email maintenance issues for a specific tree. Instead, people started interacting with the trees and sending them little love notes!&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Dearest Golden Elm Tree, I finally found you! As in I see you everyday on my way to uni, but I had no idea of what kind of tree you are. You are the most beautiful tree in the city and I love you
&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;A few weeks ago, I read about &lt;a href="https://bensmith.blog/posts/i-invented-tweeting-trains-probably"&gt;Ben Smith inventing Tweeting trains&lt;/a&gt;. With a bit of code, every train line in the UK was suddenly represented on the web in a convenient format. Well… Convenient if you were on Twitter.&lt;/p&gt;

&lt;p&gt;Museums, trees, and trains naturally brings me on to the Internet of Things. I think it is fair to say that IoT is in a bit of an odd place right now. &lt;a href="https://csa-iot.org/all-solutions/matter/"&gt;Matter&lt;/a&gt; is a confusing mishmash of standards.  Security and privacy issues dog the simplest devices. Many people don't even &lt;em&gt;want&lt;/em&gt; their toaster online!&lt;/p&gt;

&lt;p&gt;For the majority of domestic uses, people want an &lt;em&gt;Intranet&lt;/em&gt; of Things. There's little need to have your light-bulbs controlled when you're outside of WiFi range.  Similarly, it is probably a &lt;em&gt;really&lt;/em&gt; bad idea to have your &lt;a href="https://www.politico.com/news/2023/11/28/federal-government-investigating-multiple-hacks-of-us-water-utilities-00128977"&gt;hydroelectric dam connected to the Internet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Which brings me back to the Fediverse.&lt;/p&gt;

&lt;p&gt;On the one hand, it would be nice to be able to follow &lt;code&gt;@Yellow_Line@Transit_Authority.gov&lt;/code&gt; - or even &lt;code&gt;@Bus_Stop_1234@bus_company.biz&lt;/code&gt; - that would allow for hyperfocused data getting to the right people.  It seems feasible that &lt;em&gt;every&lt;/em&gt; civic object could have a Fediverse account. From the individual streetlights to the municipal sewerage system.  Perhaps people won't send love letters to overflowing drains - but a social-dashboard of your civic environment could be both practical and delightful.&lt;/p&gt;

&lt;p&gt;And, as for your &lt;em&gt;domestic&lt;/em&gt; gadgets? Why not give every room, or every light-bulb, in your home a &lt;em&gt;private&lt;/em&gt; Fediverse account? You could send a message like:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Hey @thermostat@My_Home.example.com, please set the temperature to 19°C. Thanks!
&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;That might be a bit much! But I like the idea of a &lt;em&gt;private&lt;/em&gt; social network which consists of all my IoT gadgets talking to me and each other.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=50085&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/04/the-fediverse-of-things/feed/</wfw:commentRss>
			<slash:comments>15</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[How updates work in ActivityPub / Mastodon]]></title>
		<link>https://shkspr.mobi/blog/2024/03/how-updates-work-in-activitypub-mastodon/</link>
					<comments>https://shkspr.mobi/blog/2024/03/how-updates-work-in-activitypub-mastodon/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Fri, 15 Mar 2024 12:34:28 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[mastodon]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=49894</guid>

					<description><![CDATA[I didn&#039;t realise this, so I&#039;m documenting it to stop other people making the same silly mistake that I did.  Messages in ActivityPub have two distinct ID strings.  Here&#039;s a (truncated) view of what happens when I send a new message on Mastodon:    &#38;quot;id&#38;quot;: &#38;quot;https://mastodon.social/users/Edent/statuses/1234567890/activity&#38;quot;,   &#38;quot;type&#38;quot;: &#38;quot;Create&#38;quot;,  …]]></description>
										<content:encoded>&lt;p&gt;I didn't realise this, so I'm documenting it to stop other people making the same silly mistake that I did.&lt;/p&gt;

&lt;p&gt;Messages in ActivityPub have &lt;em&gt;two distinct&lt;/em&gt; ID strings.  Here's a (truncated) view of what happens when I send a new message on Mastodon:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-json"&gt;  &amp;amp;quot;id&amp;amp;quot;: &amp;amp;quot;https://mastodon.social/users/Edent/statuses/1234567890/activity&amp;amp;quot;,
  &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;Create&amp;amp;quot;,
  &amp;amp;quot;actor&amp;amp;quot;: &amp;amp;quot;https://mastodon.social/users/Edent&amp;amp;quot;,
  &amp;amp;quot;published&amp;amp;quot;: &amp;amp;quot;2024-03-10T16:13:49Z&amp;amp;quot;,
  &amp;amp;quot;object&amp;amp;quot;: {
    &amp;amp;quot;id&amp;amp;quot;: &amp;amp;quot;https://mastodon.social/users/Edent/statuses/1234567890&amp;amp;quot;,
    &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;Note&amp;amp;quot;,
    &amp;amp;quot;content&amp;amp;quot;: &amp;amp;quot;Hello&amp;amp;quot;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The "Note" has some human-readable content, some metadata, and an ID - in this case a URl ending with &lt;code&gt;1234567890&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But that Note is wrapped in an &lt;em&gt;Activity&lt;/em&gt;. In this case, it is a "Create" message, with some metadata, and it's &lt;em&gt;own&lt;/em&gt; ID - in this case ending &lt;code&gt;1234567890/activity&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What happens if I edit the post? Here's a truncated view of what the server sends:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-json"&gt;  &amp;amp;quot;id&amp;amp;quot;: &amp;amp;quot;https://mastodon.social/users/Edent/statuses/1234567890#updates/1710087334&amp;amp;quot;,
  &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;Update&amp;amp;quot;,
  &amp;amp;quot;actor&amp;amp;quot;: &amp;amp;quot;https://mastodon.social/users/Edent&amp;amp;quot;,
  &amp;amp;quot;published&amp;amp;quot;: &amp;amp;quot;2024-03-10T16:15:34Z&amp;amp;quot;,
  &amp;amp;quot;object&amp;amp;quot;: {
    &amp;amp;quot;id&amp;amp;quot;: &amp;amp;quot;https://mastodon.social/users/Edent/statuses/1234567890&amp;amp;quot;,
    &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;Note&amp;amp;quot;,
    &amp;amp;quot;content&amp;amp;quot;: &amp;amp;quot;I meant Goodbye!&amp;amp;quot;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The "Note" has the &lt;em&gt;same&lt;/em&gt; ID as before - but the activity has a &lt;em&gt;different&lt;/em&gt; ID.&lt;/p&gt;

&lt;p&gt;Further updates follow the same pattern:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-JSON"&gt;  &amp;amp;quot;id&amp;amp;quot;: &amp;amp;quot;https://mastodon.social/users/Edent/statuses/1234567890#updates/1984651324&amp;amp;quot;,
  &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;Update&amp;amp;quot;,
  &amp;amp;quot;object&amp;amp;quot;: {
    &amp;amp;quot;id&amp;amp;quot;: &amp;amp;quot;https://mastodon.social/users/Edent/statuses/1234567890&amp;amp;quot;,
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So what happens when I &lt;em&gt;Delete&lt;/em&gt; a previously updated post?&lt;/p&gt;

&lt;p&gt;Here's what's sent:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-JSON"&gt;  &amp;amp;quot;id&amp;amp;quot;: &amp;amp;quot;https://mastodon.social/users/Edent/statuses/1234567890#delete&amp;amp;quot;,
  &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;Delete&amp;amp;quot;,
  &amp;amp;quot;actor&amp;amp;quot;: &amp;amp;quot;https://mastodon.social/users/Edent&amp;amp;quot;,
  &amp;amp;quot;object&amp;amp;quot;: {
    &amp;amp;quot;id&amp;amp;quot;: &amp;amp;quot;https://mastodon.social/users/Edent/statuses/1234567890&amp;amp;quot;,
    &amp;amp;quot;type&amp;amp;quot;: &amp;amp;quot;Tombstone&amp;amp;quot;,
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Again, the Activity has its own, unique, ID. But it is &lt;em&gt;the original ID&lt;/em&gt; of the Note which is to be deleted!&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.w3.org/TR/activitypub/#obj-id"&gt;spec says that all IDs must be URls&lt;/a&gt; - but it doesn't say what format they should be in. Mastodon helpfully makes the Activity's ID somewhat related to the object's ID - but not all software will do that.&lt;/p&gt;

&lt;p&gt;So, if you're doing something like saving messages to disk or a database, use the &lt;em&gt;object&lt;/em&gt; ID as the canonical reference. The ID of the Activity isn't particularly important when it comes to receiving updates, deletes, replies, or anything else.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=49894&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/03/how-updates-work-in-activitypub-mastodon/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[I made a mistake in verifying HTTP Message Signatures]]></title>
		<link>https://shkspr.mobi/blog/2024/03/i-made-a-mistake-in-verifying-http-message-signatures/</link>
					<comments>https://shkspr.mobi/blog/2024/03/i-made-a-mistake-in-verifying-http-message-signatures/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Thu, 14 Mar 2024 12:34:05 +0000</pubDate>
		<category><![CDATA[ActivityPub]]></category><category><![CDATA[CyberSecurity]]></category><category><![CDATA[HTTP]]></category><category><![CDATA[security]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=49885</guid>

					<description><![CDATA[It&#039;s never great to find out you&#039;re wrong, but that&#039;s how learning and personal growth happens.  HTTP Message Signatures are hard. There are lots of complex parts and getting any aspect wrong means certain death.  In a previous post, I wrote A simple(ish) guide to verifying HTTP Message Signatures in PHP. It turns out that it was too simple. And far too trusting.  An HTTP Message Signature is a…]]></description>
										<content:encoded>&lt;p&gt;It's never great to find out you're wrong, but that's how learning and personal growth happens.&lt;/p&gt;

&lt;p&gt;HTTP Message Signatures are hard&lt;sup id="fnref:hard"&gt;&lt;a href="https://shkspr.mobi/blog/2024/03/i-made-a-mistake-in-verifying-http-message-signatures/#fn:hard" class="footnote-ref" title="You might think the Entscheidungsproblem is hard, but that's just peanuts compared to etc. etc." role="doc-noteref"&gt;0&lt;/a&gt;&lt;/sup&gt;. There are lots of complex parts and getting any aspect wrong means certain death&lt;sup id="fnref:death"&gt;&lt;a href="https://shkspr.mobi/blog/2024/03/i-made-a-mistake-in-verifying-http-message-signatures/#fn:death" class="footnote-ref" title="Or cake." role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;In a previous post, I wrote &lt;a href="https://shkspr.mobi/blog/2024/02/a-simpleish-guide-to-verifying-http-message-signatures-in-php/"&gt;A simple(ish) guide to verifying HTTP Message Signatures in PHP&lt;/a&gt;. It turns out that it was &lt;em&gt;too&lt;/em&gt; simple. And far too trusting.&lt;/p&gt;

&lt;p&gt;An HTTP Message Signature is a header which is separate to the message it signs.  You might receive a JSON message like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-json"&gt;{
   "actor":   "https://example.com/user/Alice",
   "message": "We strike at dawn!"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How do you know that &lt;em&gt;really&lt;/em&gt; came from Alice? You look at the header of the message. It will be something like:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-_"&gt;Signature: 
   keyId="https://example.org/user/Alice#main-key",
   algorithm="rsa-sha256",
   headers="(request-target) host date digest",
   signature="/AJ4Dv/wSL3XE1dLjFHCYVc7AF4f3+Q10G/r8+6cPsooiUh2K3YX3z++Nclo4qKHYr61yu+T4OMqUry1T6ZHmZqmNkg1RpVg=="
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We want to check that Alice signed this message with her &lt;em&gt;private&lt;/em&gt; key. So we grab her &lt;em&gt;public&lt;/em&gt; key given by the &lt;code&gt;keyId&lt;/code&gt;.
From there, we do some fancy maths using RSA-SHA256 and conclude that, when you put together the &lt;code&gt;(request-target) host date digest content-type&lt;/code&gt; and compare them to the public key, they can only have be signed by the private key. Hurrah!&lt;/p&gt;

&lt;p&gt;Did you spot the mistake I made? It wasn't in the maths, or the complex ordering of the data, or the algorithm choice, or some weird Unicode problem.&lt;/p&gt;

&lt;p&gt;I made an error in &lt;em&gt;trust&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Take a look at the Signature again.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;keyId&lt;/code&gt; is from example.&lt;strong&gt;org&lt;/strong&gt;. But the actor is from example.&lt;strong&gt;com&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This message &lt;em&gt;is&lt;/em&gt; signed correctly. It &lt;em&gt;is&lt;/em&gt; cryptographically valid. &lt;strong&gt;But it wasn't signed by the actor in the message!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this case, the fix is simple.  Get the public key from &lt;code&gt;keyId&lt;/code&gt;. Then &lt;em&gt;independently&lt;/em&gt; get the named actor's public key.  If they match, all is well. If not, skulduggery is afoot.&lt;/p&gt;

&lt;p&gt;I'm &lt;em&gt;almost&lt;/em&gt; tempted to say that you should &lt;em&gt;ignore&lt;/em&gt; the provided &lt;code&gt;keyId&lt;/code&gt; entirely; the source of truth is the actor's key - and the best way to get that is directly from the actor's profile.&lt;/p&gt;

&lt;p&gt;Please explain why I'm wrong in the comments.&lt;/p&gt;

&lt;div id="footnotes" role="doc-endnotes"&gt;
&lt;hr aria-label="Footnotes"&gt;
&lt;ol start="0"&gt;

&lt;li id="fn:hard"&gt;
&lt;p&gt;You might think the &lt;i lang="de"&gt;Entscheidungsproblem&lt;/i&gt; is hard, but that's just &lt;em&gt;peanuts&lt;/em&gt; compared to etc. etc.&amp;nbsp;&lt;a href="https://shkspr.mobi/blog/2024/03/i-made-a-mistake-in-verifying-http-message-signatures/#fnref:hard" class="footnote-backref" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn:death"&gt;
&lt;p&gt;Or cake.&amp;nbsp;&lt;a href="https://shkspr.mobi/blog/2024/03/i-made-a-mistake-in-verifying-http-message-signatures/#fnref:death" class="footnote-backref" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;
&lt;/div&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=49885&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/03/i-made-a-mistake-in-verifying-http-message-signatures/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
