This is a technical Google Summer of Code Project Report describing
briefly what I did from April 23 to August 6.
The whole code I wrote during this period is available
here.
The API documentation is available
here.
This document helps understanding what was done in a simple and informal way,
highlighting the most relevant parts, why some decisions were made and what
I've learned with it.
The following document is intended to be reasonably self contained
and capable of quickstarting anyone in the world of ActivityPub implementation,
yet not replacing the official standard specification.
From April 23 to May 14 I had to familiarize myself with the
Activity Pub standard and GNU social's plugins/events API and community.
What is GNU social?
GNU social is a social communication software used in federated
social networks.
ActivityPub?
In order to achieve said decentralization, a variety of standards on
how communication between different pieces of software in a federated
context should be done were created, such as OStatus. ActivityPub, however,
is the newest and covers parts left out of OStatus's specification, namely
app/client development.
Benefits
The tendency is that newer software will focus in the
implementation of the ActivityPub Protocol (as it is newer
and considered to be simpler) instead of OStatus, given
that, it is important for GNU social to support it in order to stay updated
and relevant in an even larger fediverse;
It will simplify app/client development which is not covered by the
OStatus's specification and is becoming more and more relevant,
with the increase of smartphone users.
Why a plugin?
Unix tools design philosophy
GNU social is true to the Unix-philosophy of small programs to do a
small job.
Compact and concise input syntax, making full use of ASCII repertoire to minimise keystrokes
Output format should be simple and easily usable as input for other programs
Programs can be joined together in “pipes” and “scripts” to solve more complex problems
Each tool originally performed a simple single function
Prefer reusing existing tools with minor extension to rewriting a new tool from scratch
The main user-interface software (“shell”) is a normal replaceable program without special privileges
Support for automating routine tasks
As so the project aims at building a plugin that will
implement the ActivityPub Protocol in GNU social.
The ActivityPub protocol is a decentralized social networking
protocol based upon the ActivityStreams 2.0 data format.
It provides a client to server API for creating, updating and deleting
content, as well as a federated server to server API for delivering
notifications and content.
Note: You are advised to read (at least) the standard
overview before continuing.
Actor
Actor is the user doing a change in the fediverse and are identified by an URI.
In GNU social they have the following format:
https://myinstance.net/user/{id}. Thus allowing users to change their
usernames (or nicknames).
Objects
Objects are our building blocks for the bigger concept of Activity.
The plugin has the following objects:
For the plugin I decided to create two key components.
The Explorer
Defined in this file it is responsable for grabbing remote users and creating an identity for those in the local instance. It is higly related with Activitypub_profile.php.
The Postman
This guy does the magic of publishing the activities
(thus the name ActivityPub!) to remote instances, he kinda is the
responsable for the federation provided by this plugin. Its code is here.
Becoming familiar with GNU social's events
We just know what and when to deliver something thanks to GNU social's events.
Events the plugin is handling
Discovery Events
Find remote profiles from mentions in texts (onEndFindMentions)
Allow to reference a remote profile (onStartCommandGetProfile)
Allow to reference a remote profile (onStartGetProfileUri)
Delivery Events
Notify remote instance of subscription (onEndSubscribe)
Notify remote instance when a subscription is canceled (onEndUnsubscribe)
Notify remote instances when a notice is liked (onEndFavorNotice)
Notify remote instances when a notice like is reverted (onEndDisfavorNotice)
Notify remote instances when a notice is deleted (onEndDeleteOwnNotice)
Notify remote instances when a notice is created (onStartNoticeDistribute)
These are not the only events this plugin is listening to, but are
the most relevant. All these events hooks can be found here.
Fediverse is similar to the real world in some aspects. And one of those
is that people, sometimes, share the same "building". A list of some
public GNU social instances is available here.
Well, if two people live in the same place then our Postman doesn't have to "travel" twice! Thus
the concept of shared inbox.
Lets start with the inbox. An
inbox is where we, I mean, the Postman publishes
our Activity.
By now you should have already realized that Activities are just
verbs wrapping objects thus basically forming a phrase:
ActorverbObjectto Attention Actor(s).
Well, for each Attention actor we deliver the same
ActorverbObject.
Since it is the same message and frequently for people residing
in the same server we can obviously reduce a lot of traffic and
processing power here.
The Explorer hands the Postman the sharedInbox address always that
it is possible.
This plugin fulfills and even exceeds what I've originally proposed to
do during this summer (hooray!). But there is still room for further development
and improvement!
Not really, this document doesn't describe the implementation of
HTTP Signatures, the internal representation of ActivityPub Actors,
nor the details of Activity Streams or even the particularities of integrating
this in GNU social (I'm looking at you OStatus plugin). As stated in the
beginning of this document, the whole code and documentation is available
above, this was just meant to make the reading easier.
I'm interested in implementing ActivityPub on my program and reading
this really helped me! Is there something else that I should know of that
wasn't mentioned in the article?
GSoC was a wonderful experience for me. I now feel more comfortable
with the GNU social’s codebase. I learned a lot of useful stuff like
ActivityPub, ActivityStreams, HTTP Signatures, PSR and Redis as well as
software engineering concepts like Circuit Breakers. I've also learned
more about Git and how libre and open source software development is
done and organized.
I will try my best to regularly contribute to GNU social and other
projects.
Thanks to Daniel Supernault and Mikael Nordfeldth for such a
wonderful experience and the knowledge.