First
[anni] / lib / pleroma / web / api_spec / operations / chat_operation.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ApiSpec.ChatOperation do
6   alias OpenApiSpex.Operation
7   alias OpenApiSpex.Schema
8   alias Pleroma.Web.ApiSpec.Schemas.ApiError
9   alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
10   alias Pleroma.Web.ApiSpec.Schemas.Chat
11   alias Pleroma.Web.ApiSpec.Schemas.ChatMessage
12
13   import Pleroma.Web.ApiSpec.Helpers
14
15   @spec open_api_operation(atom) :: Operation.t()
16   def open_api_operation(action) do
17     operation = String.to_existing_atom("#{action}_operation")
18     apply(__MODULE__, operation, [])
19   end
20
21   def mark_as_read_operation do
22     %Operation{
23       tags: ["Chats"],
24       summary: "Mark all messages in the chat as read",
25       operationId: "ChatController.mark_as_read",
26       parameters: [Operation.parameter(:id, :path, :string, "The ID of the Chat")],
27       requestBody: request_body("Parameters", mark_as_read()),
28       responses: %{
29         200 =>
30           Operation.response(
31             "The updated chat",
32             "application/json",
33             Chat
34           )
35       },
36       security: [
37         %{
38           "oAuth" => ["write:chats"]
39         }
40       ]
41     }
42   end
43
44   def mark_message_as_read_operation do
45     %Operation{
46       tags: ["Chats"],
47       summary: "Mark a message as read",
48       operationId: "ChatController.mark_message_as_read",
49       parameters: [
50         Operation.parameter(:id, :path, :string, "The ID of the Chat"),
51         Operation.parameter(:message_id, :path, :string, "The ID of the message")
52       ],
53       responses: %{
54         200 =>
55           Operation.response(
56             "The read ChatMessage",
57             "application/json",
58             ChatMessage
59           )
60       },
61       security: [
62         %{
63           "oAuth" => ["write:chats"]
64         }
65       ]
66     }
67   end
68
69   def show_operation do
70     %Operation{
71       tags: ["Chats"],
72       summary: "Retrieve a chat",
73       operationId: "ChatController.show",
74       parameters: [
75         Operation.parameter(
76           :id,
77           :path,
78           :string,
79           "The id of the chat",
80           required: true,
81           example: "1234"
82         )
83       ],
84       responses: %{
85         200 =>
86           Operation.response(
87             "The existing chat",
88             "application/json",
89             Chat
90           )
91       },
92       security: [
93         %{
94           "oAuth" => ["read"]
95         }
96       ]
97     }
98   end
99
100   def create_operation do
101     %Operation{
102       tags: ["Chats"],
103       summary: "Create a chat",
104       operationId: "ChatController.create",
105       parameters: [
106         Operation.parameter(
107           :id,
108           :path,
109           :string,
110           "The account id of the recipient of this chat",
111           required: true,
112           example: "someflakeid"
113         )
114       ],
115       responses: %{
116         200 =>
117           Operation.response(
118             "The created or existing chat",
119             "application/json",
120             Chat
121           )
122       },
123       security: [
124         %{
125           "oAuth" => ["write:chats"]
126         }
127       ]
128     }
129   end
130
131   def index_operation do
132     %Operation{
133       tags: ["Chats"],
134       summary: "Retrieve list of chats (unpaginated)",
135       deprecated: true,
136       description:
137         "Deprecated due to no support for pagination. Using [/api/v2/pleroma/chats](#operation/ChatController.index2) instead is recommended.",
138       operationId: "ChatController.index",
139       parameters: [
140         Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users")
141       ],
142       responses: %{
143         200 => Operation.response("The chats of the user", "application/json", chats_response())
144       },
145       security: [
146         %{
147           "oAuth" => ["read:chats"]
148         }
149       ]
150     }
151   end
152
153   def index2_operation do
154     %Operation{
155       tags: ["Chats"],
156       summary: "Retrieve list of chats",
157       operationId: "ChatController.index2",
158       parameters: [
159         Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users")
160         | pagination_params()
161       ],
162       responses: %{
163         200 => Operation.response("The chats of the user", "application/json", chats_response())
164       },
165       security: [
166         %{
167           "oAuth" => ["read:chats"]
168         }
169       ]
170     }
171   end
172
173   def messages_operation do
174     %Operation{
175       tags: ["Chats"],
176       summary: "Retrieve chat's messages",
177       operationId: "ChatController.messages",
178       parameters:
179         [Operation.parameter(:id, :path, :string, "The ID of the Chat")] ++
180           pagination_params(),
181       responses: %{
182         200 =>
183           Operation.response(
184             "The messages in the chat",
185             "application/json",
186             chat_messages_response()
187           ),
188         404 => Operation.response("Not Found", "application/json", ApiError)
189       },
190       security: [
191         %{
192           "oAuth" => ["read:chats"]
193         }
194       ]
195     }
196   end
197
198   def post_chat_message_operation do
199     %Operation{
200       tags: ["Chats"],
201       summary: "Post a message to the chat",
202       operationId: "ChatController.post_chat_message",
203       parameters: [
204         Operation.parameter(:id, :path, :string, "The ID of the Chat")
205       ],
206       requestBody: request_body("Parameters", chat_message_create()),
207       responses: %{
208         200 =>
209           Operation.response(
210             "The newly created ChatMessage",
211             "application/json",
212             ChatMessage
213           ),
214         400 => Operation.response("Bad Request", "application/json", ApiError),
215         422 => Operation.response("MRF Rejection", "application/json", ApiError)
216       },
217       security: [
218         %{
219           "oAuth" => ["write:chats"]
220         }
221       ]
222     }
223   end
224
225   def delete_message_operation do
226     %Operation{
227       tags: ["Chats"],
228       summary: "Delete message",
229       operationId: "ChatController.delete_message",
230       parameters: [
231         Operation.parameter(:id, :path, :string, "The ID of the Chat"),
232         Operation.parameter(:message_id, :path, :string, "The ID of the message")
233       ],
234       responses: %{
235         200 =>
236           Operation.response(
237             "The deleted ChatMessage",
238             "application/json",
239             ChatMessage
240           )
241       },
242       security: [
243         %{
244           "oAuth" => ["write:chats"]
245         }
246       ]
247     }
248   end
249
250   def chats_response do
251     %Schema{
252       title: "ChatsResponse",
253       description: "Response schema for multiple Chats",
254       type: :array,
255       items: Chat,
256       example: [
257         %{
258           "account" => %{
259             "pleroma" => %{
260               "is_admin" => false,
261               "is_confirmed" => true,
262               "hide_followers_count" => false,
263               "is_moderator" => false,
264               "hide_favorites" => true,
265               "ap_id" => "https://dontbulling.me/users/lain",
266               "hide_follows_count" => false,
267               "hide_follows" => false,
268               "background_image" => nil,
269               "skip_thread_containment" => false,
270               "hide_followers" => false,
271               "relationship" => %{},
272               "tags" => []
273             },
274             "avatar" =>
275               "https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg",
276             "following_count" => 0,
277             "header_static" => "https://originalpatchou.li/images/banner.png",
278             "source" => %{
279               "sensitive" => false,
280               "note" => "lain",
281               "pleroma" => %{
282                 "discoverable" => false,
283                 "actor_type" => "Person"
284               },
285               "fields" => []
286             },
287             "statuses_count" => 1,
288             "locked" => false,
289             "created_at" => "2020-04-16T13:40:15.000Z",
290             "display_name" => "lain",
291             "fields" => [],
292             "acct" => "lain@dontbulling.me",
293             "id" => "9u6Qw6TAZANpqokMkK",
294             "emojis" => [],
295             "avatar_static" =>
296               "https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg",
297             "username" => "lain",
298             "followers_count" => 0,
299             "header" => "https://originalpatchou.li/images/banner.png",
300             "bot" => false,
301             "note" => "lain",
302             "url" => "https://dontbulling.me/users/lain"
303           },
304           "id" => "1",
305           "unread" => 2
306         }
307       ]
308     }
309   end
310
311   def chat_messages_response do
312     %Schema{
313       title: "ChatMessagesResponse",
314       description: "Response schema for multiple ChatMessages",
315       type: :array,
316       items: ChatMessage,
317       example: [
318         %{
319           "emojis" => [
320             %{
321               "static_url" => "https://dontbulling.me/emoji/Firefox.gif",
322               "visible_in_picker" => false,
323               "shortcode" => "firefox",
324               "url" => "https://dontbulling.me/emoji/Firefox.gif"
325             }
326           ],
327           "created_at" => "2020-04-21T15:11:46.000Z",
328           "content" => "Check this out :firefox:",
329           "id" => "13",
330           "chat_id" => "1",
331           "account_id" => "someflakeid",
332           "unread" => false
333         },
334         %{
335           "account_id" => "someflakeid",
336           "content" => "Whats' up?",
337           "id" => "12",
338           "chat_id" => "1",
339           "emojis" => [],
340           "created_at" => "2020-04-21T15:06:45.000Z",
341           "unread" => false
342         }
343       ]
344     }
345   end
346
347   def chat_message_create do
348     %Schema{
349       title: "ChatMessageCreateRequest",
350       description: "POST body for creating an chat message",
351       type: :object,
352       properties: %{
353         content: %Schema{
354           type: :string,
355           description: "The content of your message. Optional if media_id is present"
356         },
357         media_id: %Schema{type: :string, description: "The id of an upload"}
358       },
359       example: %{
360         "content" => "Hey wanna buy feet pics?",
361         "media_id" => "134234"
362       }
363     }
364   end
365
366   def mark_as_read do
367     %Schema{
368       title: "MarkAsReadRequest",
369       description: "POST body for marking a number of chat messages as read",
370       type: :object,
371       required: [:last_read_id],
372       properties: %{
373         last_read_id: %Schema{
374           type: :string,
375           description: "The content of your message."
376         }
377       },
378       example: %{
379         "last_read_id" => "abcdef12456"
380       }
381     }
382   end
383 end