# Social Extension

Lets users post notes, with visibility, mentions, replies, quotes and a collection of each user's notes.

Extension name: `pub.versia:social`

The Social extension lets [Users](/entities/user) post [Notes](#note): text, images and other media, which other users can reply to and quote. It also gives each user a [collection of their notes](#notes-collection) and a list of featured notes.

Other extensions build on it, such as [Likes](/extensions/likes), [Share](/extensions/share), [Reactions](/extensions/reactions), [Polls](/extensions/polls), [Groups](/extensions/groups) and [Interaction Controls](/extensions/interaction-controls).

> Notes are not just limited to microblogging. They can be used for any kind of content, such as forum posts, blog posts, image posts, video posts, audio posts, and even messaging.

## Definition

### Note

A `Note` is a piece of content posted by a User.

- Type: `"pub.versia:social/Note"`

- Fetch: `GET /.versia/v0.7/entities/pub.versia:social/Note/{id}`

- Collections:

  - `replies`: [Reference Collection](/structures/collection#reference-collection) of [Note](#note) entities that are replies to this note.
  - `quotes`: [Reference Collection](/structures/collection#reference-collection) of [Note](#note) entities that quote this note.

**Fields**

- `type` (`string`, required): **MUST** be `pub.versia:social/Note`.

- `attachments` (`Media[]`, required): Media attachments to the note. Any media type is allowed. The `content` can [place attachments inside the text](/structures/rich-text#media).

- `author` (`Reference`, required): [Reference](/entities#reference) to the `User` considered the author of the note.

- `category` (`Category`): Category of the note. Useful for clients to render notes differently depending on their intended purpose.

  - `"microblog"`: Short posts, like Twitter or Mastodon
  - `"forum"`: Threaded discussions, like Reddit
  - `"blog"`: Long articles, like WordPress or Medium
  - `"image"`: Image posts, like Instagram
  - `"video"`: Video posts, like YouTube or PeerTube
  - `"audio"`: Audio posts, like SoundCloud or Spotify
  - `"messaging"`: Chat messages, like Discord, Element or Signal

  A receiver **MUST** treat an unknown value as if `category` were left out.

- `content` (`RichText`): The content of the note. It can [place the note's attachments inside its text](/structures/rich-text#media) with `img`, `video` and `audio`. Every user named in a [mention](/structures/rich-text#mentions) in it **MUST** also be listed in `mentions`.

- `device` (`Device`): Device used to post the note. Useful for showing which app posted the note.

  - `name` (`string`, required)
  - `version` (`string`)
  - `url` (`string`)

- `visibility` (`"public" | "subscribers" | "mentions"`, required): Who can see the note, besides its author:

  - `public`: Anyone.
  - `subscribers`: The author's subscribers, the users mentioned in the note, and the authors of the Notes it replies to.
  - `mentions`: Only the users mentioned in the note, and the authors of the Notes it replies to.

- `is_sensitive` (`boolean`, required): Whether the note contains "sensitive content". This can be used with `subject` as a "content warning" feature.

- `mentions` (`Reference[]`, required): [References](/entities#reference) to [Users](/entities/user) mentioned by the note. The content can also contain mentions, however only the mentions in this field **SHOULD** trigger notifications.

- `previews` (`LinkPreview[]`, required): Previews for any links in the publication. This is to avoid the [stampeding mastodon problem](https://github.com/mastodon/mastodon/issues/23662) where a link preview is fetched by every instance that sees the publication, creating an accidental DDOS attack.

  Implementations **SHOULD NOT** trust previews, as a malicious remote instance could fake them to redirect users to malicious links.

  - `link` (`string`, required)
  - `title` (`string`, required)
  - `description` (`string`)
  - `image` (`string`)
  - `icon` (`string`)

- `quoting` (`Reference`): [Reference](/entities#reference) to the note that this note is quoting, if any. Quoting is similar to replying, but does not notify the author of the quoted note.

- `replies_to` (`Reference`): [Reference](/entities#reference) to the note that this note is a reply to, if any.

- `subject` (`string`): A subject for the note. Useful for clients to display a "content warning" or "spoiler" feature, such as on Mastodon. **MUST** be plain text, not [RichText](/structures/rich-text).

- `url` (`URI`): Address of the note's page on its instance, for people to open in a browser. Software that shows the note elsewhere can link to it.

Inherited from [Entity](/entities):

- [`id`](/entities#entity-id) (`string`, required)
- [`created_at`](/entities#entity-created-at) (`RFC3339`, required)
- [`updated_at`](/entities#entity-updated-at) (`RFC3339`)
- [`extensions`](/entities#entity-extensions) (`Extensions`)

```jsonc title="Example Note"
{
    "id": "0341e147rp002",
    "type": "pub.versia:social/Note",
    "created_at": "2024-06-19T01:07:44Z",
    "attachments": [
        {
            "url": "https://cdn.example.com/29e810bf4707fef373d886af322089d5db300fce66e4e073efc26827f10825f6/image.png",
            "media_type": "image/png",
            "size": 221275,
            "hash": "967b8e86d8708c6283814f450efcbd3be94d3d24ca9a7ab435b2ff8b51dcbc21",
            "thumbhash": "1QcSHQRnh493V4dIh4eXh1h4kJUI",
            "width": 639,
            "height": 960
        },
        {
            "url": "https://cdn.example.com/68c02dd11c179ef4d170b05393f6e72133dd0ad733f40d41b42363d8784e8d5d/fire.txt",
            "media_type": "text/plain",
            "size": 8,
            "hash": "68c02dd11c179ef4d170b05393f6e72133dd0ad733f40d41b42363d8784e8d5d"
        }
    ],
    "author": "versia.example:033nrcdtky006",
    "category": "microblog",
    "content": "<p>In the next versia-fe update: account settings, finally!</p>",
    "device": {
        "name": "Example Client",
        "version": "1.0.0",
        "url": "https://client.example"
    },
    "extensions": {
        "pub.versia:custom_emojis": {
            "emojis": []
        }
    },
    "visibility": "public",
    "is_sensitive": false,
    "mentions": [],
    "previews": [],
    "subject": "Versia development",
    "url": "https://versia.example/notes/0341e147rp002"
}
```

## Delivery and Access

A sender **MUST** [deliver](/federation#delivery) a Note to the instances hosting these users:

| Note                          | Delivered to                                                                                           |
| ----------------------------- | ------------------------------------------------------------------------------------------------------ |
| `visibility` is `public`      | The author's subscribers, the users it mentions, and the authors of the Notes it replies to and quotes |
| `visibility` is `subscribers` | The author's subscribers, the users it mentions, and the authors of the Notes it replies to            |
| `visibility` is `mentions`    | The users it mentions and the authors of the Notes it replies to                                       |

These instances [may fetch](/federation#access) a Note:

| Note                          | May be fetched by                                                                                     |
| ----------------------------- | ----------------------------------------------------------------------------------------------------- |
| `visibility` is `public`      | Any instance                                                                                          |
| `visibility` is `subscribers` | Instances hosting a subscriber of the author, a mentioned user, or the author of a Note it replies to |
| `visibility` is `mentions`    | Instances hosting a mentioned user or the author of a Note it replies to                              |

## Notes Collection

Every user has a `pub.versia:social/Notes` collection (at `/.versia/v0.7/entities/User/{id}/collections/pub.versia:social/Notes`). It is a [Collection](/structures/collection) of the Notes that the user has authored, and plays the role that an outbox plays in other protocols.

It **MUST** list only the Notes the requesting instance [may fetch](#delivery-and-access). For example, if Alice sends a Note whose `visibility` is `mentions` and that only mentions Bob, Alice's instance **MUST** return it in response to a request from Bob's instance, and **MUST NOT** list it in Alice's collection in response to a request from Joe's instance.

This collection is very useful for "backfilling" data when a new instance joins the network. By resolving the collections of all new users it encounters, a new instance can quickly catch up on all old notes.

## User Collections

The Social extension adds the following collections to the [User](/entities/user) entity:

- `pub.versia:social/Notes`: [Collection](/structures/collection) of notes authored by the user, described under [Notes Collection](#notes-collection).
- `pub.versia:social/Featured`: [Reference Collection](/structures/collection#reference-collection) of notes that the user wants to feature on their profile ("pinned" notes).

## Interaction Types

This extension registers the following [interaction types](/extensions/interaction-controls#interaction-types):

- `pub.versia:social/reply`, for sending a Note whose `replies_to` is the Note.
- `pub.versia:social/quote`, for sending a Note whose `quoting` is the Note.

## Versia Links

The Social extension adds the following [Versia Link](/links) actions:

- `notes/{instance}/{id}`: Open a note.
- `reply/{instance}/{id}`: Open the composer to reply to a note.
- `quote/{instance}/{id}`: Open the composer to quote a note.
- `compose/{text}`: Compose a new note. Text passed at the end will be added in the note compose field. Used for "Share with Versia" buttons on websites. It has no `{instance}`.

```text title="Viewing a note"
web+versia://notes/jim.example/0341e147rp002
```

```text title="Replying to a note"
web+versia://reply/bob.example/0341e147rp002
```
