|
|
|
@ -67,11 +67,18 @@ Whenever `server_notice_type` is `m.server_notice.content_report`,
|
|
|
|
|
| --------- | ------ | ----------- |
|
|
|
|
|
| body | string | **Required** A human-readable description of the problem, generated by the server (e.g. "User %s has reported that '%s'"). |
|
|
|
|
|
| msgtype | enum | **Required** In this case, `m.server_notice.content_report`. |
|
|
|
|
|
| room_id | string | **Required** The id of the room being reported. |
|
|
|
|
|
| event_id | string | **Required** The id of the event being reported. |
|
|
|
|
|
| user_id | string | **Required** The id of the user reporting the event. |
|
|
|
|
|
| room_id | string | **Required** The id of the room being reported. |
|
|
|
|
|
| event_id | string | **Required** The id of the event being reported. |
|
|
|
|
|
| user_id | string | **Required** The id of the user reporting the event. |
|
|
|
|
|
| score | integer | The score to rate this content as where -100 is most offensive and 0 is inoffensive, as given by the reporting user. |
|
|
|
|
|
| reason | string | The reason given by the reporting user. |
|
|
|
|
|
| nature | enum | The type of activity being reported. |
|
|
|
|
|
|
|
|
|
|
Field `nature` is designed to be filled by the reporter's front-end and to aid moderator-side tools (e.g. bots) to make
|
|
|
|
|
a decision on the event. As of this MSC, `nature` is one of:
|
|
|
|
|
|
|
|
|
|
- `abuse.spam` (reporting spam);
|
|
|
|
|
- `abuse.moderation` (reporting a behavior that should be moderated, typically trolling).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### Client behavior (sending reports)
|
|
|
|
@ -83,7 +90,8 @@ When this UX is used, a call to `POST /_matrix/client/r0/rooms/{room_id}/report/
|
|
|
|
|
{
|
|
|
|
|
"target": "room_moderators",
|
|
|
|
|
"score": -100,
|
|
|
|
|
"reason": "this makes me sad"
|
|
|
|
|
"reason": "this makes me sad",
|
|
|
|
|
"nature": "abuse.moderation",
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
@ -92,8 +100,10 @@ When this UX is used, a call to `POST /_matrix/client/r0/rooms/{room_id}/report/
|
|
|
|
|
Whenever a server receives a `POST /_matrix/client/r0/rooms/{room_id}/report/{event_id}` with `target` specified
|
|
|
|
|
as `"room_moderators"` they should:
|
|
|
|
|
|
|
|
|
|
1. ignore the message if `event_id` is not an event in `room_id` or if the user is not a member of `room_id`; otherwise
|
|
|
|
|
2. for all moderators in room `room_id` *on the local homeserver*:
|
|
|
|
|
1. if `event_id` is not an event in `room_id` or if the user is not a member of `room_id`, return a HTTP NOT FOUND and Matrix error code NOT FOUND;
|
|
|
|
|
2. if `nature` is not a known nature, normalize it to `None`;
|
|
|
|
|
3. if `room_id` has no moderators, return a HTTP NOT FOUND and Matrix error code NOT FOUND;
|
|
|
|
|
4. for all moderators in room `room_id` *on the local homeserver*:
|
|
|
|
|
|
|
|
|
|
1. send a server notice
|
|
|
|
|
```jsonc
|
|
|
|
@ -102,13 +112,13 @@ as `"room_moderators"` they should:
|
|
|
|
|
"msgtype": "m.server_notice.content_report",
|
|
|
|
|
"room_id": "{room_id}", // From path parameter
|
|
|
|
|
"event_id": "{event_id}", // From path parameter
|
|
|
|
|
"user_id": "{user_id}", // From authentication token
|
|
|
|
|
"reporter_id": "{user_id}", // From authentication token
|
|
|
|
|
"score": "{score}", // From JSON body parameter
|
|
|
|
|
"reason": "{reason}" // From JSON body parameter
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
3. for all homeservers other than local with at least one moderator in room `room_id`:
|
|
|
|
|
5. for all homeservers other than local with at least one moderator in room `room_id`:
|
|
|
|
|
|
|
|
|
|
1. send a EDU
|
|
|
|
|
```jsonc
|
|
|
|
@ -123,9 +133,10 @@ as `"room_moderators"` they should:
|
|
|
|
|
"msgtype": "m.server_notice.content_report",
|
|
|
|
|
"room_id": "{room_id}", // From path parameter
|
|
|
|
|
"event_id": "{event_id}", // From path parameter
|
|
|
|
|
"user_id": "{user_id}", // From authentication token
|
|
|
|
|
"score": "{score}", // From JSON body parameter
|
|
|
|
|
"reason": "{reason}", // From JSON body parameter
|
|
|
|
|
"reporter_id": "{user_id}",// From authentication token
|
|
|
|
|
"score": "{score}", // From JSON body parameter
|
|
|
|
|
"reason": "{reason}", // From JSON body parameter
|
|
|
|
|
"nature": "{nature}", // From JSON body parameter
|
|
|
|
|
},
|
|
|
|
|
"prev_events": [...], // Most recent events in room `{room_id}`, as per usual EDU mechanisms
|
|
|
|
|
"depth": ?????, // FIXME: How should we pick this?
|
|
|
|
@ -141,22 +152,24 @@ as `"room_moderators"` they should:
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
2. When a server receives a EDU with the following content:
|
|
|
|
|
|
|
|
|
|
1. When a server receives a EDU with the following content:
|
|
|
|
|
```jsonc
|
|
|
|
|
{
|
|
|
|
|
"body": "{body}",
|
|
|
|
|
"msgtype": "m.server_notice.content_report",
|
|
|
|
|
"room_id": "{room_id}",
|
|
|
|
|
"event_id": "{event_id}",
|
|
|
|
|
"user_id": "{user_id}",
|
|
|
|
|
"reporter_id": "{user_id}",
|
|
|
|
|
"score": "{score}",
|
|
|
|
|
"reason": "{reason}",
|
|
|
|
|
"nature": "{nature}",
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
1. ignore the message if it is an invalid EDU, as per usual EDU rules; otherwise
|
|
|
|
|
2. ignore the message if server is not part of `room_id`; otherwise
|
|
|
|
|
3. ignore the message if `event_id` is not an event in `room_id` or if `user_id` is not a member of `room_id`; otherwise
|
|
|
|
|
3. ignore the message if `event_id` is not an event in `room_id` or if `reporter_id` is not a member of `room_id`; otherwise
|
|
|
|
|
4. for all moderators in room `room_id` on server:
|
|
|
|
|
|
|
|
|
|
1. send a server notice
|
|
|
|
@ -166,9 +179,10 @@ as `"room_moderators"` they should:
|
|
|
|
|
"msgtype": "m.server_notice.content_report",
|
|
|
|
|
"room_id": "{room_id}", // From EDU
|
|
|
|
|
"event_id": "{event_id}", // From EDU
|
|
|
|
|
"user_id": "{user_id}", // From EDU
|
|
|
|
|
"score": "{score}", // From EDU
|
|
|
|
|
"reason": "{reason}" // From EDU
|
|
|
|
|
"reporter_id": "{user_id}",// From EDU
|
|
|
|
|
"score": "{score}", // From EDU
|
|
|
|
|
"reason": "{reason}", // From EDU
|
|
|
|
|
"nature": "{nature}", // From EDU
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
@ -188,6 +202,8 @@ of the homeserver.
|
|
|
|
|
|
|
|
|
|
## Alternatives
|
|
|
|
|
|
|
|
|
|
### Send DM to moderator
|
|
|
|
|
|
|
|
|
|
An alternative would be to encourage users to send DM to moderators. This has the
|
|
|
|
|
following drawbacks:
|
|
|
|
|
|
|
|
|
@ -199,6 +215,8 @@ following drawbacks:
|
|
|
|
|
3. If several users report the same content, moderators may find themselves bombarded
|
|
|
|
|
with large number of DMs, which makes tracking bad content more complicated.
|
|
|
|
|
|
|
|
|
|
### Send DM to moderator, with UX
|
|
|
|
|
|
|
|
|
|
A variant would be to implement a "Report Content to Room Moderators" button as a mechanism that
|
|
|
|
|
sends a DM to all moderators in the room. This solves one of the pain points above but still
|
|
|
|
|
has the following drawbacks:
|
|
|
|
@ -208,6 +226,30 @@ has the following drawbacks:
|
|
|
|
|
2. If several users report the same content, moderators may find themselves bombarded
|
|
|
|
|
with large number of DMs, which makes tracking bad content more complicated.
|
|
|
|
|
|
|
|
|
|
### Reporting room
|
|
|
|
|
|
|
|
|
|
Another alternative would be to create (dynamically), for each room `r`, another room `r_reports` dedicated to reporting events
|
|
|
|
|
in `r`. The room `r_reports` would let each member of `r` send message to `r_reports` but only moderators of `r`
|
|
|
|
|
could read messages in `r_reports`. This would simplify the work of federation and ensure that reports are not
|
|
|
|
|
lost in case of ill-timed network problems but would raise a number of difficulties:
|
|
|
|
|
|
|
|
|
|
1. What user creates `r_reports` and on which server?
|
|
|
|
|
2. What happens whenever a user becomes a moderator/loses PL in `r`?
|
|
|
|
|
3. Why should the moderators of `r` accept invites to this unknown room `r_reports`?
|
|
|
|
|
4. When an event is reported and the room `r_reports` already exists, how does the homeserver determine that the event
|
|
|
|
|
should be reported in this same `r_reports`?
|
|
|
|
|
|
|
|
|
|
### Reporting room, revisited
|
|
|
|
|
|
|
|
|
|
A variant of the previous idea would be to create, for each room `room` and each report `rep`, a new room `room_report`.
|
|
|
|
|
Once the room is created, only moderators of `room` have access to this room `room_report`. This would similarly
|
|
|
|
|
simplify the work of federation and ensure that reports are not lost in case of ill-timed network problems but
|
|
|
|
|
would raise a number of difficulties:
|
|
|
|
|
|
|
|
|
|
1. What user creates `room_reports` and on which server?
|
|
|
|
|
2. Why should the moderators of `room` accept invites to this unknown room `room_reports`?
|
|
|
|
|
3. If the room is subject to much abuse or if many users report the same event, moderators quickly risk ending
|
|
|
|
|
up with hundreds of distinct abuse rooms. This may end up being very counter-productive.
|
|
|
|
|
|
|
|
|
|
## Security considerations
|
|
|
|
|
|
|
|
|
@ -225,4 +267,7 @@ difference between sending to a homeserver administrator, to a room moderator or
|
|
|
|
|
|
|
|
|
|
## Unstable prefix
|
|
|
|
|
|
|
|
|
|
During experimentation, `m.server_notice.content_report` will be prefixed into `org.matrix.m.server_notice.content_report`.
|
|
|
|
|
During experimentation,
|
|
|
|
|
|
|
|
|
|
- `m.server_notice.content_report` will be prefixed into `org.matrix.msc2938.content_report`;
|
|
|
|
|
- `target` will be prefixed into `org.matrix.msc2938.target`;
|
|
|
|
|