От Тима: привет! Сегодня в календаре — гостевой пост про ActivityPub. Это важная часть истории про альтернативы корпоративным социальным сетям, которая развивалась параллельно стандартам Индивеба Microformats и Webmention.
Мне хочется, чтобы ActivityPub был упомянут в календаре, но мне не хватает знаний из первых рук про всю эту экосистему — поэтому я попросил Гришу написать пост про ActivityPub. ActivityPub-экосистема подходит к федеративным социальным сетям с несколько другой стороны, но не буду спойлерить.
Если кратко: ActivityPub — это самый популярный протокол федерации между серверами социальных сетей, микроблогов и прочих подобных вещей.
По своей концепции ActivityPub очень похож на SMTP. Есть независимые сервера, на каждом сервере есть свои пользователи, у каждого пользователя есть инбокс. В инбоксы кладут «активити» — действия других пользователей, которые так или иначе касаются получателя. Совершают эти действия «акторы» — пользователи, группы, боты, и так далее. Например, если Вася с сервера mastodon.xyz подписан на Петю с сервера example.social, и Петя создаёт новый пост, Петин сервер положит этот пост Васе в инбокс на его сервере, и он появится в Васиной ленте.
Вся совокупность серверов социальных сетей, которые федерируются друг с другом, называется fediverse — соединение слов federation и universe.
Все объекты представлены в (весьма наркоманском) формате JSON-LD и передаются по HTTPS, но пока что представьте себе, что это обычный JSON с ключом @context
. Вот пример объекта (актора) пользователя, обратите внимание на ключ inbox
:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"id": "https://example.social/users/petya",
"type": "Person",
"url": "https://example.social/@petya",
"preferredUsername": "petya",
"name": "Петя",
"inbox": "https://example.social/users/petya/inbox"
"outbox": "https://example.social/users/petya/outbox",
"followers": "https://example.social/users/petya/followers",
"following": "https://example.social/users/petya/following",
"summary": "<p>Тот самый мазохист, который упомянут в спецификации LD-signatures<\/p>",
"endpoints": {
"sharedInbox": "https://example.social/sharedInbox"
},
"icon": {
"type": "Image",
"url": "https://example.social/uploads/avatars/79b12c2b44826342fa0fe07d9662010d.jpg"
},
"publicKey": {
"owner": "https://example.social/users/petya",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n",
"id": "https://example.social/users/petya#main-key"
},
}
Вот создание (активити типа Create) поста (объекта типа Note) пользователем (актором типа Person):
{
"@context":[
"https://www.w3.org/ns/activitystreams",
{"sensitive":"as:sensitive"}
],
"id":"https://example.social/posts/2851/activity",
"type":"Create",
"actor":"https://example.social/users/petya",
"to":["https://www.w3.org/ns/activitystreams#Public"],
"cc":["https://example.social/users/petya/followers"],
"published":"2019-12-15T16:28:35Z",
"object":{
"id":"https://example.social/posts/2851",
"type":"Note",
"to":["https://www.w3.org/ns/activitystreams#Public"],
"cc":["https://example.social/users/petya/followers"],
"attributedTo":"https://example.social/users/petya",
"published":"2019-12-15T16:28:35Z",
"sensitive":false,
"content":"<p>Я сегодня видел няшного котика!<\/p>",
"url":"https://example.social/posts/2851"
}
}
Получить ActivityPub-объект для любого пользователя или поста можно по адресу этого пользователя или поста, добавив в запрос заголовок Accept: application/ld+json
, например:
$ curl -H "Accept: application/ld+json" https://mastodon.social/users/grishka
Результат:
Сам по себе ActivityPub слишком сложный и многогранный, чтобы быть полностью описанным в одной статье адекватной длины. Если появилось любопытство, хочется больше подробностей и потыкать в настоящие сервера, я бы советовал начать с этих двух статей в блоге Mastodon.
Существующие реализации
На данный момент есть уже достаточно много различного серверного софта, поддерживающего ActivityPub:
- Mastodon, Pleroma, Misskey, Honk — микроблоги по типу твиттера
- Pixelfed — фотошеринг по типу инстаграма
- Friendica — социальная сеть, реализующая очень небольшую часть функционала фейсбука
- Funkwhale — музыкальный сервис
- PeerTube — видеохостинг по типу ютуба, примечателен ещё и тем, что использует WebTorrent для раздачи видео в плеер
- Неофициальный плагин для вордпресса, добавляющий ему поддержку ActivityPub
- Конвертер RSS в ActivityPub
Всё это в изрядной степени работает друг с другом. То есть, я могу подписаться на пользователя Pixelfed со своего акканта в Mastodon, и смотреть на его фотографии котов в своей ленте. Как тебе такое, Илон Маск Марк Цукерберг?!
Мой опыт
Мне, как человеку, полжизни прожившему и 5 лет проработавшему ВКонтакте, очень хотелось аналогичной социальной сети, но со стеной без Mail.ru Group и без централизации со всеми её последствиями. Посмотрел я такой на это всё, и решил сделать свою, потому что Friendica слишком далека от того, что я хочу, и назвал её Smithereen. Да, этот Smithereen.
Пишу на джаве. Для федерации, само собой, использую ActivityPub. С мастодоном уже работает, но до чего-то презентабельного там далековато, так что ссылок пока не будет. Но могу описать сложности, с которыми я столкнулся:
- JSON-LD — наркоманский формат. Это как XML со схемой и неймспейсами, только JSON. Для нормального участия в fediverse надо уметь его корректно парсить, переводя всё полученное в понятный тебе вид. Есть спецификация, в которой по шагам описаны алгоритмы преобразования, но лучше поберегите свою психику и не читайте её без необходимости.
- Подписывание запросов. По-хорошему, каждый запрос должен быть подписан приватным ключом актора два раза: HTTP-подписью и LD-подписью. Первая генерируется и проверяется просто, но запросы, подписанные только HTTP-подписью, нельзя проксировать, т.к. подписываемые заголовки включают в себя Host, делая подпись зависимой от хоста назначения запроса. Вторая — это очень больно, ибо предполагает многочисленные неочевидные манипуляции с JSON-LD, но запросы с ней проксировать можно, нужно и полезно. Подробно о моих страданиях с LD-подписями можно почитать вот здесь.
- Первопроходчество. Его много. Всё существующее так или иначе похоже на твиттер, концепции друзей ни у кого нет, сообществ тоже ни у кого нет, даже стен ни у кого нет. И это я пока не начал думать про фотоальбомы и прочие видеозаписи. Но сам по себе протокол достаточно открытый для интерпретации и расширения, приходится много всего придумывать.
Что почитать по теме
- Спецификацию ActivityPub
- Спецификации JSON-LD и алгоритмов для его обработки, но лучше использовать готовую библиотеку
- Эту серию постов от разработчика Honk
- Официальный форум разработчиков
- Следить за обновлениями моего проекта можно по хэштегу #Smithereen в мастодоне
← День 15: WebSub · День 17 →