summaryrefslogtreecommitdiff
path: root/lib/polyjuice/client.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/polyjuice/client.ex')
-rw-r--r--lib/polyjuice/client.ex182
1 files changed, 48 insertions, 134 deletions
diff --git a/lib/polyjuice/client.ex b/lib/polyjuice/client.ex
index 0c60241..93b672b 100644
--- a/lib/polyjuice/client.ex
+++ b/lib/polyjuice/client.ex
@@ -15,12 +15,38 @@
defmodule Polyjuice.Client do
@moduledoc """
Matrix client functions.
+
+ The struct in this module, or any struct that implements the
+ `Polyjuice.Client.API` protocol, can be used to connect to a Matrix server
+ using the functions from submodules.
+
+ - `Polyjuice.Client.Filter`: build filters for use with sync
+ - `Polyjuice.Client.Room`: interact with rooms, such as sending messages
+ - `Polyjuice.Client.MsgBuilder`: build message contents
+
+ To sync with the homeserver, start a process using the child spec returned by
+ `Polyjuice.Client.API.sync_child_spec/3`.
+
"""
require Logger
+ @typedoc """
+ Matrix client data.
+
+ - `base_url` (string): Required. The base URL for the homeserver.
+ - `access_token` (string): Required to call endpoints that require an
+ authenticated user. The user's access token.
+ - `user_id` (string): Required for some endpoints and for sync. The user's
+ Matrix ID.
+ - `storage` (`Polyjuice.Client.Storage`): Required for some endpoints and for
+ sync. Storage for the client.
+
+ """
@type t :: %__MODULE__{
base_url: String.t(),
- access_token: String.t()
+ access_token: String.t(),
+ user_id: String.t(),
+ storage: Polyjuice.Client.Storage.t()
}
@enforce_keys [:base_url]
@@ -42,8 +68,10 @@ defmodule Polyjuice.Client do
"""
@doc """
- Call a Matrix client API. This is a lower-level function; generally, clients
- will want to call one of the higher-level functions from `Polyjuice.Client`.
+ Call a Matrix client API.
+
+ This is a lower-level function; generally, clients will want to call one of
+ the higher-level functions from `Polyjuice.Client`.
"""
@spec call(
client_api :: Polyjuice.Client.API.t(),
@@ -59,10 +87,26 @@ defmodule Polyjuice.Client do
@doc """
Get the child spec for the sync process.
+
+ `listener` will receive messages with the sync results. Messages include:
+
+ - `{:connected}`: the process has connected to the homeserver
+ - `{:disconnected}`: the process has been disconnected from the homeserver
+ - `{:initial_sync_completed}`: the first sync has completed
+ - `{:limited, room_id, prev_batch}`: a room's timeline has been limited.
+ Previous messages can be fetched using the `prev_batch`
+ - `{:message, room_id, event}`: a message event has been received
+ - `{:state, room_id, event}`: a state event has been received
+ - `{:invite, room_id, inviter, invite_state}`: the user was invited to a room
+ - `{:left, room_id}`: the user left a room
+
+ `opts` is a keyword list of options:
+
+ - `filter:` (string or map) the filter to use with the sync
"""
@spec sync_child_spec(
client_api :: Polyjuice.Client.API.t(),
- listener :: pid() | fun(),
+ listener :: pid(),
opts :: list()
) :: map()
def sync_child_spec(client_api, listener, opts \\ [])
@@ -110,134 +154,4 @@ defmodule Polyjuice.Client do
Polyjuice.Client.Sync.child_spec([client, listener | opts])
end
end
-
- @doc """
- Send a message to a room.
-
- `msg` can either be anything that implements the
- `Polyjuice.Client.MsgBuilder.MsgData` protocol (which will be sent as an
- `m.message`), or a map (which specifies the full message content).
-
- Examples:
-
- Polyjuice.Client.send_message(client, "text message", "!room_id")
-
- Polyjuice.Client.send_message(
- client,
- {"message with formatting", "<i>message</i> with <b>formatting</b>"},
- "!room_id"
- )
-
- Polyjuice.Client.send_message(
- client,
- ["Hello, ", Polyjuice.Client.MsgBuilder.mention("@world:example.com")],
- "!room_id"
- )
-
- Polyjuice.Client.send_message(
- client,
- %{"msgtype" => "m.notice", "body" => "using full message content"},
- "!room_id"
- )
-
- """
- @spec send_message(
- client_api :: Polyjuice.Client.API.t(),
- msg :: map | Polyjuice.Client.MsgBuilder.MsgData.t(),
- room :: String.t()
- ) :: String.t()
- def send_message(client_api, msg, room) when is_binary(room) do
- cond do
- Polyjuice.Client.MsgBuilder.MsgData.impl_for(msg) != nil ->
- Polyjuice.Client.API.call(
- client_api,
- %Polyjuice.Client.Endpoint.PutRoomsSend{
- txn_id: Polyjuice.Client.API.transaction_id(client_api),
- room: room,
- event_type: "m.room.message",
- message: Polyjuice.Client.MsgBuilder.to_message(msg)
- }
- )
-
- is_map(msg) and not Map.has_key?(msg, :__struct__) ->
- Polyjuice.Client.API.call(
- client_api,
- %Polyjuice.Client.Endpoint.PutRoomsSend{
- txn_id: Polyjuice.Client.API.transaction_id(client_api),
- room: room,
- event_type: "m.room.message",
- message: msg
- }
- )
-
- true ->
- raise ArgumentError, message: "invalid argument msg"
- end
- end
-
- @doc """
- Send an event to a room.
- """
- @spec send_event(
- client_api :: Polyjuice.Client.API.t(),
- event_type :: String.t(),
- event :: map,
- room :: String.t()
- ) :: String.t()
- def send_event(client_api, event_type, event, room)
- when is_binary(event_type) and is_map(event) and is_binary(room) do
- Polyjuice.Client.API.call(
- client_api,
- %Polyjuice.Client.Endpoint.PutRoomsSend{
- txn_id: Polyjuice.Client.API.transaction_id(client_api),
- room: room,
- event_type: event_type,
- message: event
- }
- )
- end
-
- @doc """
- Update the client's read receipt (of the given type) to the given message in the
- given room.
- """
- @spec update_read_receipt(
- client_api :: Polyjuice.Client.API.t(),
- room :: String.t(),
- event_id :: String.t(),
- receipt_type :: String.t()
- ) :: Any
- def update_read_receipt(client_api, room, event_id, receipt_type \\ "m.read")
- when is_binary(room) and is_binary(event_id) and is_binary(receipt_type) do
- Polyjuice.Client.API.call(
- client_api,
- %Polyjuice.Client.Endpoint.PostRoomsReceipt{
- room: room,
- event_id: event_id,
- receipt_type: receipt_type
- }
- )
- end
-
- @doc """
- Join a room.
- """
- @spec join_room(
- client_api :: Polyjuice.Client.API.t(),
- room :: String.t(),
- servers :: list(String.t()),
- third_party_join :: map | nil
- ) :: Any
- def join_room(client_api, room, servers \\ [], third_party_signed \\ nil)
- when is_binary(room) and is_list(servers) and
- (is_map(third_party_signed) or third_party_signed == nil) do
- Polyjuice.Client.API.call(
- client_api,
- %Polyjuice.Client.Endpoint.PostJoin{
- room: room,
- servers: servers,
- third_party_signed: third_party_signed
- }
- )
- end
end