diff options
Diffstat (limited to 'lib/polyjuice/client.ex')
-rw-r--r-- | lib/polyjuice/client.ex | 182 |
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 |