Blob/Cat

2020/01/31 4:53:51 AM UTC

Planning on federating via ActivityPub, reading about it and ActivityStreams, the protocols look pretty simple and elegant. What's your guys' take on and ?

2020/02/01 2:20:48 AM UTC

@nodetube you might want to check out , which your project could be compatible with!

2020/02/01 5:38:55 AM UTC

@sean yeah I'm familiar with PeerTube. Actually based on my research I don't plan on doing ActivityPub for a while i'm not sold on it. Will focus on making a really great standalone instance when the dust is settled more on what decentralized protocol is going to make it I'll look into implementing it. I have a live instance up at nodetube.live if you want to contrast it with PeerTube

2020/02/01 6:22:44 AM UTC

@mewmew @nodetube it's not a perfect protocol by any means. The biggest thing AP has going for it lies in its adoption. Currently, 8 major federated platforms support it, covering use-cases ranging from microblogging to music and photo sharing and more. As a network, it has about 3 million users, and most of the apps can interoperate in some way. For example, Mastodon can follow PeerTube, and Funkwhale (a music player) is working towards similar functionality so that the wider network can follow musicians.

There's room to grow, and the biggest challenge to tackle involves better privacy. That said, as a collaborative effort, we've gotten really far.

2020/02/01 6:23:52 AM UTC

@sean @nodetube
> Funkwhale
lol

I do agree that AP isn't perfect but I'd like to know what their specific concerns are.

2020/02/01 8:13:14 PM UTC

@mewmew @sean

@sean

Here's a Reddit post I wrote with some of my ActivityPub concerns: reddit.com/r/Rad_Decentralizat

(Not quite the space to send it as a message here on Fosstodon sorry).

Interested in hearing your guys' response. Really I hope ActivityPub could be the thing that solves my question of how I'd like NodeTube instances to federate but at the moment I'm very skeptical as per the reasons in the Reddit post above.

2020/02/01 8:57:26 PM UTC

@nodetube @sean ok, I can address this.

First, a lot of these issues are only in the implementation. For example, following an instance is definitely possible in ActivityPub, Mastodon simply does not have this supported.

The ugly redirect flow isn’t necessary either, you just search up their handle on your instance.

You can still use the protocol and have a more oAuth like flow for interactions - simply expose channels as Actor, videos as Video, audio as Audio, comments as Note, etc (and when someone follows a channel, send them Create Video, Like Video, Create Note etc).

As for your community concern, I think that’s more about the people who are interested in ActivityPub using ActivityPub, of course they’re not gonna be on Twitter - they’re here.

If you have further questions I can answer them.

2020/02/01 8:59:00 PM UTC

@nodetube @sean for example, PeerTube allows instances to follow other instances so all of their videos federate to the instance. If you'd like an account on my instance for testing, I could make you one.

2020/02/01 9:26:50 PM UTC

@mewmew @sean Okay you're definitely a great person to talk to in this regard. And yeah it's hard for me to decouple ActivityPub from Mastodon/PeerTube at times because there's not a lot of great documentation/tutorials I can find online so it's really like poking around with those apps and making assumptions in large part.

2020/02/01 9:32:38 PM UTC

@mewmew @sean I have a PeerTube account that I've been doing some testing with. It was cool because I could look up another PeerTube account and then comment on the video from my @video.tedomum.net identity which was awesome. But then when I actually went over to that instance I couldn't 'login' so the only way I could interact was through the redirect flow.

2020/02/01 9:33:55 PM UTC

@nodetube @sean yeah... that's a bit of a harder thing to do, ideally you see the content on your own instance instead of having to login on the other one. I don't see how a well thought out redirect flow is any worse than oauth though, and it's a lot safer imo.

2020/02/01 9:34:29 PM UTC

@mewmew @sean I mean, is it a limitation of ActivityPub the protocol or its implementation that disallows a "Login from another PeerTube instance" type functionality. If that could land then you have something that approximately 'one login for all instances' which is what I'm after. Even if you have to redirect to sign in (Like with 'login with your Stackexchange account') that would be perfect but I don't see that in the wild atm.

2020/02/01 9:36:41 PM UTC

@mewmew @sean The oAuth flow is nice because it's one and done and you interact with that instance per your single identity. Trying to poke around another PeerTube instance and having to ridirect everytime you like, subscribe etc, it's maddening. Like trying to eat a taco with oven mits on or something lol. You'd just want to make your own account at that instance at that point, which means another password/email verification etc (ugh). Plus that doesn't scale. May as well just do normal auth

2020/02/01 9:41:12 PM UTC

@nodetube @sean ActivityPub c2s allows that - the problem is for that method of login you need to give your keys to each instance.

2020/02/01 9:42:28 PM UTC

@nodetube @sean You could just as easily have it setup so an instance remembers where to redirect you to.

If you had your oAuth flow, you'd need to visit each instance you have subscriptions on to check your subscriptions. With the redirect flow, you only need to do that once, and if you find the account by browsing the timeline on your local instance, not even at all.

2020/02/01 9:48:01 PM UTC

@mewmew @sean Is it like a 'root key' which has all the privileges in one, or could you segment like oAuth so maybe the instance can comment/like on your behalf, but not post content or something along those lines? Like I would love to just read some authoritative textbook from Manning or something on ActivityPub so I can fully wrap my hands around it but it seems so new it's like everything just redirects to the W3C standard.

2020/02/01 9:49:45 PM UTC

@mewmew @sean And then I went to go read the standard it was like "Oh it's based on Activity Streams 2.0" and I was like "okay cool", googled Activity Streams 2.0 and it was a veritable wasteland. Even on YouTube there's just the one video from 2014. Ideally there's like 5 tutorials so I can try a couple approaches and there's options if one doesn't work for me but everything is so new/undocumented it's a bit scary.

2020/02/01 9:51:16 PM UTC

@mewmew @sean Even when I look up 'activitypub c2s' the top link is to this: github.com/tootsuite/mastodon/

Which is a recent thread where people are having like a very philosophical conversation on whether Mastodon's API will end up becoming a de facto standard for ActivityPub lol. Very scary to think I have to tread through those waters to get my implementation up. That's why my take was to wait and let the dust settle a bit before choosing a decentralized protocol to implement.

2020/02/01 9:51:31 PM UTC

@mewmew @sean Thanks a ton for your help btw really appreciate it

2020/02/01 9:58:47 PM UTC

@nodetube @sean I think I'll just have to explain how ActivityPub works to you, gimme a bit of time, it's kinda complex.

2020/02/01 11:44:13 PM UTC

@nodetube @sean (you should view this on my instance since fosstodon.org doesn’t support Markdown formatting so it’ll look like a garbled mess on your instance)

there are a few things you need to understand to understand ActivityPub:

  1. ActivityStreams2
  2. ActivityPub
  3. How ActivityPub servers actually implement the protocol (very different from the other three!)

so first, let’s start with ActivityStreams2. The general way this works is by having multiple types of Objects. An object can be anything, but there are three main categories: Object (catch-all category), Actor, and Activity. So while all Activities are Objects, not all Objects are Activities.

An example of an Activity is a Like. Another example is a Follow. Another example is a Create.

Here’s what a Pleroma (implementation of ActivityPub similar to Mastodon) Like looks like:

{ 
   "cc":[ 
      "https://veenus.art/users/lottev",
      "https://www.w3.org/ns/activitystreams#Public"
   ],
   "id":"https://blob.cat/activities/c42bc3be-fbdb-42f6-8562-0b411aec69b4",
   "to":[ 
      "https://blob.cat/users/mewmew/followers",
      "https://veenus.art/users/lottev"
   ],
   "type":"Like",
   "actor":"https://blob.cat/users/mewmew",
   "object":"https://veenus.art/objects/7f3e54e1-a19f-49be-a9dc-9d410ff42bcb",
   "context":"https://veenus.art/contexts/4990b6d8-7457-4bc1-8bfe-ac6b72d10c1b",
   "published":"2020-02-01T22:10:10.801412Z",
   "context_id":5619370
}

Let’s take a look at this. First, take a look at the “object” field. This is the ID of another Object (in this case, a Note). ActivityStreams2 uses JSON-LD, meaning that instead of having to embed the object, you can just put a URL for it instead.

Next, the “actor” field. This is the ID of the Actor (think: user) who did the activity (in this case, me).

The type is “Like” obviously.

“to” lists who the object is being sent to - in particular, it’s addressed to the actor https://veenus.art/users/lottev, whose Note is being liked, and to the list of my followers: https://blob.cat/users/mewmew/followers. “cc” is for people who the object isn’t explicitly being sent to, but is visible to. https://www.w3.org/ns/activitystreams#Public is a URL to say “this is public”. Note: for normal posts, if that URL is part of the “to” field, then the post is listed on timelines, if it’s part of the “cc” field, it’s unlisted. However, this is not part of the spec and is instead how instances choose to implement it so you don’t need to implement things in a similar way.

Finally, “id” is the unique ID of the object. Every object, be it an actor, activity, note, etc, has a unique ID. If another object wanted to reference this object, it’d reference that ID instead of embedding the entire object.

Now, how do Actors work? Here’s an example of an actor (me):

{ 
   "@context":[ 
      "https://www.w3.org/ns/activitystreams",
      "https://blob.cat/schemas/litepub-0.1.jsonld",
      { 
         "@language":"und"
      }
   ],
   "attachment":[ 
      { 
         "name":"I set this using ",
         "type":"PropertyValue",
         "value":"Husky"
      },
      { 
         "name":"UwU?",
         "type":"PropertyValue",
         "value":"uwu"
      }
   ],
   "discoverable":false,
   "endpoints":{ 
      "oauthAuthorizationEndpoint":"https://blob.cat/oauth/authorize",
      "oauthRegistrationEndpoint":"https://blob.cat/api/v1/apps",
      "oauthTokenEndpoint":"https://blob.cat/oauth/token",
      "sharedInbox":"https://blob.cat/inbox",
      "uploadMedia":"https://blob.cat/api/ap/upload_media"
   },
   "followers":"https://blob.cat/users/mewmew/followers",
   "following":"https://blob.cat/users/mewmew/following",
   "icon":{ 
      "type":"Image",
      "url":"https://blob.cat/media/4388406b7171498d806fcd512613b9d2586e86399e5d92b2b5898710f332e081.png"
   },
   "id":"https://blob.cat/users/mewmew",
   "image":{ 
      "type":"Image",
      "url":"https://blob.cat/media/6d52a75f1e0825f6570611c19a5c0065d80ab1e1c51071dd41217080d6ff5ef4.png"
   },
   "inbox":"https://blob.cat/users/mewmew/inbox",
   "manuallyApprovesFollowers":false,
   "name":"Fridayblob :blobcat:",
   "outbox":"https://blob.cat/users/mewmew/outbox",
   "preferredUsername":"mewmew",
   "publicKey":{ 
      "id":"https://blob.cat/users/mewmew#main-key",
      "owner":"https://blob.cat/users/mewmew",
      "publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA38zn7CJV6qBMHrkealqC\n70l/WlSGcNC4PHx5HnOmw8cXqbmeFKkJuyXFiDsz8m2BwjeN/TEjeBsn/1LcQ5x1\nqvx5QQ+0XFvHuCXigjRhR7p54M1yPyxxiQF2BDe1dRMArfBh0ca48kvqzkzvfhrr\n5sFhXChy9+n8Y4FhAeZ39nTvmpkpEdZ/F/0PIjR5IdwrWKmJ510Tn0tBx5YWmQ7p\nj0K2mlVANJmLT/YiqCu25LX3D/UsEA69mWRDYNqj5EozyvAi1FA1SHisNWy8a6zg\nnoqk3/pQ5rU7A4upGCvASmParxAY54FZ05JeYee3FXzvwSmHG+zj6lMrirK1zI8T\nLQIDAQAB\n-----END PUBLIC KEY-----\n\n"
   },
   "summary":"admin of <a href=\"http://blob.cat\">blob.cat</a> and busshi.moe, if you have any questions/concerns, or if you just wanna talk, dm me<br><br>please don&#39;t tag me in hellthreads though<br><br>if i&#39;m posting too much meta stuff please slap me or something don&#39;t just unfollow that makes me sad :blobcatglare: <br><br>mastodon alt: <span class=\"h-card\"><a data-user=\"9poBFzbtejsZg96wsa\" class=\"u-url mention\" href=\"https://busshi.moe/@mewmew\" rel=\"ugc\">@<span>mewmew@busshi.moe</span></a></span><br>private alt: <span class=\"h-card\"><a data-user=\"9phYcLTwGpaIFSikcK\" class=\"u-url mention\" href=\"https://princess.cat/users/mewmew\" rel=\"ugc\">@<span>mewmew@princess.cat</span></a></span><br>xmpp account: mewmew@blob.cat (all local users here have it!)",
   "tag":[ 
      { 
         "icon":{ 
            "type":"Image",
            "url":"https://blob.cat/emoji/custom/blobcats/blobcatglare.png"
         },
         "name":":blobcatglare:",
         "type":"Emoji"
      },
      { 
         "icon":{ 
            "type":"Image",
            "url":"https://blob.cat/emoji/custom/blobcats/blobcat.png"
         },
         "name":":blobcat:",
         "type":"Emoji"
      }
   ],
   "type":"Person",
   "url":"https://blob.cat/users/mewmew"
}

There’s a lot going on here. First, take a look at the “id”. This is https://blob.cat/users/mewmew and my id on this social network - I’ll explain how you get from that to @mewmew later.

“followers” and “following” are collections (a type of object) that list who I am following and who follows me.

“name” is what I have my nickname set to currently.

“type” is “Person” - there can also be automated actors such as relays (which is the way you’d follow an instance).

Most important: take a look at “inbox” (https://blob.cat/users/mewmew/inbox),"outbox” (https://blob.cat/users/mewmew/inbox), and under “endpoints”, “sharedInbox” (https://blob.cat/inbox). These are the main way ActivityPub federation works. If you make a private post and want to send it to me, what you would do is POST it to my inbox, while signing the request with your key. You can see publicKeyPem listed in my profile - this is the key that all my posts are signed with, so if I send you a direct message, a message is POSTed to your inbox URL (probably https://fosstodon.org/users/nodetube/inbox), with an HTTP signature made using my private key (stored on server).

Now, this is inefficient for public posts - so for a post that’s public, you send it to the sharedInbox endpoint instead (so this post is only getting sent to https://fosstodon.org/inbox, not to you individually).

Now, /outbox is another important endpoint. It allows you to iterate over an actor’s posts. Usually it only displays public ones, but if you sign your fetch with an HTTP signature, it’ll show all of the ones that that actor is allowed to access (so if you follow me and sign the request with your signature, you can load my followers-only posts). This is useful for backfilling posts to your instance when you first find an account for example.

NOW, for your intended functionality - what I would do is the following:

  • Allow oAuth for various scopes
  • On the remote instance, authenticate with oAuth
  • When you do something on the remote instance, send the object created back to your home instance to be federated out

(sorry if this didn’t make sense, kinda hard to explain it)

2020/02/02 2:12:27 AM UTC

@mewmew @sean Awesome man thank you for this. I will have a good chance to dig into it and cross-reference it against some googling tomorrow. Highly appreciate it though I was hoping to run into someone who had a solid grasp of ActivityPub so they could point out where I was missing things, hopefully we can figure something out and have NodeTube in the Fediverse but also super-user friendly flow, that's the dream.

2020/02/02 2:21:00 AM UTC

@nodetube @sean glad you came on here and reached out - it'd be awesome to have another video platform as part of the network! Feel free to ask me if you have more questions.

2020/02/02 3:16:24 AM UTC

@nodetube @mewmew you might want to check out the SocialHub forum, it's run by the ActivityPub project and has a lot of contributors going through the semantics.

A few people that know a lot about the spec would probably be @lain @cwebber and perhaps @nightpool

2020/02/02 3:17:42 AM UTC

@sean @nodetube @cwebber @lain I think you tagged the wrong nightpool account

2020/02/03 6:08:57 AM UTC

@mewmew @sean Alright I had a chance to go over that today, and no don't worry it made perfect sense. So based on my flow where say I'm on Nodetube1.com but I'm already registered on NodeTube2.com, let's say there's a "Login with existing NodeTube account", where you enter the URL to your home instance and it redirects you there, at which point you login (or just accept the permissions if already logged in) and are redirected back to Nodetube1.com ..

2020/02/03 6:11:34 AM UTC

@mewmew @sean

Theoretically you could post on Nodetube1.com, and have it show up with the credentials from your Nodetube2.com account, which is made possible by an oAuth scope which will allow you to do a PGP signature over HTTP , basically posting to Nodetube2.com/@useryoureviewing/inbox . I guess I have to mete out in my mind where oAuth begins and ActivityPub ends, but does that flow I just laid out for you seem technically plausible in your opinion? Thx again much appreciated!

2020/02/03 6:12:25 AM UTC

@sean Thanks for the heads up I will definitely check that out!

2020/02/03 6:16:16 AM UTC

@nodetube @sean yes that is totally plausible! Basically the nodetube instances other than your home ones act as "clients" that authenticate for a limited set of actions over oauth (maybe something like, authenticate only for interactions with said instance).

2020/02/03 6:20:08 AM UTC

@mewmew @sean I couldn't quite tell, it looked like but I'm not sure, is ActivityPub 'smart enough' to know about oAuth? Like is the capability to say "hey this is an instance which I want to be able to use my public key in certain regards but not in others", is that already baked in ActivityPub or would it have to built independently?

2020/02/03 6:21:16 AM UTC

@nodetube @sean that's on your home server to do - the easiest solution is to route all posts through there over a non-AP API

2020/02/03 6:24:53 AM UTC

@mewmew @sean Ah okay I get it, just reroute it to the home server which is authenticated to make calls against that public key. So AP and oAuth are totally decoupled then? Blob.cat is a plemora instance, so basically the Plemora devs have already built in oAuth capability into their app and that's why it was showing up on your Actor object document? Also how does the Server-to-server API function? I think I might do that first then c2s after 🤔

2020/02/03 6:27:49 AM UTC

@nodetube @sean ok so

1. yes, totally decoupled. the oauth endpoint is for client apps only and not part of the AP standard.
2. s2s API is basically what I described, sending posts to /inbox and crawling posts from /outbox. You don't want to use c2s in your client, it's not that useful. Your server acts as an "ActivityPub client" in the sense that it caches message threads (this post isn't loaded directly by your client, it's sent to fosstodon which sends it to your client). So don't worry about c2s, except for when fetching posts.

2020/02/03 6:35:22 AM UTC

@mewmew @sean So basically, in the same manner that Mastodon has this redirect flow which sends the request back to the authenticated url, I would basically be abstracting that away through oAuth right? Things are definitely more clear to me I have to say that chances of me doing AP went from like 10% to like 49.9% with this convo lol. I think if I had like 3 people who were as smart as you and able to help me out I could feel confident enough to start an integration lol

2020/02/03 6:36:57 AM UTC

@nodetube @sean yes exactly

I'm sure you have an API, so for remote instances, when they authenticate give them an API token and let them call the API.

Of course you still implement the s2s stuff, but all the federating out is done by your home server - the only part done by the one you oauth authenticate with is sending the non-AP API request to your home server.

2020/02/03 6:39:07 AM UTC

@mewmew @sean yeah exactly, and then another question I have is, for example this url: fosstodon.org/web/accounts/336 is what pops up when I checked out someone who replied in this thread. Is this what you mean by AP is performing some kind of caching? Because it doesn't make sense that that id number is permanent , so is it retrieved via a GET request and then cached or something? 🤔

2020/02/03 6:39:23 AM UTC

@nodetube @sean yes please come make some posts about your project there. socialhub.activitypub.rocks is exactly where alot of these discussions are happening.

2020/02/03 6:40:51 AM UTC

@liaizon @sean okay epic that looks like a great resource thanks a lot!

2020/02/03 6:41:11 AM UTC

@nodetube @sean that's actually part of c2s and is unique to Mastodon's implementation. Mastodon caches copies of remote profiles and posts, so does Pleroma, so does PeerTube, etc. It does this by fetching the profile or post (or receiving a post via a POST to /inbox) and storing it in its database. You'll want to do this so remote videos and channels show up in your feed on your local instance, and so remote comments show up when you view a thread.

2020/02/03 6:42:27 AM UTC

@nodetube @sean there is also talk.feneas.org where some of the other projects are discussed. ForgeFed (Git issues over AP) is using that one.

2020/02/03 6:43:40 AM UTC

@mewmew @sean
> so remote comments show up when you view a thread.
could you explain that part? the rest of it is clear to me. And also how long does the caching take place, is it on a per-instance basis?

2020/02/03 6:47:03 AM UTC

@nodetube @sean if your instance didn't cache remote comments, if you viewed a video with remote comments on it, you wouldn't see the comments as they'd live only on the remote server.

Most implementations cache indefinitely, you can definitely make it configurable though. If you do, make sure to refetch pruned objects when someone tries to load them though.

2020/02/04 4:59:09 PM UTC

@mewmew @sean Thanks for the help. I'm continuing to learn a lot about ActivityPub but our conversations were a great springboard to get the ball rolling for me. Let me shoot you another ? though if you don't mind, I know you have a PeerTube instance up, how difficult was it to get up? And does PeerTube's WebTorrent integration work when run over localhost? I've been taking a look at WebTorrent the last couple days but can't seem to be able to seed via my local computer.

2020/02/04 5:53:54 PM UTC

@nodetube @sean Peertube took around an hour for me to setup so I'd say that it's not too hard (and most of that time was compiling).

No idea about the webtorrent, it's not a great protocol and I turn it off when watching videos.

2020/02/05 3:20:05 AM UTC

@mewmew @sean Did you turn it off for your whole instance or does it still run?

2020/02/05 3:20:34 AM UTC

@nodetube @sean no, just turned it off in my settings, anyone else on my instance can use it

2020/02/08 12:42:28 AM UTC

@mewmew @sean What's your criticisms of WebTorrent as a protocol?

2020/02/08 1:44:19 AM UTC

@nodetube @sean
* Leaks viewer IP addresses
* Currently not compatible with clients like qbittorrent
* Uses a lot of RAM
* High overhead when using webseeds due to the large number of HTTP requests made
* Most people have slow residential connections so the benefit of load reduction is minimal

Torrent just isn't a good protocol for streaming video over the internet, it has all the weaknesses and none of the strengths of the protocol.
replies
2
announces
1
likes
3

2020/02/08 1:46:17 AM UTC

@mewmew @nodetube @sean
>* Currently not compatible with clients like qbittorrent
what do you mean by this mewmew do you mean that i can't use with webtorrent something being seeded by qbittorrent?

2020/02/08 5:57:15 PM UTC

@mewmew @sean Yeah I agree with you 100%. Those are the exact reasons to a T why I looked into WebTorrent and decided against implementing it in NodeTube. Come to find out as well there's a lot of complexity with storing/hosting the files as well, so it's not only bad for users but it's bad for developers who would want to help in an open-source capacity as well. Maybe it could be supported/turned on with a flag but to rely on it out of the box, icky.

2020/02/08 7:52:58 PM UTC

@nodetube @sean yeah, totally fine not to support it IMO - if you federate with PeerTube you could probably still get away with not supporting it