14
14
# limitations under the License.
15
15
import logging
16
16
import urllib .parse
17
- from typing import TYPE_CHECKING , Any , Dict , Iterable , List , Optional , Union
17
+ from typing import TYPE_CHECKING , Dict , Iterable , List , Mapping , Optional , Tuple , Union
18
18
19
19
from prometheus_client import Counter
20
20
27
27
from synapse .metrics .background_process_metrics import run_as_background_process
28
28
from synapse .push import Pusher , PusherConfig , PusherConfigException
29
29
from synapse .storage .databases .main .event_push_actions import HttpPushAction
30
+ from synapse .types import JsonDict
30
31
31
32
from . import push_tools
32
33
56
57
)
57
58
58
59
59
- def tweaks_for_actions (actions : List [Union [str , Dict ]]) -> Dict [str , Any ]:
60
+ def tweaks_for_actions (actions : List [Union [str , Dict ]]) -> Dict [str , str ]:
60
61
"""
61
62
Converts a list of actions into a `tweaks` dict (which can then be passed to
62
63
the push gateway).
@@ -101,6 +102,7 @@ def __init__(self, hs: "HomeServer", pusher_config: PusherConfig):
101
102
self ._storage_controllers = self .hs .get_storage_controllers ()
102
103
self .app_display_name = pusher_config .app_display_name
103
104
self .device_display_name = pusher_config .device_display_name
105
+ self .device_id = pusher_config .device_id
104
106
self .pushkey_ts = pusher_config .ts
105
107
self .data = pusher_config .data
106
108
self .backoff_delay = HttpPusher .INITIAL_BACKOFF_SEC
@@ -324,7 +326,7 @@ async def _process_one(self, push_action: HttpPushAction) -> bool:
324
326
event = await self .store .get_event (push_action .event_id , allow_none = True )
325
327
if event is None :
326
328
return True # It's been redacted
327
- rejected = await self .dispatch_push (event , tweaks , badge )
329
+ rejected = await self .dispatch_push_event (event , tweaks , badge )
328
330
if rejected is False :
329
331
return False
330
332
@@ -342,9 +344,12 @@ async def _process_one(self, push_action: HttpPushAction) -> bool:
342
344
await self ._pusherpool .remove_pusher (self .app_id , pk , self .user_id )
343
345
return True
344
346
345
- async def _build_notification_dict (
346
- self , event : EventBase , tweaks : Dict [str , bool ], badge : int
347
- ) -> Dict [str , Any ]:
347
+ async def _build_event_notification (
348
+ self ,
349
+ event : EventBase ,
350
+ tweaks : Mapping [str , str ],
351
+ badge : int ,
352
+ ) -> Tuple [JsonDict , Mapping [str , str ]]:
348
353
priority = "low"
349
354
if (
350
355
event .type == EventTypes .Encrypted
@@ -358,80 +363,70 @@ async def _build_notification_dict(
358
363
# This was checked in the __init__, but mypy doesn't seem to know that.
359
364
assert self .data is not None
360
365
if self .data .get ("format" ) == "event_id_only" :
361
- d : Dict [str , Any ] = {
362
- "notification" : {
363
- "event_id" : event .event_id ,
364
- "room_id" : event .room_id ,
365
- "counts" : {"unread" : badge },
366
- "prio" : priority ,
367
- "devices" : [
368
- {
369
- "app_id" : self .app_id ,
370
- "pushkey" : self .pushkey ,
371
- "pushkey_ts" : int (self .pushkey_ts / 1000 ),
372
- "data" : self .data_minus_url ,
373
- }
374
- ],
375
- }
366
+ content : JsonDict = {
367
+ "event_id" : event .event_id ,
368
+ "room_id" : event .room_id ,
369
+ "counts" : {"unread" : badge },
370
+ "prio" : priority ,
376
371
}
377
- return d
372
+ return content , {}
378
373
379
374
ctx = await push_tools .get_context_for_event (
380
375
self ._storage_controllers , event , self .user_id
381
376
)
382
377
383
- d = {
384
- "notification" : {
385
- "id" : event .event_id , # deprecated: remove soon
386
- "event_id" : event .event_id ,
387
- "room_id" : event .room_id ,
388
- "type" : event .type ,
389
- "sender" : event .user_id ,
390
- "prio" : priority ,
391
- "counts" : {
392
- "unread" : badge ,
393
- # 'missed_calls': 2
394
- },
395
- "devices" : [
396
- {
397
- "app_id" : self .app_id ,
398
- "pushkey" : self .pushkey ,
399
- "pushkey_ts" : int (self .pushkey_ts / 1000 ),
400
- "data" : self .data_minus_url ,
401
- "tweaks" : tweaks ,
402
- }
403
- ],
404
- }
378
+ content = {
379
+ "id" : event .event_id , # deprecated: remove soon
380
+ "event_id" : event .event_id ,
381
+ "room_id" : event .room_id ,
382
+ "type" : event .type ,
383
+ "sender" : event .user_id ,
384
+ "prio" : priority ,
385
+ "counts" : {
386
+ "unread" : badge ,
387
+ # 'missed_calls': 2
388
+ },
405
389
}
406
390
if event .type == "m.room.member" and event .is_state ():
407
- d [ "notification" ] ["membership" ] = event .content ["membership" ]
408
- d [ "notification" ] ["user_is_target" ] = event .state_key == self .user_id
391
+ content ["membership" ] = event .content ["membership" ]
392
+ content ["user_is_target" ] = event .state_key == self .user_id
409
393
if self .hs .config .push .push_include_content and event .content :
410
- d [ "notification" ] ["content" ] = event .content
394
+ content ["content" ] = event .content
411
395
412
396
# We no longer send aliases separately, instead, we send the human
413
397
# readable name of the room, which may be an alias.
414
398
if "sender_display_name" in ctx and len (ctx ["sender_display_name" ]) > 0 :
415
- d [ "notification" ] ["sender_display_name" ] = ctx ["sender_display_name" ]
399
+ content ["sender_display_name" ] = ctx ["sender_display_name" ]
416
400
if "name" in ctx and len (ctx ["name" ]) > 0 :
417
- d ["notification" ]["room_name" ] = ctx ["name" ]
401
+ content ["room_name" ] = ctx ["name" ]
402
+
403
+ return (content , tweaks )
404
+
405
+ def _build_notification_dict (
406
+ self , content : JsonDict , tweaks : Mapping [str , str ]
407
+ ) -> JsonDict :
408
+ device = {
409
+ "app_id" : self .app_id ,
410
+ "pushkey" : self .pushkey ,
411
+ "pushkey_ts" : int (self .pushkey_ts / 1000 ),
412
+ "data" : self .data_minus_url ,
413
+ }
414
+ if tweaks :
415
+ device ["tweaks" ] = tweaks
418
416
419
- return d
417
+ content ["devices" ] = [device ]
418
+
419
+ return {"notification" : content }
420
420
421
421
async def dispatch_push (
422
- self , event : EventBase , tweaks : Dict [str , bool ], badge : int
422
+ self , content : JsonDict , tweaks : Mapping [str , str ] = {}
423
423
) -> Union [bool , Iterable [str ]]:
424
- notification_dict = await self ._build_notification_dict (event , tweaks , badge )
425
- if not notification_dict :
426
- return []
424
+ notif_dict = self ._build_notification_dict (content , tweaks )
427
425
try :
428
- resp = await self .http_client .post_json_get_json (
429
- self .url , notification_dict
430
- )
426
+ resp = await self .http_client .post_json_get_json (self .url , notif_dict )
431
427
except Exception as e :
432
428
logger .warning (
433
- "Failed to push event %s to %s: %s %s" ,
434
- event .event_id ,
429
+ "Failed to push data to %s: %s %s" ,
435
430
self .name ,
436
431
type (e ),
437
432
e ,
@@ -440,10 +435,27 @@ async def dispatch_push(
440
435
rejected = []
441
436
if "rejected" in resp :
442
437
rejected = resp ["rejected" ]
443
- if not rejected :
444
- self .badge_count_last_call = badge
445
438
return rejected
446
439
440
+ async def dispatch_push_event (
441
+ self ,
442
+ event : EventBase ,
443
+ tweaks : Mapping [str , str ],
444
+ badge : int ,
445
+ ) -> Union [bool , Iterable [str ]]:
446
+ content , tweaks = await self ._build_event_notification (event , tweaks , badge )
447
+ if not content :
448
+ return []
449
+
450
+ res = await self .dispatch_push (content , tweaks )
451
+
452
+ if res is False :
453
+ return False
454
+ if not res :
455
+ self .badge_count_last_call = badge
456
+
457
+ return res
458
+
447
459
async def _send_badge (self , badge : int ) -> None :
448
460
"""
449
461
Args:
0 commit comments