10
10
import asyncio
11
11
import logging
12
12
13
- from mautrix .types import JSON , UserID , RoomAlias , Event , SerializerError
13
+ from mautrix .types import JSON , UserID , RoomAlias , Event , EphemeralEvent , SerializerError
14
14
15
15
QueryFunc = Callable [[web .Request ], Awaitable [Optional [web .Response ]]]
16
16
HandlerFunc = Callable [[Event ], Awaitable ]
@@ -21,16 +21,18 @@ class AppServiceServerMixin:
21
21
log : logging .Logger
22
22
23
23
hs_token : str
24
+ ephemeral_events : bool
24
25
25
26
query_user : Callable [[UserID ], JSON ]
26
27
query_alias : Callable [[RoomAlias ], JSON ]
27
28
28
29
transactions : Set [str ]
29
30
event_handlers : List [HandlerFunc ]
30
31
31
- def __init__ (self ) -> None :
32
+ def __init__ (self , ephemeral_events : bool = False ) -> None :
32
33
self .transactions = set ()
33
34
self .event_handlers = []
35
+ self .ephemeral_events = ephemeral_events
34
36
35
37
async def default_query_handler (_ ):
36
38
return None
@@ -64,45 +66,45 @@ def _check_token(self, request: web.Request) -> bool:
64
66
65
67
async def _http_query_user (self , request : web .Request ) -> web .Response :
66
68
if not self ._check_token (request ):
67
- return web .Response ( status = 401 )
69
+ return web .json_response ({ "error" : "Invalid auth token" }, status = 401 )
68
70
69
71
try :
70
72
user_id = request .match_info ["user_id" ]
71
73
except KeyError :
72
- return web .Response ( status = 400 )
74
+ return web .json_response ({ "error" : "Missing user_id parameter" }, status = 400 )
73
75
74
76
try :
75
77
response = await self .query_user (user_id )
76
78
except Exception :
77
79
self .log .exception ("Exception in user query handler" )
78
- return web .Response ( status = 500 )
80
+ return web .json_response ({ "error" : "Internal appservice error" }, status = 500 )
79
81
80
82
if not response :
81
- return web .Response ( status = 404 )
83
+ return web .json_response ({}, status = 404 )
82
84
return web .json_response (response )
83
85
84
86
async def _http_query_alias (self , request : web .Request ) -> web .Response :
85
87
if not self ._check_token (request ):
86
- return web .Response ( status = 401 )
88
+ return web .json_response ({ "error" : "Invalid auth token" }, status = 401 )
87
89
88
90
try :
89
91
alias = request .match_info ["alias" ]
90
92
except KeyError :
91
- return web .Response ( status = 400 )
93
+ return web .json_response ({ "error" : "Missing alias parameter" }, status = 400 )
92
94
93
95
try :
94
96
response = await self .query_alias (alias )
95
97
except Exception :
96
98
self .log .exception ("Exception in alias query handler" )
97
- return web .Response ( status = 500 )
99
+ return web .json_response ({ "error" : "Internal appservice error" }, status = 500 )
98
100
99
101
if not response :
100
- return web .Response ( status = 404 )
102
+ return web .json_response ({}, status = 404 )
101
103
return web .json_response (response )
102
104
103
105
async def _http_handle_transaction (self , request : web .Request ) -> web .Response :
104
106
if not self ._check_token (request ):
105
- return web .Response ( status = 401 )
107
+ return web .json_response ({ "error" : "Invalid auth token" }, status = 401 )
106
108
107
109
transaction_id = request .match_info ["transaction_id" ]
108
110
if transaction_id in self .transactions :
@@ -111,15 +113,26 @@ async def _http_handle_transaction(self, request: web.Request) -> web.Response:
111
113
try :
112
114
json = await request .json ()
113
115
except JSONDecodeError :
114
- return web .Response ( status = 400 )
116
+ return web .json_response ({ "error" : "Body is not JSON" }, status = 400 )
115
117
116
118
try :
117
119
events = json ["events" ]
118
120
except KeyError :
119
- return web .Response (status = 400 )
121
+ return web .json_response ({"error" : "Missing events object in body" }, status = 400 )
122
+
123
+ if self .ephemeral_events :
124
+ try :
125
+ ephemeral = json ["ephemeral" ]
126
+ except KeyError :
127
+ try :
128
+ ephemeral = json ["de.sorunome.msc2409.ephemeral" ]
129
+ except KeyError :
130
+ ephemeral = None
131
+ else :
132
+ ephemeral = None
120
133
121
134
try :
122
- await self .handle_transaction (transaction_id , events )
135
+ await self .handle_transaction (transaction_id , events = events , ephemeral = ephemeral )
123
136
except Exception :
124
137
self .log .exception ("Exception in transaction handler" )
125
138
@@ -137,7 +150,15 @@ def _fix_prev_content(raw_event: JSON) -> None:
137
150
except KeyError :
138
151
pass
139
152
140
- async def handle_transaction (self , txn_id : str , events : List [JSON ]) -> None :
153
+ async def handle_transaction (self , txn_id : str , events : List [JSON ],
154
+ ephemeral : Optional [List [JSON ]] = None ) -> None :
155
+ for raw_edu in ephemeral :
156
+ try :
157
+ edu = EphemeralEvent .deserialize (raw_edu )
158
+ except SerializerError :
159
+ self .log .exception ("Failed to deserialize ephemeral event %s" , raw_edu )
160
+ else :
161
+ self .handle_matrix_event (edu )
141
162
for raw_event in events :
142
163
try :
143
164
self ._fix_prev_content (raw_event )
0 commit comments