1414# limitations under the License.
1515import logging
1616import urllib .parse
17- from typing import TYPE_CHECKING , Any , Dict , Iterable , List , Optional , Union
17+ from typing import TYPE_CHECKING , Dict , Iterable , List , Optional , Tuple , Union
1818
1919from prometheus_client import Counter
2020
2727from synapse .metrics .background_process_metrics import run_as_background_process
2828from synapse .push import Pusher , PusherConfig , PusherConfigException
2929from synapse .storage .databases .main .event_push_actions import HttpPushAction
30+ from synapse .types import JsonDict , JsonMapping
3031
3132from . import push_tools
3233
5657)
5758
5859
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 ]:
6061 """
6162 Converts a list of actions into a `tweaks` dict (which can then be passed to
6263 the push gateway).
@@ -101,6 +102,7 @@ def __init__(self, hs: "HomeServer", pusher_config: PusherConfig):
101102 self ._storage_controllers = self .hs .get_storage_controllers ()
102103 self .app_display_name = pusher_config .app_display_name
103104 self .device_display_name = pusher_config .device_display_name
105+ self .device_id = pusher_config .device_id
104106 self .pushkey_ts = pusher_config .ts
105107 self .data = pusher_config .data
106108 self .backoff_delay = HttpPusher .INITIAL_BACKOFF_SEC
@@ -324,7 +326,7 @@ async def _process_one(self, push_action: HttpPushAction) -> bool:
324326 event = await self .store .get_event (push_action .event_id , allow_none = True )
325327 if event is None :
326328 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 )
328330 if rejected is False :
329331 return False
330332
@@ -342,9 +344,12 @@ async def _process_one(self, push_action: HttpPushAction) -> bool:
342344 await self ._pusherpool .remove_pusher (self .app_id , pk , self .user_id )
343345 return True
344346
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 : JsonMapping ,
351+ badge : int ,
352+ ) -> Tuple [JsonDict , JsonMapping ]:
348353 priority = "low"
349354 if (
350355 event .type == EventTypes .Encrypted
@@ -358,80 +363,70 @@ async def _build_notification_dict(
358363 # This was checked in the __init__, but mypy doesn't seem to know that.
359364 assert self .data is not None
360365 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 ,
376371 }
377- return d
372+ return content , {}
378373
379374 ctx = await push_tools .get_context_for_event (
380375 self ._storage_controllers , event , self .user_id
381376 )
382377
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+ },
405389 }
406390 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
409393 if self .hs .config .push .push_include_content and event .content :
410- d [ "notification" ] ["content" ] = event .content
394+ content ["content" ] = event .content
411395
412396 # We no longer send aliases separately, instead, we send the human
413397 # readable name of the room, which may be an alias.
414398 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" ]
416400 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 : Optional [JsonMapping ]
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
418416
419- return d
417+ content ["devices" ] = [device ]
418+
419+ return {"notification" : content }
420420
421421 async def dispatch_push (
422- self , event : EventBase , tweaks : Dict [ str , bool ], badge : int
422+ self , content : JsonDict , tweaks : Optional [ JsonMapping ] = None
423423 ) -> 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 )
427425 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 )
431427 except Exception as e :
432428 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" ,
435430 self .name ,
436431 type (e ),
437432 e ,
@@ -440,10 +435,27 @@ async def dispatch_push(
440435 rejected = []
441436 if "rejected" in resp :
442437 rejected = resp ["rejected" ]
443- if not rejected :
444- self .badge_count_last_call = badge
445438 return rejected
446439
440+ async def dispatch_push_event (
441+ self ,
442+ event : EventBase ,
443+ tweaks : JsonMapping ,
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+
447459 async def _send_badge (self , badge : int ) -> None :
448460 """
449461 Args:
0 commit comments