aa6119670449c4887cc22cec3c291231b30a8138
[akkoma] / docs / API / chats.md
1 # Chats
2
3 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.
4
5 ## Why Chats?
6
7 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.
8
9 This is an awkward setup for a few reasons:
10
11 - 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")
12 - 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.
13 - 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.
14 - 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.
15
16 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.
17
18 ## Chats explained
19 For this reasons, Chats are a new and different entity, both in the API as well as in ActivityPub. A quick overview:
20
21 - 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.
22 - Chat messages have the ActivityPub type `ChatMessage`. They are not `Note`s. Servers that don't understand them will just drop them.
23 - The only addressing allowed in `ChatMessage`s is one single ActivityPub actor in the `to` field.
24 - 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.
25 - `ChatMessage`s are posted with a different api, making it very hard to accidentally send a message to the wrong person.
26 - `ChatMessage`s don't show up in the existing timelines.
27 - Chats can never go from private to public. They are always private between the two actors.
28
29 ## Caveats
30
31 - Chats are NOT E2E encrypted (yet). Security is still the same as email.
32
33 ## API
34
35 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`.
36
37 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`.
38
39 ### Creating or getting a chat.
40
41 To create or get an existing Chat for a certain recipient (identified by Account ID)
42 you can call:
43
44 `POST /api/v1/pleroma/chats/by-account-id/:account_id`
45
46 The account id is the normal FlakeId of the user
47 ```
48 POST /api/v1/pleroma/chats/by-account-id/someflakeid
49 ```
50
51 If you already have the id of a chat, you can also use
52
53 ```
54 GET /api/v1/pleroma/chats/:id
55 ```
56
57 There will only ever be ONE Chat for you and a given recipient, so this call
58 will return the same Chat if you already have one with that user.
59
60 Returned data:
61
62 ```json
63 {
64 "account": {
65 "id": "someflakeid",
66 "username": "somenick",
67 ...
68 },
69 "id" : "1",
70 "unread" : 2,
71 "last_message" : {...}, // The last message in that chat
72 "updated_at": "2020-04-21T15:11:46.000Z"
73 }
74 ```
75
76 ### Marking a chat as read
77
78 To mark a number of messages in a chat up to a certain message as read, you can use
79
80 `POST /api/v1/pleroma/chats/:id/read`
81
82
83 Parameters:
84 - last_read_id: Given this id, all chat messages until this one will be marked as read. Required.
85
86
87 Returned data:
88
89 ```json
90 {
91 "account": {
92 "id": "someflakeid",
93 "username": "somenick",
94 ...
95 },
96 "id" : "1",
97 "unread" : 0,
98 "updated_at": "2020-04-21T15:11:46.000Z"
99 }
100 ```
101
102 ### Marking a single chat message as read
103
104 To set the `unread` property of a message to `false`
105
106 `POST /api/v1/pleroma/chats/:id/messages/:message_id/read`
107
108 Returned data:
109
110 The modified chat message
111
112 ### Getting a list of Chats
113
114 `GET /api/v1/pleroma/chats`
115
116 This will return a list of chats that you have been involved in, sorted by their
117 last update (so new chats will be at the top).
118
119 Returned data:
120
121 ```json
122 [
123 {
124 "account": {
125 "id": "someflakeid",
126 "username": "somenick",
127 ...
128 },
129 "id" : "1",
130 "unread" : 2,
131 "last_message" : {...}, // The last message in that chat
132 "updated_at": "2020-04-21T15:11:46.000Z"
133 }
134 ]
135 ```
136
137 The recipient of messages that are sent to this chat is given by their AP ID.
138 No pagination is implemented for now.
139
140 ### Getting the messages for a Chat
141
142 For a given Chat id, you can get the associated messages with
143
144 `GET /api/v1/pleroma/chats/:id/messages`
145
146 This will return all messages, sorted by most recent to least recent. The usual
147 pagination options are implemented.
148
149 Returned data:
150
151 ```json
152 [
153 {
154 "account_id": "someflakeid",
155 "chat_id": "1",
156 "content": "Check this out :firefox:",
157 "created_at": "2020-04-21T15:11:46.000Z",
158 "emojis": [
159 {
160 "shortcode": "firefox",
161 "static_url": "https://dontbulling.me/emoji/Firefox.gif",
162 "url": "https://dontbulling.me/emoji/Firefox.gif",
163 "visible_in_picker": false
164 }
165 ],
166 "id": "13",
167 "unread": true
168 },
169 {
170 "account_id": "someflakeid",
171 "chat_id": "1",
172 "content": "Whats' up?",
173 "created_at": "2020-04-21T15:06:45.000Z",
174 "emojis": [],
175 "id": "12",
176 "unread": false
177 }
178 ]
179 ```
180
181 ### Posting a chat message
182
183 Posting a chat message for given Chat id works like this:
184
185 `POST /api/v1/pleroma/chats/:id/messages`
186
187 Parameters:
188 - content: The text content of the message. Optional if media is attached.
189 - media_id: The id of an upload that will be attached to the message.
190
191 Currently, no formatting beyond basic escaping and emoji is implemented.
192
193 Returned data:
194
195 ```json
196 {
197 "account_id": "someflakeid",
198 "chat_id": "1",
199 "content": "Check this out :firefox:",
200 "created_at": "2020-04-21T15:11:46.000Z",
201 "emojis": [
202 {
203 "shortcode": "firefox",
204 "static_url": "https://dontbulling.me/emoji/Firefox.gif",
205 "url": "https://dontbulling.me/emoji/Firefox.gif",
206 "visible_in_picker": false
207 }
208 ],
209 "id": "13",
210 "unread": false
211 }
212 ```
213
214 ### Deleting a chat message
215
216 Deleting a chat message for given Chat id works like this:
217
218 `DELETE /api/v1/pleroma/chats/:chat_id/messages/:message_id`
219
220 Returned data is the deleted message.
221
222 ### Notifications
223
224 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`:
225
226 ```json
227 {
228 "id": "someid",
229 "type": "pleroma:chat_mention",
230 "account": { ... } // User account of the sender,
231 "chat_message": {
232 "chat_id": "1",
233 "id": "10",
234 "content": "Hello",
235 "account_id": "someflakeid",
236 "unread": false
237 },
238 "created_at": "somedate"
239 }
240 ```
241
242 ### Streaming
243
244 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.
245
246 ### Web Push
247
248 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.