Groups Extension

Groups are a way to organize users and notes into communities. They can be used for any purpose, such as forums, blogs, image galleries, video sharing, audio sharing, and messaging. They are similar to Discord's channels or Matrix's rooms.

Refer to Note's group property for how notes can be associated with groups.

Entity Definition

  • Name
    type
    Required
    Required
    Type
    string
    Description

    Must be pub.versia:groups/Group.

  • Name
    name
    Type
    ContentFormat
    Description

    Group name/title.

    Text only (text/plain, text/html, etc).

  • Name
    description
    Type
    ContentFormat
    Description

    Short description of the group's contents and purpose.

    Text only (text/plain, text/html, etc).

  • Name
    open
    Type
    boolean
    Description

    Whether the group is open to all users or requires approval to join.

  • Name
    members
    Required
    Required
    Type
    URI
    Description

    URI of the group's members list. URI Collection of Users.

  • Name
    notes
    Type
    URI
    Description

    URI of the group's associated notes. URI Collection of Notes.

Example Group

{
    "type": "pub.versia:groups/Group",
    "id": "ed480922-b095-4f09-9da5-c995be8f5960",
    "uri": "https://example.com/groups/ed480922-b095-4f09-9da5-c995be8f5960",
    "name": {
        "text/html": {
            "content": "The <strong>Woozy</strong> fan club"
        }
    },
    "description": {
        "text/plain": {
            "content": "A group for fans of the Woozy emoji."
        }
    },
    "open": false,
    "members": "https://example.com/groups/ed480922-b095-4f09-9da5-c995be8f5960/members",
}

Subscribing to Groups

Users may "subscribe" to a Group in order to receive all Notes posted to it. The mechanism by which federation is handled is described at the end of this document.

First, a User must send a GroupSubscribe activity to the group. The group will then respond with either a GroupSubscribeAccept or a GroupSubscribeReject activity.

If the group accepts the subscription, the user will receive all notes posted to the group. If the group rejects the subscription, the user will not receive any notes posted to the group.

GroupSubscribe

Indicates that a User wishes to subscribe to a group.

  • Name
    type
    Required
    Required
    Type
    string
    Description

    Must be pub.versia:groups/Subscribe.

  • Name
    uri
    Type
    null
    Description

    This is a Transient Entity and does not have a URI.

  • Name
    subscriber
    Required
    Required
    Type
    URI
    Description

    URI of the User subscribing to the group.

  • Name
    group
    Required
    Required
    Type
    URI
    Description

    URI of the group to subscribe to.

Example GroupSubscribe

{
    "type": "pub.versia:groups/Subscribe",
    "id": "9a7e9345-4e4a-4d5a-8301-4dbbfe777ca0",
    "subscriber": "https://bob.social/users/e9277471-8aa1-4d40-a3d0-0878e818ccdc",
    "group": "https://example.com/groups/ed480922-b095-4f09-9da5-c995be8f5960",
    "created_at": "2021-01-01T00:00:00Z"
}

GroupUnsubscribe

Indicates that a User wishes to unsubscribe from a group.

  • Name
    type
    Required
    Required
    Type
    string
    Description

    Must be pub.versia:groups/Unsubscribe.

  • Name
    uri
    Type
    null
    Description

    This is a Transient Entity and does not have a URI.

  • Name
    subscriber
    Required
    Required
    Type
    URI
    Description

    URI of the User unsubscribing from the group.

  • Name
    group
    Required
    Required
    Type
    URI
    Description

    URI of the group to unsubscribe from.

Example GroupUnsubscribe

{
    "type": "pub.versia:groups/Unsubscribe",
    "id": "9a7e9345-4e4a-4d5a-8301-4dbbfe777ca0",
    "subscriber": "https://bob.social/users/e9277471-8aa1-4d40-a3d0-0878e818ccdc",
    "group": "https://example.com/groups/ed480922-b095-4f09-9da5-c995be8f5960",
    "created_at": "2021-01-01T00:00:00Z"
}

GroupSubscribeAccept

Indicates that a Group has accepted a User's subscription request. Should be signed by the instance hosting the group.

  • Name
    type
    Required
    Required
    Type
    string
    Description

    Must be pub.versia:groups/SubscribeAccept.

  • Name
    uri
    Type
    null
    Description

    This is a Transient Entity and does not have a URI.

  • Name
    subscriber
    Required
    Required
    Type
    URI
    Description

    URI of the User subscribing to the group.

  • Name
    group
    Required
    Required
    Type
    URI
    Description

    URI of the group that accepted the subscription.

Example GroupSubscribeAccept

{
    "type": "pub.versia:groups/SubscribeAccept",
    "id": "9a7e9345-4e4a-4d5a-8301-4dbbfe777ca0",
    "subscriber": "https://bob.social/users/e9277471-8aa1-4d40-a3d0-0878e818ccdc",
    "group": "https://example.com/groups/ed480922-b095-4f09-9da5-c995be8f5960",
    "created_at": "2021-01-01T00:00:00Z"
}

GroupSubscribeReject

Indicates that a Group has rejected a User's subscription request. Should be signed by the instance hosting the group.

  • Name
    type
    Required
    Required
    Type
    string
    Description

    Must be pub.versia:groups/SubscribeReject.

  • Name
    uri
    Type
    null
    Description

    This is a Transient Entity and does not have a URI.

  • Name
    subscriber
    Required
    Required
    Type
    URI
    Description

    URI of the User subscribing to the group.

  • Name
    group
    Required
    Required
    Type
    URI
    Description

    URI of the group that rejected the subscription.

Example GroupSubscribeReject

{
    "type": "pub.versia:groups/SubscribeReject",
    "id": "9a7e9345-4e4a-4d5a-8301-4dbbfe777ca0",
    "subscriber": "https://bob.social/users/e9277471-8aa1-4d40-a3d0-0878e818ccdc",
    "group": "https://example.com/groups/ed480922-b095-4f09-9da5-c995be8f5960",
    "created_at": "2021-01-01T00:00:00Z"
}

Federation

Group federation represents a particularly challenging problem, as it requires a way to make sure every single Note posted to it is delivered to every single member of the group.

All Notes posted to a group (using the group field) must be sent to its instance's shared inbox. Groups do not have an inbox of their own.

Once this is done, the group's instance must then federate this Note to every member of the group. However, this cannot be done the "normal way", as the group's instance does not have the private key to sign the Note.

GroupFederate

The GroupFederate entity allows a group to federate a note to all of its members, without needing to sign the note itself. It contains a URI to the note being federated, which must be fetched by the receiving instances. This entity is signed by the group's instance.

  • Name
    type
    Required
    Required
    Type
    string
    Description

    Must be pub.versia:groups/Federate.

  • Name
    uri
    Type
    null
    Description

    This is a Transient Entity and does not have a URI.

  • Name
    note
    Required
    Required
    Type
    URI
    Description

    URI of the note to federate.

  • Name
    group
    Required
    Required
    Type
    URI
    Description

    URI of the group federating the note.

Example GroupFederate

{
    "type": "pub.versia:groups/Federate",
    "id": "9a7e9345-4e4a-4d5a-8301-4dbbfe777ca0",
    "note": "https://example.com/notes/ed480922-b095-4f09-9da5-c995be8f5960",
    "group": "https://example.com/groups/ed480922-b095-4f09-9da5-c995be8f5960",
    "created_at": "2021-01-01T00:00:00Z"
}