Add setAccountData to Matrix rooms

4-transfer-api
Bram 2024-07-19 09:01:42 +02:00
parent 5319f47145
commit 8b2db7bff6
5 changed files with 198 additions and 8 deletions

View File

@ -1,6 +1,6 @@
module Internal.Api.Main exposing
( Msg
, sendMessageEvent, sendStateEvent, sync
, sendMessageEvent, sendStateEvent, setRoomAccountData, sync
)
{-|
@ -18,7 +18,7 @@ This module is used as reference for getting
## Actions
@docs sendMessageEvent, sendStateEvent, sync
@docs sendMessageEvent, sendStateEvent, setRoomAccountData, sync
-}
@ -26,6 +26,8 @@ import Internal.Api.Task as ITask exposing (Backpack)
import Internal.Tools.Json as Json
import Internal.Values.Context as Context
import Internal.Values.Envelope as E
import Internal.Values.User as User
import Internal.Values.Vault as V
{-| Update message type that is being returned.
@ -84,6 +86,39 @@ sendStateEvent env data =
(Context.apiFormat env.context)
{-| Set the account data for a Matrix room.
-}
setRoomAccountData :
E.Envelope a
->
{ content : Json.Value
, eventType : String
, roomId : String
, toMsg : Msg -> msg
}
-> Cmd msg
setRoomAccountData env data =
case env.context.user of
Just u ->
ITask.run
data.toMsg
(ITask.setRoomAccountData
{ content = data.content
, eventType = data.eventType
, roomId = data.roomId
, userId = User.toString u
}
)
(Context.apiFormat env.context)
Nothing ->
Cmd.none
-- TODO: Return error about lacking user capabilities
{-| Sync with the Matrix API to stay up-to-date.
-}
sync :

View File

@ -0,0 +1,112 @@
module Internal.Api.SetRoomAccountData.Api exposing (..)
{-|
# Set Room Account Data
This module allows the developer to set account data to a Matrix room.
@docs Phantom, setRoomAccountData
-}
import Internal.Api.Api as A
import Internal.Api.Invite.Api exposing (Phantom)
import Internal.Api.Request as R
import Internal.Config.Log exposing (log)
import Internal.Config.Text as Text
import Internal.Tools.Json as Json
import Internal.Values.Envelope as E
import Internal.Values.Room as R
import Internal.Values.Vault as V
{-| Set account data to a Matrix room.
-}
setRoomAccountData : SetRoomAccountDataInput -> A.TaskChain (Phantom a) (Phantom a)
setRoomAccountData =
A.startWithVersion "r0.0.0" setRoomAccountDataV1
|> A.sameForVersion "r0.0.1"
|> A.sameForVersion "r0.1.0"
|> A.sameForVersion "r0.2.0"
|> A.sameForVersion "r0.3.0"
|> A.sameForVersion "r0.4.0"
|> A.sameForVersion "r0.5.0"
|> A.sameForVersion "r0.6.0"
|> A.sameForVersion "r0.6.1"
|> A.forVersion "v1.1" setRoomAccountDataV2
|> A.sameForVersion "v1.2"
|> A.sameForVersion "v1.3"
|> A.sameForVersion "v1.4"
|> A.sameForVersion "v1.5"
|> A.sameForVersion "v1.6"
|> A.sameForVersion "v1.7"
|> A.sameForVersion "v1.8"
|> A.sameForVersion "v1.9"
|> A.sameForVersion "v1.10"
|> A.sameForVersion "v1.11"
|> A.versionChain
{-| Context needed for setting account data on a room.
-}
type alias Phantom a =
{ a | accessToken : (), baseUrl : (), versions : () }
type alias PhantomV1 a =
{ a | accessToken : (), baseUrl : () }
type alias SetRoomAccountDataInput =
{ content : Json.Value, eventType : String, roomId : String, userId : String }
type alias SetRoomAccountDataInputV1 a =
{ a | content : Json.Value, eventType : String, roomId : String, userId : String }
type alias SetRoomAccountDataOutputV1 =
()
setRoomAccountDataV1 : SetRoomAccountDataInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
setRoomAccountDataV1 { content, eventType, roomId, userId } =
A.request
{ attributes = [ R.accessToken, R.fullBody content ]
, coder = coderV1
, contextChange = always identity
, method = "PUT"
, path = [ "_matrix", "client", "r0", "user", userId, "rooms", roomId, "account_data", eventType ]
, toUpdate =
\() ->
( R.SetAccountData eventType content
|> V.MapRoom roomId
|> E.ContentUpdate
, []
)
}
setRoomAccountDataV2 : SetRoomAccountDataInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
setRoomAccountDataV2 { content, eventType, roomId, userId } =
A.request
{ attributes = [ R.accessToken, R.fullBody content ]
, coder = coderV1
, contextChange = always identity
, method = "PUT"
, path = [ "_matrix", "client", "v3", "user", userId, "rooms", roomId, "account_data", eventType ]
, toUpdate =
\() ->
( R.SetAccountData eventType content
|> V.MapRoom roomId
|> E.ContentUpdate
, []
)
}
coderV1 : Json.Coder SetRoomAccountDataOutputV1
coderV1 =
Json.unit

View File

@ -1,6 +1,6 @@
module Internal.Api.Task exposing
( Task, run, Backpack
, sendMessageEvent, sendStateEvent, sync
, sendMessageEvent, sendStateEvent, setRoomAccountData, sync
)
{-|
@ -23,7 +23,7 @@ up-to-date.
## Tasks
@docs sendMessageEvent, sendStateEvent, sync
@docs sendMessageEvent, sendStateEvent, setRoomAccountData, sync
-}
@ -34,6 +34,7 @@ import Internal.Api.Now.Api
import Internal.Api.Request as Request
import Internal.Api.SendMessageEvent.Api
import Internal.Api.SendStateEvent.Api
import Internal.Api.SetRoomAccountData.Api
import Internal.Api.Sync.Api
import Internal.Api.Versions.Api
import Internal.Config.Log exposing (Log, log)
@ -242,6 +243,15 @@ sendStateEvent input =
|> finishTask
{-| Set account data for a Matrix room.
-}
setRoomAccountData : { content : Json.Value, eventType : String, roomId : String, userId : String } -> Task
setRoomAccountData input =
makeVBA
|> C.andThen (Internal.Api.SetRoomAccountData.Api.setRoomAccountData input)
|> finishTask
{-| Sync with the Matrix API to stay up-to-date.
-}
sync : { fullState : Maybe Bool, presence : Maybe String, since : Maybe String, timeout : Maybe Int } -> Task

View File

@ -1,5 +1,5 @@
module Internal.Tools.Json exposing
( Coder, string, bool, int, float, value
( Coder, string, bool, int, float, value, unit
, Encoder, encode, Decoder, decode, Value
, succeed, fail, andThen, lazy, map
, Docs(..), RequiredField(..), toDocs
@ -29,7 +29,7 @@ data types. Because this module uses dynamic builder types, this also means it
is relatively easy to write documentation for any data type that uses this
module to build its encoders and decoders.
@docs Coder, string, bool, int, float, value
@docs Coder, string, bool, int, float, value, unit
## JSON Coding
@ -165,6 +165,7 @@ type Docs
| DocsRiskyMap (Descriptive { content : Docs, failure : List String })
| DocsSet Docs
| DocsString
| DocsUnit
| DocsValue
@ -1462,6 +1463,18 @@ toEncodeField (Field data) =
( data.fieldName, data.toField >> data.encoder )
{-| Completely ignore whatever needs to be encoded, and simply return a unit
value.
-}
unit : Coder ()
unit =
Coder
{ encoder = \() -> E.object []
, decoder = D.succeed ( (), [] )
, docs = DocsUnit
}
{-| Do not do anything useful with a JSON value, just bring it to Elm as a
JavaScript value.
-}

View File

@ -1,6 +1,6 @@
module Matrix.Room exposing
( Room, mostRecentEvents, roomId
, getAccountData
, getAccountData, setAccountData
, sendMessageEvent, sendStateEvent
)
@ -34,7 +34,7 @@ data is linked to the user account: other logged in devices can see the account
data too, as the server synchronizes it, but the server shouldn´t show it to
other users.
@docs getAccountData
@docs getAccountData, setAccountData
## Sending events
@ -126,3 +126,23 @@ sendStateEvent data =
, stateKey = data.stateKey
, toMsg = Types.VaultUpdate >> data.toMsg
}
{-| Set account data to a Matrix room.
-}
setAccountData :
{ content : E.Value
, eventType : String
, room : Room
, toMsg : Types.VaultUpdate -> msg
}
-> Cmd msg
setAccountData data =
case data.room of
Room room ->
Api.setRoomAccountData room
{ content = data.content
, eventType = data.eventType
, roomId = roomId data.room
, toMsg = Types.VaultUpdate >> data.toMsg
}