4ce3e7419cd44bb07e24af4c120c1d15ea8e7c72
[akkoma] / lib / pleroma / web / pleroma_api / controllers / chat_controller.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4 defmodule Pleroma.Web.PleromaAPI.ChatController do
5 use Pleroma.Web, :controller
6
7 alias Pleroma.Activity
8 alias Pleroma.Chat
9 alias Pleroma.Object
10 alias Pleroma.Pagination
11 alias Pleroma.Plugs.OAuthScopesPlug
12 alias Pleroma.Repo
13 alias Pleroma.User
14 alias Pleroma.Web.CommonAPI
15 alias Pleroma.Web.PleromaAPI.ChatMessageView
16 alias Pleroma.Web.PleromaAPI.ChatView
17
18 import Ecto.Query
19 import Pleroma.Web.ActivityPub.ObjectValidator, only: [stringify_keys: 1]
20
21 action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
22
23 plug(
24 OAuthScopesPlug,
25 %{scopes: ["write:statuses"]}
26 when action in [:post_chat_message, :create, :mark_as_read, :delete_message]
27 )
28
29 plug(
30 OAuthScopesPlug,
31 %{scopes: ["read:statuses"]} when action in [:messages, :index, :show]
32 )
33
34 plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
35
36 defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ChatOperation
37
38 def delete_message(%{assigns: %{user: %{ap_id: actor} = user}} = conn, %{
39 message_id: id
40 }) do
41 with %Object{
42 data: %{
43 "actor" => ^actor,
44 "id" => object,
45 "to" => [recipient],
46 "type" => "ChatMessage"
47 }
48 } = message <- Object.get_by_id(id),
49 %Chat{} = chat <- Chat.get(user.id, recipient),
50 %Activity{} = activity <- Activity.get_create_by_object_ap_id(object),
51 {:ok, _delete} <- CommonAPI.delete(activity.id, user) do
52 conn
53 |> put_view(ChatMessageView)
54 |> render("show.json", for: user, object: message, chat: chat)
55 else
56 _e -> {:error, :could_not_delete}
57 end
58 end
59
60 def post_chat_message(
61 %{body_params: %{content: content} = params, assigns: %{user: %{id: user_id} = user}} =
62 conn,
63 %{
64 id: id
65 }
66 ) do
67 with %Chat{} = chat <- Repo.get_by(Chat, id: id, user_id: user_id),
68 %User{} = recipient <- User.get_cached_by_ap_id(chat.recipient),
69 {:ok, activity} <-
70 CommonAPI.post_chat_message(user, recipient, content, media_id: params[:media_id]),
71 message <- Object.normalize(activity) do
72 conn
73 |> put_view(ChatMessageView)
74 |> render("show.json", for: user, object: message, chat: chat)
75 end
76 end
77
78 def mark_as_read(%{assigns: %{user: %{id: user_id}}} = conn, %{id: id}) do
79 with %Chat{} = chat <- Repo.get_by(Chat, id: id, user_id: user_id),
80 {:ok, chat} <- Chat.mark_as_read(chat) do
81 conn
82 |> put_view(ChatView)
83 |> render("show.json", chat: chat)
84 end
85 end
86
87 def messages(%{assigns: %{user: %{id: user_id} = user}} = conn, %{id: id} = params) do
88 with %Chat{} = chat <- Repo.get_by(Chat, id: id, user_id: user_id) do
89 messages =
90 chat
91 |> Chat.messages_for_chat_query()
92 |> Pagination.fetch_paginated(params |> stringify_keys())
93
94 conn
95 |> put_view(ChatMessageView)
96 |> render("index.json", for: user, objects: messages, chat: chat)
97 else
98 _ ->
99 conn
100 |> put_status(:not_found)
101 |> json(%{error: "not found"})
102 end
103 end
104
105 def index(%{assigns: %{user: %{id: user_id}}} = conn, params) do
106 chats =
107 from(c in Chat,
108 where: c.user_id == ^user_id,
109 order_by: [desc: c.updated_at]
110 )
111 |> Pagination.fetch_paginated(params |> stringify_keys)
112
113 conn
114 |> put_view(ChatView)
115 |> render("index.json", chats: chats)
116 end
117
118 def create(%{assigns: %{user: user}} = conn, params) do
119 with %User{ap_id: recipient} <- User.get_by_id(params[:id]),
120 {:ok, %Chat{} = chat} <- Chat.get_or_create(user.id, recipient) do
121 conn
122 |> put_view(ChatView)
123 |> render("show.json", chat: chat)
124 end
125 end
126
127 def show(%{assigns: %{user: user}} = conn, params) do
128 with %Chat{} = chat <- Repo.get_by(Chat, user_id: user.id, id: params[:id]) do
129 conn
130 |> put_view(ChatView)
131 |> render("show.json", chat: chat)
132 end
133 end
134 end