Add exposed Event module

3-event
Bram 2023-12-24 00:03:07 +01:00
parent 5065ed05ff
commit 1a819cbe39
3 changed files with 170 additions and 23 deletions

View File

@ -6,6 +6,7 @@
"version": "2.0.0", "version": "2.0.0",
"exposed-modules": [ "exposed-modules": [
"Matrix", "Matrix",
"Matrix.Event",
"Matrix.Settings", "Matrix.Settings",
"Internal.Config.Default", "Internal.Config.Default",
"Internal.Config.Leaks", "Internal.Config.Leaks",

View File

@ -66,7 +66,7 @@ type UnsignedData
= UnsignedData = UnsignedData
{ age : Maybe Int { age : Maybe Int
, prevContent : Maybe E.Value , prevContent : Maybe E.Value
, redactedBecause : Maybe Event , redactedBecause : Maybe IEvent
, transactionId : Maybe String , transactionId : Maybe String
} }
@ -95,6 +95,11 @@ content =
-} -}
decoder : D.Decoder Event decoder : D.Decoder Event
decoder = decoder =
Envelope.decoder decoderInternal
decoderInternal : D.Decoder IEvent
decoderInternal =
D.map8 IEvent D.map8 IEvent
(D.field "content" D.value) (D.field "content" D.value)
(D.field "eventId" D.string) (D.field "eventId" D.string)
@ -104,7 +109,6 @@ decoder =
(D.opField "stateKey" D.string) (D.opField "stateKey" D.string)
(D.field "eventType" D.string) (D.field "eventType" D.string)
(D.opField "unsigned" decoderUnsignedData) (D.opField "unsigned" decoderUnsignedData)
|> Envelope.decoder
{-| Decode Unsigned Data from a JSON value. {-| Decode Unsigned Data from a JSON value.
@ -114,29 +118,30 @@ decoderUnsignedData =
D.map4 (\a b c d -> UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }) D.map4 (\a b c d -> UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d })
(D.opField "age" D.int) (D.opField "age" D.int)
(D.opField "prevContent" D.value) (D.opField "prevContent" D.value)
(D.opField "redactedBecause" (D.lazy (\_ -> decoder))) (D.opField "redactedBecause" (D.lazy (\_ -> decoderInternal)))
(D.opField "transactionId" D.string) (D.opField "transactionId" D.string)
{-| Encode an Event into a JSON value. {-| Encode an Event into a JSON value.
-} -}
encode : Event -> E.Value encode : Event -> E.Value
encode envelope = encode =
Envelope.encode Envelope.encode encodeInternal
(\event ->
E.maybeObject
[ ( "content", Just event.content ) encodeInternal : IEvent -> E.Value
, ( "eventId", Just <| E.string event.eventId ) encodeInternal event =
, ( "originServerTs", Just <| Timestamp.encode event.originServerTs ) E.maybeObject
, ( "roomId", Just <| E.string event.roomId ) [ ( "content", Just event.content )
, ( "sender", Just <| E.string event.sender ) , ( "eventId", Just <| E.string event.eventId )
, ( "stateKey", Maybe.map E.string event.stateKey ) , ( "originServerTs", Just <| Timestamp.encode event.originServerTs )
, ( "eventType", Just <| E.string event.eventType ) , ( "roomId", Just <| E.string event.roomId )
, ( "unsigned", Maybe.map encodeUnsignedData event.unsigned ) , ( "sender", Just <| E.string event.sender )
, ( "version", Just <| E.string Default.currentVersion ) , ( "stateKey", Maybe.map E.string event.stateKey )
] , ( "eventType", Just <| E.string event.eventType )
) , ( "unsigned", Maybe.map encodeUnsignedData event.unsigned )
envelope , ( "version", Just <| E.string Default.currentVersion )
]
{-| Encode Unsigned Data into a JSON value. {-| Encode Unsigned Data into a JSON value.
@ -146,7 +151,7 @@ encodeUnsignedData (UnsignedData data) =
E.maybeObject E.maybeObject
[ ( "age", Maybe.map E.int data.age ) [ ( "age", Maybe.map E.int data.age )
, ( "prevContent", data.prevContent ) , ( "prevContent", data.prevContent )
, ( "redactedBecause", Maybe.map encode data.redactedBecause ) , ( "redactedBecause", Maybe.map encodeInternal data.redactedBecause )
, ( "transactionId", Maybe.map E.string data.transactionId ) , ( "transactionId", Maybe.map E.string data.transactionId )
] ]
@ -204,14 +209,13 @@ prevContent envelope =
redacted it here. redacted it here.
-} -}
redactedBecause : Event -> Maybe Event redactedBecause : Event -> Maybe Event
redactedBecause envelope = redactedBecause =
Envelope.extract Envelope.mapMaybe
(\event -> (\event ->
Maybe.andThen Maybe.andThen
(\(UnsignedData data) -> data.redactedBecause) (\(UnsignedData data) -> data.redactedBecause)
event.unsigned event.unsigned
) )
envelope
{-| Unique id assigned to the Matrix room. You can use this room id to reference {-| Unique id assigned to the Matrix room. You can use this room id to reference

142
src/Matrix/Event.elm Normal file
View File

@ -0,0 +1,142 @@
module Matrix.Event exposing
( Event, content, eventType, stateKey
, eventId, originServerTs, roomId, sender
, previousContent, redactedBecause
)
{-|
# Matrix Events
This module contains all the functions necessary to view and manipulate Matrix
events.
## Event
@docs Event, content, eventType, stateKey
## Metadata
@docs eventId, originServerTs, roomId, sender
## Optional data
Occasionally, the Event might bring some extra information. Given how this
information isn't always applicable, it doesn't always exist.
@docs previousContent, redactedBecause
-}
import Internal.Values.Event as Internal
import Json.Encode
import Time
import Types exposing (Event(..))
{-| In Matrix, the primary form of communication is to send JSON values to one
another. These JSON values, together with their metadata, are bundled into Event
types. They contain information like:
- Who sent the JSON value
- How they intend you to decode it
- When they sent it
- In what room they sent it
-}
type alias Event =
Types.Event
{-| Receive the body of an Event, as created by the user that sent it.
-}
content : Event -> Json.Encode.Value
content (Event event) =
Internal.content event
{-| Determine the globally unique identifier for an event.
-}
eventId : Event -> String
eventId (Event event) =
Internal.eventId event
{-| To give a hint what the event's [content](#content) might look like, users
can use this eventType value to hint at how the JSON might be decoded.
Standard examples of event types are `m.room.message`, `m.room.member` and
`me.noordstar.game.chess.move`.
-}
eventType : Event -> String
eventType (Event event) =
Internal.eventType event
{-| Determine the timestamp of at what time the event was originally received by
the original homeserver.
Generally, this timestamp offers a relatively accurate indicator of when a
message was sent. However, this number isn't completely reliable! The timestamp
can be far in the past due to long network lag, and a (malicious) homeserver can
spoof this number to make it seem like something was sent ridiculously far in
the past - or even in the future.
-}
originServerTs : Event -> Time.Posix
originServerTs (Event event) =
Internal.originServerTs event
{-| Determine the previous `content` value for this event. This field is only a
`Just value` if the event is a state event, and the Matrix Vault has permission
to see the previous content.
-}
previousContent : Event -> Maybe Json.Encode.Value
previousContent (Event event) =
Internal.prevContent event
{-| If the event has been redacted, the homeserver can display the event that
redacted it here.
-}
redactedBecause : Event -> Maybe Event
redactedBecause (Event event) =
Internal.redactedBecause event
|> Maybe.map Event
{-| Unique id assigned to the Matrix room. You can use this room id to reference
or look up rooms.
-}
roomId : Event -> String
roomId (Event event) =
Internal.roomId event
{-| Determine the fully-qualified ID of the user who sent an event.
-}
sender : Event -> String
sender (Event event) =
Internal.sender event
{-| Determine an event's state key.
It is present if, and only if, the event is a _state_ event. The key makes the
piece of state unique in the room. Note that it is often `Just ""`. If it is not
present, its value is `Nothing`.
State keys starting with an `@` are reserved for referencing user IDs, such as
room members. With the exception of a few events, state events set with a given
user'd ID as the state key can only be set by that user.
-}
stateKey : Event -> Maybe String
stateKey (Event event) =
Internal.stateKey event