Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do announce for all actions posted to a community. #662

Closed
dessalines opened this issue Apr 24, 2020 · 14 comments
Closed

Do announce for all actions posted to a community. #662

dessalines opened this issue Apr 24, 2020 · 14 comments
Labels
area: federation support federation via activitypub

Comments

@dessalines
Copy link
Member

dessalines commented Apr 24, 2020

Object creates should look like:

...
 "to": [
        "https://www.w3.org/ns/activitystreams#Public",
        "https://honk.tedunangst.com/u/tedu/followers"
      ],

And followers looks like:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://mastodon.social/users/dessalines/followers",
  "type": "OrderedCollection",
  "totalItems": 114,
  "first": "https://mastodon.social/users/dessalines/followers?page=1"
}

and first looking like

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://mastodon.social/users/dessalines/followers?page=1",
  "type": "OrderedCollectionPage",
  "totalItems": 114,
  "next": "https://mastodon.social/users/dessalines/followers?page=2",
  "partOf": "https://mastodon.social/users/dessalines/followers",
  "orderedItems": [
    "https://moon.holiday/users/runascesya", // Notice these aren't inbox urls, those still need to be fetched
  ]
}

Or, from activitypub:

The inbox is determined by first retrieving the target actor's JSON-LD representation and then looking up the inbox property. If a recipient is a Collection or OrderedCollection, then the server MUST dereference the collection (with the user's credentials) and discover inboxes for each item in the collection. Servers MUST limit the number of layers of indirections through collections which will be performed, which MAY be one.

This involves building both a followers paged collection, and a buildToList

We need to build a buildToList method, which:

  • Does recurring fetches on the followers collection (has to do page fetches here too) to get users, then another to get their inboxes.
    • Mastodon has this in a user's endpoints: "endpoints":{"sharedInbox":"https://mastodon.social/inbox"}
  • Remove the specific inbox if there's a sharedInbox.
  • Dedupe in case there's multiples of the same shared inbox.
@dessalines dessalines added area: federation support federation via activitypub Component: Backend labels Apr 24, 2020
@Nutomic
Copy link
Member

Nutomic commented Apr 24, 2020

Do we really want to make community followers public? That was implemented before, but I removed it because it seems like a privacy problem. And more importantly its not needed, because the only actor that directly addresses the community followers is the community itself.

@Nutomic
Copy link
Member

Nutomic commented Apr 24, 2020

So in fact all you need to do when sending out a community post is query the followers of that community from the database, and selecting the inbox/sharedinbox. The only reason you would need network calls for that is if the actors need to be refreshed.

@dessalines
Copy link
Member Author

I'm seeing this in some of the docs:

If the post is public, however, we’ll use the sharedInbox property. This might be https://example.com/inbox. Note the absence of username. Many users on the same instance will have the same sharedInbox, so we will deduplicate the list. In the end, we should have a list of URL endpoints.

So for example, in building the inboxes, if I query the CommunityFollower table, it might give me :

[ 
  instance1/user1/inbox,
  instance1/user2/inbox,
  instance2/user1/inbox,
]

And since its public, I need to dedupe these to just

[ 
  instance1/inbox,
  instance2/inbox
]

I'll also add something like:

  fn get_shared_inbox_url(&self) -> String {
    format!("{}/inbox", &Url::parse(strip out everything but the domain for self.actor_id()))
  }

@asonix
Copy link
Collaborator

asonix commented Apr 25, 2020

It's best you don't try to generate URLs for foreign domains. Am actor will tell you were it's shared inbox is, if it's server supports shared inboxes.

@dessalines
Copy link
Member Author

dessalines commented Apr 25, 2020

Right now at least, we're only storing the actor_id in the DB row for that user and community

I'm looking at pleromas user table right now, and the only url fields they store are ap_id, follower_address, following_address, they don't store the inbox, or outbox, so I'm not sure how they are even getting that shared_inbox url... and I have to assume they're generating the inbox url from the actor_id just like we are.

I'm not sure which DB columns I should add if any, I'd originally thought these would all conform to the standard of actor_id/followers, actor_id/following, etc.

edit: Ahh looks like they recently added it: https://git.pleroma.social/pleroma/pleroma/-/blob/develop/priv/repo/migrations/20200401072456_users_add_inboxes.exs

I think as part of this then, I'll do a migration to at least add those 4 columns.

@dessalines
Copy link
Member Author

@asonix Do you know of a good list of actor_urls I should be storing in the DB for each user?

@Nutomic
Copy link
Member

Nutomic commented Apr 25, 2020

We could also leave those DB columns for later, seeing as we are only federating between Lemmy instances for now.

@dessalines
Copy link
Member Author

dessalines commented May 5, 2020

Okay I realized we're doing something kind of wrong with sending activitypub messages. Here's my problem:

  • 3 servers, A, B, and C.
  • Users on A and C both subbed to B, the center.
  • Instance A only sees that it has a local user subbed to B.
  • User on A makes a post, it sends it to B.
  • User on C doesn't receive this message

The idea here is that in theory a following relationship is tracked on both sides: as part of a followers collection associated with the actor on the originating server and as part of a followed collection associated with the actor on the receiving server. So the originating server doesn’t need to explicitly list recipients. Instead, the receiving server can take the ID of the activity’s actor, look up its own list of who’s following that actor, and deliver the object to each member of that list.

This paragraph seems to say that wherever the actor lives, it acts as a sort of "forwarding server", that forwards messages to everyone subscribed to it. So A and C only send to B/shared_inbox, which then forwards it to all the community followers.

https://www.w3.org/TR/activitypub/#delivery

So we need to alter lemmy to make sure that the actor's server is forwarding that message to all non-local servers, except the one where the message came from.

@Nutomic
Copy link
Member

Nutomic commented May 5, 2020

Right, this is why the community needs to announce the post. I kind of forgot about this issue, but its definitely more important than the comment fetching, so I will work on this next.

@dessalines
Copy link
Member Author

I don't think its an announce, but really just forwarding that create to the correct other recipients, when it receives it in its shared inbox where the actor really lives.

Its the same thing with mastodon, there's a users followers, that the sender doesn't really know about, it just sends it to https://honk.tedunangst.com/u/tedu/followers, which equates to the shared_inbox of /u/tedu, then the /u/tedu instance forwards that activity to all the other followers.

@asonix
Copy link
Collaborator

asonix commented May 6, 2020

I think it's general mastodon practice to use "Announce" even when creating new posts. the "Create" activity, in mastodon's view, isn't important. Servers Announce new posts to each other all the time.

Knowing this, in my view, Create is a client2server activity to tell the server to create a resource, and Announce is how the server tells other servers about the created resource.

@dessalines
Copy link
Member Author

dessalines commented May 6, 2020

I think announce is "boosting / sharing" : https://www.w3.org/TR/activitypub/#announce-activity-inbox. In the case of communities, we're just talking about making sure things are pushed to all the community's followers.

I think the difference here, is with masto, when you make a post, it goes to your followers, which your instance already has. But with federated communities, you might be posting to a community that lives elsewhere, and only it knows all of its followers.

@Nutomic Nutomic mentioned this issue May 6, 2020
45 tasks
@asonix
Copy link
Collaborator

asonix commented May 6, 2020

That makes sense. So you send the Create activity to the server hosting the community, and that server then Announces the new post/comment to it's members.

That's interesting, because it will mean that posts and comments really do "live" on the server hosting the community, and not necessarily the server the user is connected to.

@Nutomic
Copy link
Member

Nutomic commented May 6, 2020

@dessalines dessalines changed the title Add shared inboxes / properly do followers collection, and a :to field Do announce for all actions posted to a community. May 28, 2020
@Nutomic Nutomic closed this as completed Jun 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: federation support federation via activitypub
Projects
None yet
Development

No branches or pull requests

3 participants