About the project and this document

What is this document?

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.


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.


Why a plugin?

Unix tools design philosophy

GNU social is true to the Unix-philosophy of small programs to do a small job.

- Brian W. Kernighan, Rob Pike: The Unix Programming Environment. Prentice-Hall, 1984.

As so the project aims at building a plugin that will implement the ActivityPub Protocol in GNU social.

So how does ActivityPub work?

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 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 are our building blocks for the bigger concept of Activity. The plugin has the following objects:

Note: Tags, Attachment and Image are ("minor") objects and, usually, wrapped by ("major") objects.


Wrappers allow to give additional information on a given object. The implemented wrappers are the following:

By wrapping an object with one of those we are able to perform an action in name of a given Actor.

And how does the plugin work?

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
Delivery Events

These are not the only events this plugin is listening to, but are the most relevant. All these events hooks can be found here.

Hold on, if you have a Postman then there sure is an inbox, right?

Two actually! :)

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: Actor verb Object to Attention Actor(s).

Well, for each Attention actor we deliver the same Actor verb Object.

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.

Our plugin also is a collector

The following collections have been implemented:

Collections are lists. And lists are very important in the world of fediverse both for Server to Server and Client to Server.

What is left to do?

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!


So, that was it?

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?

Be sure to know HTTP Status Codes and to start soon with the Test-driven development.

And, obviously, follow rigorously the ActivityPub specification!

If you need help you can contact me or Daniel Supernault directly or, even better, join the W3C social IRC channel (#social@irc.w3.org), you will definitely find us both there! :)

Final Words

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.


You're active, persistent and productive. Keep it up and we'll all have a great summer of code!

- Mikael Nordfeldth, GNU social Maintainer (2018) on my first GSoC evaluation