# Interaction Controls Extension

Lets users control who can interact with their notes.

Extension name: `pub.versia:interaction_controls`

The Interaction Controls extension lets a user control who may interact with a Note, for example who may reply to it.

This extension requires [`pub.versia:social@1`](/extensions/social), which defines [Notes](/extensions/social#note).

## Definition

The structure defined in this document **MUST** be inserted in the `pub.versia:interaction_controls` key of a [Note](/extensions/social#note)'s extensions field.

- Extension ID: `pub.versia:interaction_controls`
- Extends: [Note](/entities/note)

**Fields**

- `interaction_type`: Not a literal key: each key is an [interaction type](#interaction-types), and its value says who may perform that interaction.

  - `allowed` (`InteractionGroup[]`, required)

  A user may perform the interaction if they are in any of the listed groups. The Note's author can always perform it. An interaction type that is left out allows everyone, and an empty list allows only the author.

  Values of `InteractionGroup`:

  - `everyone`: Includes every single User in the federation.
  - `mentioned`: Includes every mentioned User.
  - `subscribers`: Includes every subscriber of the author.
  - `subscriptions`: Includes every User that the author is subscribed to.
  - `mutuals`: Includes every mutual of the author (that is, every User that is both a subscriber of the author and subscribed to by the author).
  - `group`: Includes every User in the [Group](/extensions/groups) that this Note was posted to, if any. If Note is not posted to a [Group](/extensions/groups), this value has no effect.

```jsonc title="Example"
{
    "pub.versia:social/reply": {
        "allowed": [
            "group"
        ]
    },
    "pub.versia:likes/like": {
        "allowed": []
    }
}
```

## Behavior

The instance hosting the Note's author **MUST NOT** apply an interaction the user is not allowed to perform. Other instances **SHOULD** do the same when they have the data to check it.

`allowed` never widens who can see a Note. A User **MUST** be able to [see the Note](/extensions/social#delivery-and-access) to interact with it.

A refused interaction **MUST** be [rejected](/validation#rejecting-entities). The instance **MAY** also tell the sender through the [Instance Messaging](/extensions/instance-messaging) extension.

Implementations **SHOULD** keep related [Collections](/structures/collection) and [Reference Collections](/structures/collection#reference-collection), such as a user's subscribers, up to date, so as not to refuse an interaction based on outdated data.

To avoid server load from constant Collection refreshing, implementations **MAY** only refetch associated Collections when forbidden interactions are detected, then recalculate permissions again.

## Interaction Types

Each extension that adds a way to interact with a Note registers its interaction types on its page. An interaction type is named `{extension}/{action}`, where `{extension}` is the name of the extension that registers it and `{action}` is a lowercase name for the interaction, such as `pub.versia:likes/like` for the [Likes Extension](/extensions/likes).

[Social](/extensions/social#interaction-types) registers `pub.versia:social/reply` and `pub.versia:social/quote`.

## Example

```jsonc title="Example Usage"
{
    "id": "033mcbcsyt000",
    "type": "pub.versia:social/Note",
    "created_at": "2024-04-09T01:38:51Z",
    "content": "<p>Hello, world :happy_face:!</p>",
    "visibility": "public",
    // ...
    "extensions": {
        "pub.versia:interaction_controls": {
            "pub.versia:social/reply": {
                "allowed": ["subscribers"]
            }
        }
    }
}
```
