Implement client send state event endpoint
This commit is contained in:
parent
c0055b6905
commit
d4b058e739
5 changed files with 88 additions and 15 deletions
|
@ -58,15 +58,16 @@ Here, implemented and some unimplemented features are listed.
|
||||||
- POST /_matrix/client/r0/rooms/{roomId}/kick
|
- POST /_matrix/client/r0/rooms/{roomId}/kick
|
||||||
- POST /_matrix/client/r0/rooms/{roomId}/ban
|
- POST /_matrix/client/r0/rooms/{roomId}/ban
|
||||||
- POST /_matrix/client/r0/rooms/{roomId}/unban
|
- POST /_matrix/client/r0/rooms/{roomId}/unban
|
||||||
|
- PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}
|
||||||
- PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}
|
- PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}
|
||||||
- GET /_matrix/client/r0/rooms/{roomId}/messages: Except filtering.
|
- GET /_matrix/client/r0/rooms/{roomId}/messages: Except filtering.
|
||||||
- GET /_matrix/client/r0/directory/list/room/{roomId}
|
- GET /_matrix/client/r0/directory/list/room/{roomId}
|
||||||
- PUT /_matrix/client/r0/directory/list/room/{roomId}
|
- PUT /_matrix/client/r0/directory/list/room/{roomId}
|
||||||
- GET /_matrix/client/r0/capabilities
|
- GET /_matrix/client/r0/capabilities
|
||||||
- GET /_matrix/client/r0/profile/{userId}
|
- GET /_matrix/client/r0/profile/{userId}
|
||||||
- GET /_matrix/client/r0/profile/{userId}/avatar_url: Except federation.
|
- GET /_matrix/client/r0/profile/{userId}/avatar_url
|
||||||
- PUT /_matrix/client/r0/profile/{userId}/avatar_url
|
- PUT /_matrix/client/r0/profile/{userId}/avatar_url
|
||||||
- GET /_matrix/client/r0/profile/{userId}/displayname: Except federation.
|
- GET /_matrix/client/r0/profile/{userId}/displayname
|
||||||
- PUT /_matrix/client/r0/profile/{userId}/displayname
|
- PUT /_matrix/client/r0/profile/{userId}/displayname
|
||||||
|
|
||||||
#### Federation API
|
#### Federation API
|
||||||
|
|
|
@ -165,12 +165,21 @@ defmodule Architex.RoomServer do
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Send a message to this room.
|
Send a message event to this room.
|
||||||
"""
|
"""
|
||||||
@spec send_message(pid(), Account.t(), Device.t(), String.t(), map(), String.t()) ::
|
@spec send_message_event(pid(), Account.t(), Device.t(), String.t(), map(), String.t()) ::
|
||||||
{:ok, String.t()} | {:error, atom()}
|
{:ok, String.t()} | {:error, atom()}
|
||||||
def send_message(pid, account, device, event_type, content, txn_id) do
|
def send_message_event(pid, account, device, event_type, content, txn_id) do
|
||||||
GenServer.call(pid, {:send_message, account, device, event_type, content, txn_id})
|
GenServer.call(pid, {:send_message_event, account, device, event_type, content, txn_id})
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Send a state event to this room.
|
||||||
|
"""
|
||||||
|
@spec send_state_event(pid(), Account.t(), String.t(), map(), String.t()) ::
|
||||||
|
{:ok, String.t()} | {:error, atom()}
|
||||||
|
def send_state_event(pid, account, event_type, content, state_key) do
|
||||||
|
GenServer.call(pid, {:send_state_event, account, event_type, content, state_key})
|
||||||
end
|
end
|
||||||
|
|
||||||
### Implementation
|
### Implementation
|
||||||
|
@ -354,13 +363,13 @@ defmodule Architex.RoomServer do
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_call(
|
def handle_call(
|
||||||
{:send_message, account, device, event_type, content, txn_id},
|
{:send_message_event, account, device, event_type, content, txn_id},
|
||||||
_from,
|
_from,
|
||||||
%{room: room, state_set: state_set} = state
|
%{room: room, state_set: state_set} = state
|
||||||
) do
|
) do
|
||||||
message_event = Event.custom_message(room, account, event_type, content)
|
message_event = Event.custom_event(room, account, event_type, content)
|
||||||
|
|
||||||
case Repo.transaction(insert_custom_message(state_set, room, device, message_event, txn_id)) do
|
case Repo.transaction(insert_event_with_txn(state_set, room, device, message_event, txn_id)) do
|
||||||
{:ok, {state_set, room, event_id}} ->
|
{:ok, {state_set, room, event_id}} ->
|
||||||
{:reply, {:ok, event_id}, %{state | state_set: state_set, room: room}}
|
{:reply, {:ok, event_id}, %{state | state_set: state_set, room: room}}
|
||||||
|
|
||||||
|
@ -369,7 +378,25 @@ defmodule Architex.RoomServer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp insert_custom_message(
|
def handle_call(
|
||||||
|
{:send_state_event, account, event_type, content, state_key},
|
||||||
|
_from,
|
||||||
|
%{room: room, state_set: state_set} = state
|
||||||
|
) do
|
||||||
|
state_event = Event.custom_state_event(room, account, event_type, content, state_key)
|
||||||
|
|
||||||
|
case Repo.transaction(insert_single_event(room, state_set, state_event)) do
|
||||||
|
{:ok, {state_set, room, %Event{id: event_id}}} ->
|
||||||
|
{:reply, {:ok, event_id}, %{state | state_set: state_set, room: room}}
|
||||||
|
|
||||||
|
{:error, reason} ->
|
||||||
|
{:reply, {:error, reason}, state}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec insert_event_with_txn(t(), Room.t(), Device.t(), %Event{}, String.t()) ::
|
||||||
|
(() -> {t(), Room.t(), String.t()} | {:error, atom()})
|
||||||
|
defp insert_event_with_txn(
|
||||||
state_set,
|
state_set,
|
||||||
room,
|
room,
|
||||||
%Device{nid: device_nid} = device,
|
%Device{nid: device_nid} = device,
|
||||||
|
|
|
@ -56,8 +56,8 @@ defmodule Architex.Event do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec custom_message(Room.t(), Account.t(), String.t(), map()) :: %Event{}
|
@spec custom_event(Room.t(), Account.t(), String.t(), map()) :: %Event{}
|
||||||
def custom_message(room, sender, type, content) do
|
def custom_event(room, sender, type, content) do
|
||||||
%Event{
|
%Event{
|
||||||
Event.new(room, sender)
|
Event.new(room, sender)
|
||||||
| type: type,
|
| type: type,
|
||||||
|
@ -65,6 +65,11 @@ defmodule Architex.Event do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec custom_state_event(Room.t(), Account.t(), String.t(), map(), String.t()) :: %Event{}
|
||||||
|
def custom_state_event(room, sender, type, content, state_key) do
|
||||||
|
%Event{custom_event(room, sender, type, content) | state_key: state_key}
|
||||||
|
end
|
||||||
|
|
||||||
@spec is_control_event(t()) :: boolean()
|
@spec is_control_event(t()) :: boolean()
|
||||||
def is_control_event(%Event{type: "m.room.power_levels", state_key: ""}), do: true
|
def is_control_event(%Event{type: "m.room.power_levels", state_key: ""}), do: true
|
||||||
def is_control_event(%Event{type: "m.room.join_rules", state_key: ""}), do: true
|
def is_control_event(%Event{type: "m.room.join_rules", state_key: ""}), do: true
|
||||||
|
|
|
@ -205,7 +205,7 @@ defmodule ArchitexWeb.Client.RoomController do
|
||||||
|
|
||||||
Action for PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}.
|
Action for PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}.
|
||||||
"""
|
"""
|
||||||
def send_message(
|
def send_message_event(
|
||||||
%Conn{assigns: %{account: account, device: device}, body_params: body_params} = conn,
|
%Conn{assigns: %{account: account, device: device}, body_params: body_params} = conn,
|
||||||
%{
|
%{
|
||||||
"room_id" => room_id,
|
"room_id" => room_id,
|
||||||
|
@ -215,7 +215,46 @@ defmodule ArchitexWeb.Client.RoomController do
|
||||||
) do
|
) do
|
||||||
case RoomServer.get_room_server(room_id) do
|
case RoomServer.get_room_server(room_id) do
|
||||||
{:ok, pid} ->
|
{:ok, pid} ->
|
||||||
case RoomServer.send_message(pid, account, device, event_type, body_params, txn_id) do
|
case RoomServer.send_message_event(pid, account, device, event_type, body_params, txn_id) do
|
||||||
|
{:ok, event_id} ->
|
||||||
|
conn
|
||||||
|
|> put_status(200)
|
||||||
|
|> json(%{event_id: event_id})
|
||||||
|
|
||||||
|
{:error, _} ->
|
||||||
|
put_error(conn, :unknown)
|
||||||
|
end
|
||||||
|
|
||||||
|
{:error, :not_found} ->
|
||||||
|
put_error(conn, :not_found, "The given room was not found.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
State events can be sent using this endpoint.
|
||||||
|
|
||||||
|
I don't know why, but the spec is very scared of trailing slashes and accidentally
|
||||||
|
using a transaction ID as the state key.
|
||||||
|
I take no precaution against these things, it's the responsibility of the client.
|
||||||
|
Action for PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}.
|
||||||
|
"""
|
||||||
|
def send_state_event(conn, %{"state_key" => [state_key | _]} = params) do
|
||||||
|
do_send_state_event(conn, params, state_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_state_event(conn, params) do
|
||||||
|
do_send_state_event(conn, params, "")
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_send_state_event(
|
||||||
|
%Conn{assigns: %{account: account}, body_params: body_params} = conn,
|
||||||
|
%{"room_id" => room_id, "event_type" => event_type},
|
||||||
|
state_key
|
||||||
|
) do
|
||||||
|
# TODO: Check aliases according to spec.
|
||||||
|
case RoomServer.get_room_server(room_id) do
|
||||||
|
{:ok, pid} ->
|
||||||
|
case RoomServer.send_state_event(pid, account, event_type, body_params, state_key) do
|
||||||
{:ok, event_id} ->
|
{:ok, event_id} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(200)
|
|> put_status(200)
|
||||||
|
|
|
@ -85,8 +85,9 @@ defmodule ArchitexWeb.Router do
|
||||||
post "/kick", RoomController, :kick
|
post "/kick", RoomController, :kick
|
||||||
post "/ban", RoomController, :ban
|
post "/ban", RoomController, :ban
|
||||||
post "/unban", RoomController, :unban
|
post "/unban", RoomController, :unban
|
||||||
put "/send/:event_type/:txn_id", RoomController, :send_message
|
put "/send/:event_type/:txn_id", RoomController, :send_message_event
|
||||||
get "/messages", RoomController, :messages
|
get "/messages", RoomController, :messages
|
||||||
|
put "/state/:event_type/*state_key", RoomController, :send_state_event
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue