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

Add groups support #19059

Draft
wants to merge 49 commits into
base: main
Choose a base branch
from

Conversation

ClearlyClaire
Copy link
Contributor

@ClearlyClaire ClearlyClaire commented Aug 26, 2022

⚠️ Do not merge ⚠️

This PR is not intended to be merged outside of purely development environments until it's finished. While it has reached a pretty stable state, groups are a complicated topic, and the database model, API and protocol design may change before the PR gets merged, with no clear migration path between versions of this PR.

⚠️ Merging this on your instance before this is reviewed will likely result in incompatibilities and migration issues.

Basic expectations around groups

Nothing is set in stone yet, but what we are going for is something along those lines:

  • groups have a set of members and administrators/moderators
  • only group members can post in a group
  • posts and replies within a group all have the same audience, set by the group (group members, and potentially publicly-viewable as well): no public/unlisted/followers-only/direct
  • posts are viewed in a per-group timeline and not on the home timeline
  • new members may or may not need to be approved (group-specific settings)
  • moderators can kick/ban group members and delete individual posts
  • ideally, users should be able to report group posts not only to server moderators but to group moderators as well, and have a choice in that (e.g. be able to chose not to report to group moderators in case they are wanting to report the group's behavior as a whole to their server's moderators)

Interface

Video overview

demo.mp4

Viewing and posting

image

Pending and rejected posts

While a priori moderation isn't planned on Mastodon's side on the short term, interacting with remote groups means you can't synchronously know whether your posts are accepted. They may have a priori moderation, or there might be federation hiccups. For these reasons, your posts may be pending or eventually rejected

Pending Rejected
image image

Group administration dropdown

image

Group members list (with group administration dropdown)

image

Server administration interface

image

image

image

REST API

⚠️ The described API is subject to change and the description is documented for discussion.

New OAuth scopes

  • read:groups
  • write:groups
  • admin:read:groups
  • admin:write:groups

New entities

Group:

  • id: string, local identifier for the group
  • display_name: string, name of the group
  • created_at: string (ISO 8601 Datetime), date at which the group was created
  • note: string, description of the group
  • uri: string, global (ActivityPub) identifier for the group
  • url: string, user-friendly URL for the group
  • avatar: string, URL to a possibly animated image to be used as icon for the group
  • avatar_static: string, URL to an image to be used as icon for the group
  • header: string, URL to a possibly animated image to be used as a cover/header image for the group
  • header_static: string, URL to an image to be used as a cover/header image for the group
  • domain: string, domain hosting the group. null if the group is hosted locally
  • locked: boolean, false if the group is expected to automatically accept membership requests
  • statuses_visibility: boolean, 'public' is the only value so far and means all posts are expected to be public
  • membership_required: boolean, only true so far, meaning that it is expected that only members can post

GroupMembership:

  • id: string, internal identifier for the membership
  • account: Account entity, which user this membership is about
  • role: string, role of the user within the group. Valid values are admin, moderator and users

Existing entities with new or changed attributes

Status:

  • new optional group attribute: Group in which the status exists. When this attribute is set, visibility must be "group"
  • new value for the visibility attribute: "group". When visibility is "group", the Status has a group attribute
  • new optional approval_status attribute with the following possible values: "pending", "approved", "rejected", "revoked". Its absence is equivalent to "approved" and does not require any special handling. It is currently only used for group posts but may be used in other cases in the future (e.g. reply control policies). "pending" means it has not been approved yet, while "rejected" means it has been rejected in a priori moderation / automatic filtering / access rules, and "revoked" means it has been denied after being first being approved for a time

New endpoints

  • POST /api/v1/groups (requires write or write:groups and also requires proper user permissions): create a group with the given attributes (display_name, note, avatar and header). Sets the user who made the request as group administrator
  • GET /api/v1/groups (requires read or read:groups): returns an array of Group entities the current user is a member of
  • GET /api/v1/groups/:id (requires read or read:groups): returns the Group entity describing a given group
  • POST /api/v1/groups/:id/join (requires write or write:groups): joins (or request to join) a given group
  • POST /api/v1/groups/:id/leave (requires write or write:groups): leaves a given group
  • GET /api/v1/groups/:id/memberships (requires read or read:groups). Has an optional role attribute that can be used to filter by role (valid roles are "admin", "moderator", "user").

Group administration

All of these require the current account to be an admin of the group:

  • PUT /api/v1/groups/:group_id (requires write or write:groups): update group attributes (display_name, note, avatar and header)
  • DELETE /api/v1/groups/:group_id (requires write or write:groups): irreversibly deletes the group

Group moderation

All of these require the current account to be an admin/moderator of the group:

  • GET /api/v1/groups/:group_id/membership_requests (requires read or read:groups): returns an array of Account entities representing pending requests to join a group
  • POST /api/v1/groups/:group_id/membership_requests/:account_id/authorize (requires write or write:groups): accept a pending request to become a group member
  • POST /api/v1/groups/:group_id/membership_requests/:account_id/reject (requires write or write:groups): reject a pending request to become a group member
  • DELETE /api/v1/groups/:group_id/statuses/:id (requires write or write:groups): delete a group post (actually marks it as revoked if it is a local post)
  • POST /api/v1/groups/:group_id/kick?account_ids[]=… (requires write or write:groups): kick one or more group members
  • GET /api/v1/groups/:group_id/blocks (requires read or read:groups): list accounts blocked from interacting with the group
  • POST /api/v1/groups/:group_id/blocks?account_ids[]=… (requires write or write:groups): block one or more users. If they were in the group, they are also kicked of it
  • DELETE /api/v1/groups/:group_id/blocks?account_ids[]=… (requires write or write:groups): lift one or more blocks
  • POST /api/v1/groups/:group_id/promote?role=new_role&account_ids[]=… (require write or write:groups): promote one or more accounts to role new_role. An error is returned if any of those accounts has a higher role than new_role already, or if the role is higher than the issuing user's. Valid roles are admin, and moderator and user.
  • POST /api/v1/groups/:group_id/demote?role=new_role&account_ids[]=… (require write or write:groups): demote one or more accounts to role new_role. Returns an error unless every of the target account has a strictly lower role than the user (you cannot demote someone with the same role as you), or if any target account already has a role lower than new_role. Valid roles are admin, moderator and user.

Instance moderation

  • GET /api/v1/admin/groups (requires admin:read:groups and permissions to manage users): list groups known to the instance. Mimics the interface of /api/v1/admin/accounts
    Optional query parameters:
    • origin (string): "remote" to list only remote groups, or "local" to list only local groups
    • status (string): "active" to list only groups that have not been suspended, or "suspended" to list only suspended groups
    • by_domain (string): search for groups originating from a specific domain
    • display_name (string): filter groups on display name
    • order (string): "active" to sort by date of most recent post, "recent" to sort by group creation date
    • by_member (string): search groups in which a specific account (given by account id) is a member
  • GET /api/v1/admin/groups/:group_id: return basic group information
  • POST /api/v1/admin/groups/:group_id/suspend (requires admin:write:groups and permissions to manage users): suspends a group
  • POST /api/v1/admin/groups/:group_id/unsuspend (requires admin:write:groups and permissions to manage users): lift a suspension
  • DELETE /api/v1/admin/groups/:group_id (requires admin:write:groups and permissions to delete user data): deletes an already-suspended group

Changes to existing endpoints

  • POST /api/v1/statuses: accepts the new value "group" for the visibility parameter, and accepts a new group_id parameter. When visibility is set to "group", a valid group_id must be provided, and when a group_id is provided, visibility must be set to "group". A reply cannot have a different group_id than the post it is in reply to.

ActivityPub (federation)

Context and survey of existing work

Other fediverse projects have or are working on similar functionality, though there is no definite standard yet, and there are still many open questions. From what I have gathered, the main implementations seem to be:

  • Smithereen, using FEP-400e to submit posts to the group's sm:wall collection
  • Pixelfed, supposedly implementing Smithereen's protocol
  • Streams-related projects (Friendica, Hubzilla, …) which seems to aim for maximizing compatibility with every ActivityPub implementation, including those which do not have explicit support for groups
  • Lemmy, which seems to mostly reuse the Follow and Announce flow

At the same time, other projects such as Mobilizon and Peertube use Group actors for different purposes.

Implementation in this PR

⚠️ This is subject to change.

Remote users interacting with local groups and local users interacting with remote groups are supported. For the time being, local groups can only have local moderators, and local users can only moderate local groups.

At this time, Mastodon does not perform JSON-LD compaction and expects implementations to use the shorthand for the described attributes, but produces a valid context properly qualifying them.

  • groups actors are of type PublicGroup, and are expected to provide the following attributes:
    • wall: an identified public OrderedCollection of all approved group posts
    • members: a Collection or OrderedCollection of group members
    • name: a human-readable name for the group
    • publicKey: public key used for signing requests
    • attributedTo (optional): array of non-group actors with group moderation powers
    • summary (optional): a description of the group
    • icon (optional): icon for the group, akin to profile avatars
    • image (optional): header illustration for the group, akin to profile headers
    • manuallyApprovesMembers (optional): true if the group is expected to not automatically approve new members (similar to manuallyApprovesFollowers)
    • suspended (optional): indicates that the group has been temporarily suspended and should not be interacted with
  • joining a group works by sending the group actor a Join activity and expecting an Accept in return
  • leaving a group works by sending the group actor a Leave activity
  • group posts have only the group members in their explicit audience through the to attribute
  • posts are sent using FEP-400e by sending a Create activity exclusively to the group's inbox, with the embedded object targeting the group's wall collection. Such an activity can be denied in /a priori/ moderation or access control via a Reject activity
  • posts from remote groups are received through an Add activity from the group actor, adding the post to its wall collection. The post is fetched and MUST include the wall collection as its target. If the added post is a local post, it will be marked as approved.
  • users Delete their group posts, and the group actor distributes a Remove activity to reflect it. In addition, if the Delete activity is signed, the group actor may forward it
  • posts can be removed by group moderators, in which case the group actor will send a Remove activity
  • a group can Update itself or Delete itself like Person actors

Examples

Group actor:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://w3id.org/security/v1",
    {
      "toot": "http://joinmastodon.org/ns#",
      "discoverable": "toot:discoverable",
      "suspended": "toot:suspended",
      "sm": "http://smithereen.software/ns#",
      "wall": {
        "@id": "sm:wall",
        "@type": "@id"
      },
      "members": {
        "@id": "sm:members",
        "@type": "@id"
      },
      "PublicGroup": "toot:PublicGroup",
      "manuallyApprovesMembers": "toot:manuallyApprovesMembers"
    }
  ],
  "id": "https://mastodon.social/groups/1",
  "type": "PublicGroup",
  "inbox": "https://mastodon.social/groups/1/inbox",
  "outbox": "https://mastodon.social/groups/1/outbox",
  "name": "Mastodon development",
  "url": "https://mastodon.social/groups/1",
  "published": "2022-09-19T00:00:00Z",
  "wall": "https://mastodon.social/groups/1/wall",
  "members": "https://mastodon.social/groups/1/members",
  "summary": "<p>A group to discuss Mastodon development and make screenshots of the work-in-progress group feature.</p>",
  "manuallyApprovesMembers": true,
  "attributedTo": [
    "https://mastodon.social/users/Gargron",
  ],
  "publicKey": {
    "id": "https://mastodon.social/groups/1#main-key",
    "owner": "https://mastodon.social/groups/1",
    "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwwIG7x+jVanVg+C1Cb8w\nfYMrAWaK6fIu8amptKI4pChe7YmRWOzhulgTEBjSYSuwvO70kiEKkUzxUARlPRxC\nOehlw2+gsv2PlGfGu3VViq9+jZO41El3s8qOFYnZ+yfHX/SZlHGsujQLnoLP3rPZ\nc5GkaDJ3SHucTzUkFuf+znA7lESFMmK4oM7JtoSFrGlD0u8GObKKXjhenPxt8kxN\n9zKpwA/u4mi91vsEjIctoBbYo90tY5vxKJlTYQq7Btz6Xe6uKibWRXhMES9Col/7\nzG+PQ/RvdiKL7Q5T8R4H9t4bk+RmNFqFPQhmKkq1NX3kw7/uZPay+z4qCBGYud44\nRwIDAQAB\n-----END PUBLIC KEY-----\n"
  },
  "tag": [],
  "endpoints": {
    "sharedInbox": "https://mastodon.social/inbox"
  },
  "icon": {
    "type": "Image",
    "mediaType": "image/png",
    "url": "https://mastodon.social/system/groups/avatars/109/027/262/422/883/263/original/f6f5deced1bec83a.png"
  },
  "image": {
    "type": "Image",
    "mediaType": "image/png",
    "url": "https://mastodon.social/system/groups/headers/109/027/262/422/883/263/original/e5eb3fa2014b9320.png"
  }
}

Join activity:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://mastodon.dev/c07d86b4-55bd-413c-a45b-71778cdeca65",
  "type": "Join",
  "actor": "https://mastodon.dev/users/claire",
  "object": "https://mastodon.social/groups/1"
}

Create activity:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "toot": "http://joinmastodon.org/ns#",
    }
  ],
  "id": "https://mastodon.dev/users/claire/statuses/109086682464796744/activity",
  "type": "Create",
  "actor": "https://mastodon.dev/users/claire",
  "published": "2022-09-30T09:37:57Z",
  "to": [
    "https://mastodon.social/groups/1/members"
  ],
  "cc": [],
  "object": {
    "id": "https://mastodon.dev/users/claire/statuses/109086682464796744",
    "type": "Note",
    "published": "2022-09-30T09:37:57Z",
    "url": "https://mastodon.dev/@claire/109086682464796744",
    "attributedTo": "https://mastodon.dev/users/claire",
    "to": [
      "https://mastodon.social/groups/1/members"
    ],
    "cc": [],
    "content": "<p>hello</p>",
    "target": {
      "type": "OrderedCollection",
      "id": "https://mastodon.social/groups/1/wall",
      "attributedTo": "https://mastodon.social/groups/1"
    }
  }
}

Add activity:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "type": "Add",
  "actor": "https://mastodon.social/groups/1",
  "object": "https://mastodon.dev/users/claire/statuses/109086682464796744",
  "target": "https://mastodon.social/groups/1/wall"
}

TODO

This is a rough outline of the planned development, but as stated above, “finished” steps will likely be revisited as UX or protocol considerations emerge when working on other steps.

  • models and database schema for local groups, members, group posts
  • API for posting in groups and seeing group posts
  • user interface for posting in groups and seeing group posts
  • API for basic group moderation (kicking/banning someone from a group, deleting individual group posts, approving or rejecting group members)
  • basic user interface for the aforementioned moderation actions
  • API for seeing group information, group members and moderators, joining and leaving groups
  • user interface for seeing group information, joining and leaving groups
  • API for creating groups
  • user interface for creating groups (partially done, it exists but does not offer setting description, avatar or header image)
  • API for deleting groups
  • user interface for deleting groups
  • ActivityPub support for joining, leaving, and posting within a group (done up to possible upcoming protocol changes)
  • ActivityPub support for cross-instance moderation (group moderators on a different server than the group actor) (done up to possible upcoming protocol changes, also needs more testing)
  • models and database schema for reports within groups
  • REST API changes for reporting posts to group moderators
  • user interface changes for reporting posts to group moderators
  • ActivityPub support for reporting posts to group moderators

This project was funded through the NGI0 Discovery Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 825322.

@ClearlyClaire ClearlyClaire added api REST API, Streaming API, Web Push API ui Front-end, design work in progress Not to be merged, currently being worked on activitypub Protocol-related changes, federation NLnet Funded by NLnet, see https://nlnet.nl/project/Mastodon/ labels Aug 26, 2022
@ClearlyClaire ClearlyClaire force-pushed the features/nlnet-groups branch from 9ad4ba2 to d4b88c4 Compare August 26, 2022 13:49
@Tagadda
Copy link

Tagadda commented Aug 27, 2022

should boosts within groups be possible? should it be possible for outside public posts to be boosted in groups?

I guess users should be able to boosts within the group, according to the visibility of the post. Outside public posts could be boosted in public groups only, so the replies would be public too.
Eventually, replies to this boost from within a group would not mention the author in the post ?

how should posts from someone who has left/been kicked out of a group be handled? should the author still be able to access them? how? what about replies?

When a user leave a private group, they should not access posts inside the group, including their own. And that sounds not okay to me I guess, not seeing my own posts...
Maybe we need to provide a way for the user to delete all activity in the group, or something else when they leave/get kicked ?

@ClearlyClaire
Copy link
Contributor Author

should boosts within groups be possible? should it be possible for outside public posts to be boosted in groups?

I guess users should be able to boosts within the group, according to the visibility of the post. Outside public posts could be boosted in public groups only, so the replies would be public too. Eventually, replies to this boost from within a group would not mention the author in the post ?

It has been decided that, at least initially, we will not support any kind of boosts within or across groups: otherwise publicly-viewable group posts will only be seen within the context of the group and won't be boostable within or outside of the group. Public non-group posts won't be boostable in the group either.

how should posts from someone who has left/been kicked out of a group be handled? should the author still be able to access them? how? what about replies?

When a user leave a private group, they should not access posts inside the group, including their own. And that sounds not okay to me I guess, not seeing my own posts... Maybe we need to provide a way for the user to delete all activity in the group, or something else when they leave/get kicked ?

The most likely approach we are going to take is have you be able to review your posts from groups you have left or have been kicked out of, and be able to delete them. It's not completely decided yet, though, and it's not completely sure how the UI for that would look like.

@ClearlyClaire
Copy link
Contributor Author

After lengthy discussions, I think we will be making the following decisions for the initial implementation:

  • no boosts/reblogs functionality with groups
  • mentions of non-members won't be processed at all. This may eventually be changed to create mention tags for non-members but without triggering notifications, addressing changes or other behavior currently associated with mentions, but if so, that will come later.
  • groups created from Mastodon will require approval of new members to limit moderation and scaling issues
  • only group with publicly-viewable posts will be supported. While this may change in the long run, restricting ourselves to publicly-viewable posts for now avoids some potential protocol difficulties and moderation issues

@ClearlyClaire ClearlyClaire force-pushed the features/nlnet-groups branch 2 times, most recently from 5a2bde8 to 7fe590e Compare September 16, 2022 15:53
@trwnh
Copy link
Member

trwnh commented Sep 16, 2022

POST /api/v1/groups/:group_id/:group_id/kick?account_ids[]=… has :group_id in there twice

@ClearlyClaire
Copy link
Contributor Author

POST /api/v1/groups/:group_id/:group_id/kick?account_ids[]=… has :group_id in there twice

Fixed

@ClearlyClaire ClearlyClaire force-pushed the features/nlnet-groups branch 2 times, most recently from 867b084 to 7730865 Compare September 20, 2022 21:03
@ClearlyClaire ClearlyClaire force-pushed the features/nlnet-groups branch 5 times, most recently from ac41b9c to ebf7df2 Compare September 29, 2022 06:36
@ClearlyClaire ClearlyClaire force-pushed the features/nlnet-groups branch 4 times, most recently from 85eefb8 to 2c31ed4 Compare September 30, 2022 09:59
@ClearlyClaire ClearlyClaire marked this pull request as ready for review September 30, 2022 13:10
end

# Kick existing members that we are banning
memberships.each(&:destroy) # TODO: federate
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for later

@annando
Copy link

annando commented Mar 30, 2024

In Friendica people use groups for different reasons. One is the classical discussion group. The other is to extend your audience, which means that you then post to your followers and additionally to one or more groups. This is separated via ! or @. This then also could control if that post appears on your profile.

@angusmcleod
Copy link

angusmcleod commented Apr 18, 2024

Just a note that we have also been discussing the reconciliation of FEP-400e (e.g. Smithereen) and FEP-1b12 (e.g. Lemmy) in the context of Discourse, NodeBB, Flarum and other "threaded" implementations here.

@grishka
Copy link
Member

grishka commented Apr 18, 2024

FEP-400e would also work for forum-style experiences. If you imagine a forum in its simplest 00s form, e.g. phpBB/IPB/vBulletin, I'd map it to ActivityPub like this:

  • A section (phpBB calls them "forums" iirc) is a Group actor.
  • The actor has a topics collection, and possibly pinnedTopics as well.
  • A topic is defined by its first post, with name being the title and the content being the content.
  • Topics are created "into" the topics collection of the forum section actor.
  • Further posts in a topic are simply replies either to the first post or to other existing posts in it.
  • Pinning works by sending Add and Remove activities for the pinnedTopics collection (same way as post pinning works in Mastodon right now).
  • Moderation actions are sent on behalf of the forum section actor.
  • It would probably make sense that one can follow such an actor to receive new topics as they are created?

@angusmcleod
Copy link

@grishka That's not how we've implemented things so far, but it's good to think through the alternatives. Your insight would be most welcome in our working group!

@annando
Copy link

annando commented Apr 19, 2024

One thing with Lemmy's approach I really appreciate, is the usage of the audience field. This means that you don't even need to address a group via @ or ! inside the content, but instead you could create your very own front end area for group postings that set this field. The addressing via @ is a really good (and reliably working) workaround for systems without a native group support.

@shleeable
Copy link
Contributor

@ClearlyClaire Could we get an statement on the status of this PR? Groups is the single most important thing I'm looking forward to.

@grishka
Copy link
Member

grishka commented Sep 24, 2024

I've since had more thoughts about my implementation and I'm going to change it a bit.

The problem I realized I have is how comments/replies work. If done naively, like it's done now in Smithereen, the replies collection on each wall post is owned by the author of that post, so it's on them to maintain it. This is suboptimal:

  • They can modify the collection, either accidentally or on purpose
  • If their server goes down, the replies could no longer be loaded by other servers
  • Moderation is harder because you rely on that actor to honor moderation actions by updating the collection accordingly

So I'm going to soon experiment with a different approach: replies and inReplyTo will still exist, of course, but you would create your comments into a separate collection intended for comments, owned by the same actor that owns the collection for commentable objects themselves. This would also make it much easier to synchronize comments between servers, because it'll be just a single flat collection instead of this recursive replies madness. But most importantly, it would give the owner all the same control they already have over wall posts themselves.

@trwnh
Copy link
Member

trwnh commented Sep 24, 2024

@grishka have you considered having that "single flat collection" be context?

@trwnh trwnh mentioned this pull request Nov 18, 2024
@mjankowski mjankowski added moderation Administration and moderation tooling javascript Pull requests that update Javascript code ruby Pull requests that update Ruby code area/web interface Related to the Mastodon web interface labels Dec 1, 2024
@FediVideos
Copy link

Just FYI, a lot of people have been asking via FediTips if there is any feature like this on Mastodon. They basically want to come off Meta and are willing to do so if there is a Facebook Groups style feature, which this seems to be.

Any progress at all on this?

@Leatherface75
Copy link

Leatherface75 commented Jan 19, 2025

Just FYI, a lot of people have been asking via FediTips if there is any feature like this on Mastodon. They basically want to come off Meta and are willing to do so if there is a Facebook Groups style feature, which this seems to be.

Any progress at all on this?

Well i think Friendica is a better alternative for Meta users.
It works more like Facebook and via addon you can also integrate Bluesky/ATProto and a few other standards.
It also supports Quote Share posts that is another requested feature.
And because it as standard talks with ActivityPub protocol they still can communicate with Mastodon people.

@grishka
Copy link
Member

grishka commented Jan 19, 2025

The Friendica approach is still bad because your group posts also appear on your profile. It's a crutch on top of there being no groups. It's a quick-and-dirty workaround that leaks straight into the UX. Mastodon also has these pseudo-groups in the form of bots that boost everything that mentions them, the only difference being that there's no dedicated syntax for that, it's just regular mentions.

have you considered having that "single flat collection" be context?

I did, but iirc that property is already used by some other implementations for some other purposes, so I had to invent something brand new to rule out any ambiguity that may arise otherwise.

@Leatherface75
Copy link

The Friendica approach is still bad because your group posts also appear on your profile. It's a crutch on top of there being no groups. It's a quick-and-dirty workaround that leaks straight into the UX. Mastodon also has these pseudo-groups in the form of bots that boost everything that mentions them, the only difference being that there's no dedicated syntax for that, it's just regular mentions.

I don't understand what you mean.

@grishka
Copy link
Member

grishka commented Jan 19, 2025

If I remember correctly, you post in Friendica groups by posting to your profile but starting with !username of the group. It would then Announce your post to all its followers.

@Leatherface75
Copy link

Leatherface75 commented Jan 19, 2025

If I remember correctly, you post in Friendica groups by posting to your profile but starting with !username of the group. It would then Announce your post to all its followers.

It shows for the followers in that group yes as it should but not in your profile.

@annando
Copy link

annando commented Jan 19, 2025

@Leatherface75 @grishka to be exact: A post created with ! will only be sent to the group account, which will then be re-sent to all group members. The Audience header will also be set to the group. Such posts aren't sent to the followers of the user.

@grishka of course these posts will also be visible in the user's outbox, as it is a post created by that user, just as any comments will also be part of the outbox.

@imajons
Copy link

imajons commented Jan 22, 2025

Logging into my very old Github account to find out if GROUPS are coming to Mastodon. Leaving Meta with all my friends and family but this is the sole reason we are still hanging around there. Is this actually happening and if so when?

@FediVideos
Copy link

FediVideos commented Feb 1, 2025

In the last couple of weeks have had even more people getting in touch via FediTips asking if there is a Facebook Groups equivalent they can move to. People are desperate to move off Facebook and are looking at the Fedi right now (especially Mastodon), in the words of one message today: "there is momentum".

Is there any word at all on when/if Mastodon groups will actually happen, and if so will it provide private groups in a similar manner to FB Groups?

Well i think Friendica is a better alternative for Meta users.

Friendica isn't really suitable for non-technical people in its current form, it doesn't have an abuse reporting feature for example. I love Friendica but it isn't ready for non-techies yet. And it doesn't have an FB groups equivalent, which is the topic of this pull request.

@Leatherface75
Copy link

Leatherface75 commented Feb 1, 2025

In the last couple of weeks have had even more people getting in touch via FediTips asking if there is a Facebook Groups equivalent they can move to. People are desperate to move off Facebook and are looking at the Fedi right now (especially Mastodon), in the words of one message today: "there is momentum".

Is there any word at all on when/if Mastodon groups will actually happen, and if so will it provide private groups in a similar manner to FB Groups?

Well i think Friendica is a better alternative for Meta users.

Friendica isn't really suitable for non-technical people in its current form, it doesn't have an abuse reporting feature for example. I love Friendica but it isn't ready for non-techies yet. And it doesn't have an FB groups equivalent, which is the topic of this pull request.

Yes Friendica supports Gruops and that's what this PR is supporting so i don't understand what you mean.
Maybe Meta users are missing some features but that is another discussion.

@grishka
Copy link
Member

grishka commented Feb 1, 2025

(No, this PR implements the Smithereen protocol)

@Leatherface75
Copy link

(No, this PR implements the Smithereen protocol)

I'm not interested in a new protocol that is not compatible with other ActivityPub solutions.
Then we have same problem as the ATProto/ActivityPub protocols between Bluesky and Fediverse.

@grishka
Copy link
Member

grishka commented Feb 1, 2025

I've already written here why I made Smithereen groups the way they are. There were no other solutions to avoid leaking the protocol into the UX.

(though I am going to change that a bit soon — I'll make the comments on wall posts go into a separate collection, like I've done for photo albums, instead of sm:wall together with posts themselves)

@annando
Copy link

annando commented Feb 2, 2025

@FediVideos What do you mean with "abuse reporting feature"? Friendica has got a report functionality.

Back to the topic: If this PR changes anything on how to handle accounts with the type Group (like subscribing, unsubscribing or sending a post to them), then Mastodon users will lose access to Lemmy, kbin, mbin, gup.pe, Friendica groups, Peertube channels (which are groups as well) and partially Wordpress (which uses groups under certain circumstances).

@trwnh
Copy link
Member

trwnh commented Feb 2, 2025

If this PR changes anything on how to handle accounts with the type Group

at present this PR doesn't use the type Group, it uses an extension type PublicGroup

subscribing, unsubscribing or sending a post to them

furthermore, this PR at present doesn't use Follow, it uses Join/Leave. it uses members instead of followers (so one can follow a group without being a member). it uses FEP-400e ("Smithereen protocol") to have members send a Create with target of a wall, and then the PublicGroup issues an Add with the same target of the same wall. members can also Delete their posts and the PublicGroup will Remove the corresponding post.


to address potential responses ahead-of-time:

  • the PR is a draft for a reason, and has been a draft this entire time for that reason: it's not ready yet. there are unanswered questions about the way these "groups" interact with and across "servers", and literally everything is subject to change, up to and including the protocol (and all the way down to the core data model and associated UX).
  • in a lot of ways, the current usage of Group is not at all consistent. Lemmy, kbin, mbin, gup.pe, Friendica, Peertube, and Wordpress might all declare the same type value of Group for certain actors, but these actors do not all behave in the same way. there are no guarantees that just because some actor describes itself as a Group that it will necessarily produce Create, Add, Announce, etc. according to any protocol.
  • the Group type in AS2 currently has no special considerations and therefore does not behave in a way that fits with the idea of a "group" as implemented in this PR. at present, an AS2 Group is no different than a Person or Organization, or any other type! notably, this interpretation diverges from the concept of a "group" in other specs like FOAF or vCard. AS2 Group does not have members in the same way or similar way that foaf:member and vcard:hasMember are used to represent membership. but this might change depending on the work of https://github.com/swicg/groups in the future. (possibly/probably also https://github.com/swicg/forums has overlap here.)

@annando
Copy link

annando commented Feb 2, 2025

@trwnh Currently Group is used by every system in a way that is compatible with practically every system, since these account types behave identical to any other account type. And I think that this is important.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
activitypub Protocol-related changes, federation api REST API, Streaming API, Web Push API area/web interface Related to the Mastodon web interface javascript Pull requests that update Javascript code moderation Administration and moderation tooling NLnet Funded by NLnet, see https://nlnet.nl/project/Mastodon/ rebase needed 🚧 ruby Pull requests that update Ruby code ui Front-end, design work in progress Not to be merged, currently being worked on
Projects
None yet
Development

Successfully merging this pull request may close these issues.