logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://anongit.hacktivis.me/git/pleroma.git/

chats.md (9037B)


  1. # Chats
  2. Chats are a way to represent an IM-style conversation between two actors. They are not the same as direct messages and they are not `Status`es, even though they have a lot in common.
  3. ## Why Chats?
  4. There are no 'visibility levels' in ActivityPub, their definition is purely a Mastodon convention. Direct Messaging between users on the fediverse has mostly been modeled by using ActivityPub addressing following Mastodon conventions on normal `Note` objects. In this case, a 'direct message' would be a message that has no followers addressed and also does not address the special public actor, but just the recipients in the `to` field. It would still be a `Note` and is presented with other `Note`s as a `Status` in the API.
  5. This is an awkward setup for a few reasons:
  6. - As DMs generally still follow the usual `Status` conventions, it is easy to accidentally pull somebody into a DM thread by mentioning them. (e.g. "I hate @badguy so much")
  7. - It is possible to go from a publicly addressed `Status` to a DM reply, back to public, then to a 'followers only' reply, and so on. This can be become very confusing, as it is unclear which user can see which part of the conversation.
  8. - The standard `Status` format of implicit addressing also leads to rather ugly results if you try to display the messages as a chat, because all the recipients are always mentioned by name in the message.
  9. - As direct messages are posted with the same api call (and usually same frontend component) as public messages, accidentally making a public message private or vice versa can happen easily. Client bugs can also lead to this, accidentally making private messages public.
  10. As a measure to improve this situation, the `Conversation` concept and related Pleroma extensions were introduced. While it made it possible to work around a few of the issues, many of the problems remained and it didn't see much adoption because it was too complicated to use correctly.
  11. ## Chats explained
  12. For this reasons, Chats are a new and different entity, both in the API as well as in ActivityPub. A quick overview:
  13. - Chats are meant to represent an instant message conversation between two actors. For now these are only 1-on-1 conversations, but the other actor can be a group in the future.
  14. - Chat messages have the ActivityPub type `ChatMessage`. They are not `Note`s. Servers that don't understand them will just drop them.
  15. - The only addressing allowed in `ChatMessage`s is one single ActivityPub actor in the `to` field.
  16. - There's always only one Chat between two actors. If you start chatting with someone and later start a 'new' Chat, the old Chat will be continued.
  17. - `ChatMessage`s are posted with a different api, making it very hard to accidentally send a message to the wrong person.
  18. - `ChatMessage`s don't show up in the existing timelines.
  19. - Chats can never go from private to public. They are always private between the two actors.
  20. ## Caveats
  21. - Chats are NOT E2E encrypted (yet). Security is still the same as email.
  22. ## API
  23. In general, the way to send a `ChatMessage` is to first create a `Chat`, then post a message to that `Chat`. `Group`s will later be supported by making them a sub-type of `Account`.
  24. This is the overview of using the API. The API is also documented via OpenAPI, so you can view it and play with it by pointing SwaggerUI or a similar OpenAPI tool to `https://yourinstance.tld/api/openapi`.
  25. ### Creating or getting a chat.
  26. To create or get an existing Chat for a certain recipient (identified by Account ID)
  27. you can call:
  28. `POST /api/v1/pleroma/chats/by-account-id/:account_id`
  29. The account id is the normal FlakeId of the user
  30. ```
  31. POST /api/v1/pleroma/chats/by-account-id/someflakeid
  32. ```
  33. If you already have the id of a chat, you can also use
  34. ```
  35. GET /api/v1/pleroma/chats/:id
  36. ```
  37. There will only ever be ONE Chat for you and a given recipient, so this call
  38. will return the same Chat if you already have one with that user.
  39. Returned data:
  40. ```json
  41. {
  42. "account": {
  43. "id": "someflakeid",
  44. "username": "somenick",
  45. ...
  46. },
  47. "id": "1",
  48. "unread": 2,
  49. "last_message": {...}, // The last message in that chat
  50. "updated_at": "2020-04-21T15:11:46.000Z"
  51. }
  52. ```
  53. ### Marking a chat as read
  54. To mark a number of messages in a chat up to a certain message as read, you can use
  55. `POST /api/v1/pleroma/chats/:id/read`
  56. Parameters:
  57. - last_read_id: Given this id, all chat messages until this one will be marked as read. Required.
  58. Returned data:
  59. ```json
  60. {
  61. "account": {
  62. "id": "someflakeid",
  63. "username": "somenick",
  64. ...
  65. },
  66. "id": "1",
  67. "unread": 0,
  68. "updated_at": "2020-04-21T15:11:46.000Z"
  69. }
  70. ```
  71. ### Marking a single chat message as read
  72. To set the `unread` property of a message to `false`
  73. `POST /api/v1/pleroma/chats/:id/messages/:message_id/read`
  74. Returned data:
  75. The modified chat message
  76. ### Getting a list of Chats
  77. `GET /api/v2/pleroma/chats`
  78. This will return a list of chats that you have been involved in, sorted by their
  79. last update (so new chats will be at the top).
  80. Parameters:
  81. - with_muted: Include chats from muted users (boolean).
  82. - pinned: Include only pinned chats (boolean).
  83. Returned data:
  84. ```json
  85. [
  86. {
  87. "account": {
  88. "id": "someflakeid",
  89. "username": "somenick",
  90. ...
  91. },
  92. "id": "1",
  93. "unread": 2,
  94. "last_message": {...}, // The last message in that chat
  95. "updated_at": "2020-04-21T15:11:46.000Z"
  96. }
  97. ]
  98. ```
  99. The recipient of messages that are sent to this chat is given by their AP ID.
  100. The usual pagination options are implemented.
  101. ### Getting the messages for a Chat
  102. For a given Chat id, you can get the associated messages with
  103. `GET /api/v1/pleroma/chats/:id/messages`
  104. This will return all messages, sorted by most recent to least recent. The usual
  105. pagination options are implemented.
  106. Returned data:
  107. ```json
  108. [
  109. {
  110. "account_id": "someflakeid",
  111. "chat_id": "1",
  112. "content": "Check this out :firefox:",
  113. "created_at": "2020-04-21T15:11:46.000Z",
  114. "emojis": [
  115. {
  116. "shortcode": "firefox",
  117. "static_url": "https://dontbulling.me/emoji/Firefox.gif",
  118. "url": "https://dontbulling.me/emoji/Firefox.gif",
  119. "visible_in_picker": false
  120. }
  121. ],
  122. "id": "13",
  123. "unread": true
  124. },
  125. {
  126. "account_id": "someflakeid",
  127. "chat_id": "1",
  128. "content": "Whats' up?",
  129. "created_at": "2020-04-21T15:06:45.000Z",
  130. "emojis": [],
  131. "id": "12",
  132. "unread": false,
  133. "idempotency_key": "75442486-0874-440c-9db1-a7006c25a31f"
  134. }
  135. ]
  136. ```
  137. - idempotency_key: The copy of the `idempotency-key` HTTP request header that can be used for optimistic message sending. Included only during the first few minutes after the message creation.
  138. ### Posting a chat message
  139. Posting a chat message for given Chat id works like this:
  140. `POST /api/v1/pleroma/chats/:id/messages`
  141. Parameters:
  142. - content: The text content of the message. Optional if media is attached.
  143. - media_id: The id of an upload that will be attached to the message.
  144. Currently, no formatting beyond basic escaping and emoji is implemented.
  145. Returned data:
  146. ```json
  147. {
  148. "account_id": "someflakeid",
  149. "chat_id": "1",
  150. "content": "Check this out :firefox:",
  151. "created_at": "2020-04-21T15:11:46.000Z",
  152. "emojis": [
  153. {
  154. "shortcode": "firefox",
  155. "static_url": "https://dontbulling.me/emoji/Firefox.gif",
  156. "url": "https://dontbulling.me/emoji/Firefox.gif",
  157. "visible_in_picker": false
  158. }
  159. ],
  160. "id": "13",
  161. "unread": false
  162. }
  163. ```
  164. ### Deleting a chat message
  165. Deleting a chat message for given Chat id works like this:
  166. `DELETE /api/v1/pleroma/chats/:chat_id/messages/:message_id`
  167. Returned data is the deleted message.
  168. ### Pinning a chat
  169. Pinning a chat works like this:
  170. `POST /api/v1/pleroma/chats/:id/pin`
  171. Returned data:
  172. ```json
  173. {
  174. "account": {
  175. "id": "someflakeid",
  176. "username": "somenick",
  177. ...
  178. },
  179. "id": "1",
  180. "unread": 0,
  181. "updated_at": "2020-04-21T15:11:46.000Z",
  182. "pinned": true,
  183. }
  184. ```
  185. To unpin a pinned chat, use:
  186. `POST /api/v1/pleroma/chats/:id/unpin`
  187. ### Notifications
  188. There's a new `pleroma:chat_mention` notification, which has this form. It is not given out in the notifications endpoint by default, you need to explicitly request it with `include_types[]=pleroma:chat_mention`:
  189. ```json
  190. {
  191. "id": "someid",
  192. "type": "pleroma:chat_mention",
  193. "account": { ... } // User account of the sender,
  194. "chat_message": {
  195. "chat_id": "1",
  196. "id": "10",
  197. "content": "Hello",
  198. "account_id": "someflakeid",
  199. "unread": false
  200. },
  201. "created_at": "somedate"
  202. }
  203. ```
  204. ### Streaming
  205. There is an additional `user:pleroma_chat` stream. Incoming chat messages will make the current chat be sent to this `user` stream. The `event` of an incoming chat message is `pleroma:chat_update`. The payload is the updated chat with the incoming chat message in the `last_message` field.
  206. ### Web Push
  207. If you want to receive push messages for this type, you'll need to add the `pleroma:chat_mention` type to your alerts in the push subscription.