total rebase
[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(
141           :with_muted,
142           :query,
143           BooleanLike.schema(),
144           "Include chats from muted users"
145         )
146       ],
147       responses: %{
148         200 => Operation.response("The chats of the user", "application/json", chats_response())
149       },
150       security: [
151         %{
152           "oAuth" => ["read:chats"]
153         }
154       ]
155     }
156   end
157
158   def index2_operation do
159     %Operation{
160       tags: ["Chats"],
161       summary: "Retrieve list of chats",
162       operationId: "ChatController.index2",
163       parameters: [
164         Operation.parameter(
165           :with_muted,
166           :query,
167           BooleanLike.schema(),
168           "Include chats from muted users"
169         )
170         | pagination_params()
171       ],
172       responses: %{
173         200 => Operation.response("The chats of the user", "application/json", chats_response())
174       },
175       security: [
176         %{
177           "oAuth" => ["read:chats"]
178         }
179       ]
180     }
181   end
182
183   def messages_operation do
184     %Operation{
185       tags: ["Chats"],
186       summary: "Retrieve chat's messages",
187       operationId: "ChatController.messages",
188       parameters:
189         [Operation.parameter(:id, :path, :string, "The ID of the Chat")] ++
190           pagination_params(),
191       responses: %{
192         200 =>
193           Operation.response(
194             "The messages in the chat",
195             "application/json",
196             chat_messages_response()
197           ),
198         404 => Operation.response("Not Found", "application/json", ApiError)
199       },
200       security: [
201         %{
202           "oAuth" => ["read:chats"]
203         }
204       ]
205     }
206   end
207
208   def post_chat_message_operation do
209     %Operation{
210       tags: ["Chats"],
211       summary: "Post a message to the chat",
212       operationId: "ChatController.post_chat_message",
213       parameters: [
214         Operation.parameter(:id, :path, :string, "The ID of the Chat")
215       ],
216       requestBody: request_body("Parameters", chat_message_create()),
217       responses: %{
218         200 =>
219           Operation.response(
220             "The newly created ChatMessage",
221             "application/json",
222             ChatMessage
223           ),
224         400 => Operation.response("Bad Request", "application/json", ApiError),
225         422 => Operation.response("MRF Rejection", "application/json", ApiError)
226       },
227       security: [
228         %{
229           "oAuth" => ["write:chats"]
230         }
231       ]
232     }
233   end
234
235   def delete_message_operation do
236     %Operation{
237       tags: ["Chats"],
238       summary: "Delete message",
239       operationId: "ChatController.delete_message",
240       parameters: [
241         Operation.parameter(:id, :path, :string, "The ID of the Chat"),
242         Operation.parameter(:message_id, :path, :string, "The ID of the message")
243       ],
244       responses: %{
245         200 =>
246           Operation.response(
247             "The deleted ChatMessage",
248             "application/json",
249             ChatMessage
250           )
251       },
252       security: [
253         %{
254           "oAuth" => ["write:chats"]
255         }
256       ]
257     }
258   end
259
260   def chats_response do
261     %Schema{
262       title: "ChatsResponse",
263       description: "Response schema for multiple Chats",
264       type: :array,
265       items: Chat,
266       example: [
267         %{
268           "account" => %{
269             "pleroma" => %{
270               "is_admin" => false,
271               "is_confirmed" => true,
272               "hide_followers_count" => false,
273               "is_moderator" => false,
274               "hide_favorites" => true,
275               "ap_id" => "https://dontbulling.me/users/lain",
276               "hide_follows_count" => false,
277               "hide_follows" => false,
278               "background_image" => nil,
279               "skip_thread_containment" => false,
280               "hide_followers" => false,
281               "relationship" => %{},
282               "tags" => []
283             },
284             "avatar" =>
285               "https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg",
286             "following_count" => 0,
287             "header_static" => "https://originalpatchou.li/images/banner.png",
288             "source" => %{
289               "sensitive" => false,
290               "note" => "lain",
291               "pleroma" => %{
292                 "discoverable" => false,
293                 "actor_type" => "Person"
294               },
295               "fields" => []
296             },
297             "statuses_count" => 1,
298             "locked" => false,
299             "created_at" => "2020-04-16T13:40:15.000Z",
300             "display_name" => "lain",
301             "fields" => [],
302             "acct" => "lain@dontbulling.me",
303             "id" => "9u6Qw6TAZANpqokMkK",
304             "emojis" => [],
305             "avatar_static" =>
306               "https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg",
307             "username" => "lain",
308             "followers_count" => 0,
309             "header" => "https://originalpatchou.li/images/banner.png",
310             "bot" => false,
311             "note" => "lain",
312             "url" => "https://dontbulling.me/users/lain"
313           },
314           "id" => "1",
315           "unread" => 2
316         }
317       ]
318     }
319   end
320
321   def chat_messages_response do
322     %Schema{
323       title: "ChatMessagesResponse",
324       description: "Response schema for multiple ChatMessages",
325       type: :array,
326       items: ChatMessage,
327       example: [
328         %{
329           "emojis" => [
330             %{
331               "static_url" => "https://dontbulling.me/emoji/Firefox.gif",
332               "visible_in_picker" => false,
333               "shortcode" => "firefox",
334               "url" => "https://dontbulling.me/emoji/Firefox.gif"
335             }
336           ],
337           "created_at" => "2020-04-21T15:11:46.000Z",
338           "content" => "Check this out :firefox:",
339           "id" => "13",
340           "chat_id" => "1",
341           "account_id" => "someflakeid",
342           "unread" => false
343         },
344         %{
345           "account_id" => "someflakeid",
346           "content" => "Whats' up?",
347           "id" => "12",
348           "chat_id" => "1",
349           "emojis" => [],
350           "created_at" => "2020-04-21T15:06:45.000Z",
351           "unread" => false
352         }
353       ]
354     }
355   end
356
357   def chat_message_create do
358     %Schema{
359       title: "ChatMessageCreateRequest",
360       description: "POST body for creating an chat message",
361       type: :object,
362       properties: %{
363         content: %Schema{
364           type: :string,
365           description: "The content of your message. Optional if media_id is present"
366         },
367         media_id: %Schema{type: :string, description: "The id of an upload"}
368       },
369       example: %{
370         "content" => "Hey wanna buy feet pics?",
371         "media_id" => "134234"
372       }
373     }
374   end
375
376   def mark_as_read do
377     %Schema{
378       title: "MarkAsReadRequest",
379       description: "POST body for marking a number of chat messages as read",
380       type: :object,
381       required: [:last_read_id],
382       properties: %{
383         last_read_id: %Schema{
384           type: :string,
385           description: "The content of your message."
386         }
387       },
388       example: %{
389         "last_read_id" => "abcdef12456"
390       }
391     }
392   end
393 end