def make_summary_text(self, notifs_by_room, room_state_ids, notif_events, user_id, reason): if len(notifs_by_room) == 1: # Only one room has new stuff room_id = notifs_by_room.keys()[0] # If the room has some kind of name, use it, but we don't # want the generated-from-names one here otherwise we'll # end up with, "new message from Bob in the Bob room" room_name = yield calculate_room_name(self.store, room_state_ids[room_id], user_id, fallback_to_members=False) my_member_event_id = room_state_ids[room_id][("m.room.member", user_id)] my_member_event = yield self.store.get_event(my_member_event_id) if my_member_event.content["membership"] == "invite": inviter_member_event_id = room_state_ids[room_id][( "m.room.member", my_member_event.sender)] inviter_member_event = yield self.store.get_event( inviter_member_event_id) inviter_name = name_from_member_event(inviter_member_event) if room_name is None: defer.returnValue(INVITE_FROM_PERSON % { "person": inviter_name, "app": self.app_name }) else: defer.returnValue( INVITE_FROM_PERSON_TO_ROOM % { "person": inviter_name, "room": room_name, "app": self.app_name, }) sender_name = None if len(notifs_by_room[room_id]) == 1: # There is just the one notification, so give some detail event = notif_events[notifs_by_room[room_id][0]["event_id"]] if ("m.room.member", event.sender) in room_state_ids[room_id]: state_event_id = room_state_ids[room_id][("m.room.member", event.sender)] state_event = yield self.store.get_event(state_event_id) sender_name = name_from_member_event(state_event) if sender_name is not None and room_name is not None: defer.returnValue( MESSAGE_FROM_PERSON_IN_ROOM % { "person": sender_name, "room": room_name, "app": self.app_name, }) elif sender_name is not None: defer.returnValue(MESSAGE_FROM_PERSON % { "person": sender_name, "app": self.app_name, }) else: # There's more than one notification for this room, so just # say there are several if room_name is not None: defer.returnValue(MESSAGES_IN_ROOM % { "room": room_name, "app": self.app_name, }) else: # If the room doesn't have a name, say who the messages # are from explicitly to avoid, "messages in the Bob room" sender_ids = list( set([ notif_events[n['event_id']].sender for n in notifs_by_room[room_id] ])) member_events = yield self.store.get_events([ room_state_ids[room_id][("m.room.member", s)] for s in sender_ids ]) defer.returnValue( MESSAGES_FROM_PERSON % { "person": descriptor_from_member_events( member_events.values()), "app": self.app_name, }) else: # Stuff's happened in multiple different rooms # ...but we still refer to the 'reason' room which triggered the mail if reason['room_name'] is not None: defer.returnValue(MESSAGES_IN_ROOM_AND_OTHERS % { "room": reason['room_name'], "app": self.app_name, }) else: # If the reason room doesn't have a name, say who the messages # are from explicitly to avoid, "messages in the Bob room" sender_ids = list( set([ notif_events[n['event_id']].sender for n in notifs_by_room[reason['room_id']] ])) member_events = yield self.store.get_events([ room_state_ids[room_id][("m.room.member", s)] for s in sender_ids ]) defer.returnValue( MESSAGES_FROM_PERSON_AND_OTHERS % { "person": descriptor_from_member_events(member_events.values()), "app": self.app_name, })
async def make_summary_text( self, notifs_by_room, room_state_ids, notif_events, user_id, reason ): if len(notifs_by_room) == 1: # Only one room has new stuff room_id = list(notifs_by_room.keys())[0] # If the room has some kind of name, use it, but we don't # want the generated-from-names one here otherwise we'll # end up with, "new message from Bob in the Bob room" room_name = await calculate_room_name( self.store, room_state_ids[room_id], user_id, fallback_to_members=False ) my_member_event_id = room_state_ids[room_id][("m.room.member", user_id)] my_member_event = await self.store.get_event(my_member_event_id) if my_member_event.content["membership"] == "invite": inviter_member_event_id = room_state_ids[room_id][ ("m.room.member", my_member_event.sender) ] inviter_member_event = await self.store.get_event( inviter_member_event_id ) inviter_name = name_from_member_event(inviter_member_event) if room_name is None: return self.email_subjects.invite_from_person % { "person": inviter_name, "app": self.app_name, } else: return self.email_subjects.invite_from_person_to_room % { "person": inviter_name, "room": room_name, "app": self.app_name, } sender_name = None if len(notifs_by_room[room_id]) == 1: # There is just the one notification, so give some detail event = notif_events[notifs_by_room[room_id][0]["event_id"]] if ("m.room.member", event.sender) in room_state_ids[room_id]: state_event_id = room_state_ids[room_id][ ("m.room.member", event.sender) ] state_event = await self.store.get_event(state_event_id) sender_name = name_from_member_event(state_event) if sender_name is not None and room_name is not None: return self.email_subjects.message_from_person_in_room % { "person": sender_name, "room": room_name, "app": self.app_name, } elif sender_name is not None: return self.email_subjects.message_from_person % { "person": sender_name, "app": self.app_name, } else: # There's more than one notification for this room, so just # say there are several if room_name is not None: return self.email_subjects.messages_in_room % { "room": room_name, "app": self.app_name, } else: # If the room doesn't have a name, say who the messages # are from explicitly to avoid, "messages in the Bob room" sender_ids = list( { notif_events[n["event_id"]].sender for n in notifs_by_room[room_id] } ) member_events = await self.store.get_events( [ room_state_ids[room_id][("m.room.member", s)] for s in sender_ids ] ) return self.email_subjects.messages_from_person % { "person": descriptor_from_member_events(member_events.values()), "app": self.app_name, } else: # Stuff's happened in multiple different rooms # ...but we still refer to the 'reason' room which triggered the mail if reason["room_name"] is not None: return self.email_subjects.messages_in_room_and_others % { "room": reason["room_name"], "app": self.app_name, } else: # If the reason room doesn't have a name, say who the messages # are from explicitly to avoid, "messages in the Bob room" room_id = reason["room_id"] sender_ids = list( { notif_events[n["event_id"]].sender for n in notifs_by_room[room_id] } ) member_events = await self.store.get_events( [room_state_ids[room_id][("m.room.member", s)] for s in sender_ids] ) return self.email_subjects.messages_from_person_and_others % { "person": descriptor_from_member_events(member_events.values()), "app": self.app_name, }
async def make_summary_text( self, notifs_by_room: Dict[str, List[Dict[str, Any]]], room_state_ids: Dict[str, StateMap[str]], notif_events: Dict[str, EventBase], user_id: str, reason: Dict[str, Any], ): if len(notifs_by_room) == 1: # Only one room has new stuff room_id = list(notifs_by_room.keys())[0] # If the room has some kind of name, use it, but we don't # want the generated-from-names one here otherwise we'll # end up with, "new message from Bob in the Bob room" room_name = await calculate_room_name(self.store, room_state_ids[room_id], user_id, fallback_to_members=False) # See if one of the notifs is an invite event for the user invite_event = None for n in notifs_by_room[room_id]: ev = notif_events[n["event_id"]] if ev.type == EventTypes.Member and ev.state_key == user_id: if ev.content.get("membership") == Membership.INVITE: invite_event = ev break if invite_event: inviter_member_event_id = room_state_ids[room_id].get( ("m.room.member", invite_event.sender)) inviter_name = invite_event.sender if inviter_member_event_id: inviter_member_event = await self.store.get_event( inviter_member_event_id, allow_none=True) if inviter_member_event: inviter_name = name_from_member_event( inviter_member_event) if room_name is None: return self.email_subjects.invite_from_person % { "person": inviter_name, "app": self.app_name, } else: return self.email_subjects.invite_from_person_to_room % { "person": inviter_name, "room": room_name, "app": self.app_name, } sender_name = None if len(notifs_by_room[room_id]) == 1: # There is just the one notification, so give some detail event = notif_events[notifs_by_room[room_id][0]["event_id"]] if ("m.room.member", event.sender) in room_state_ids[room_id]: state_event_id = room_state_ids[room_id][("m.room.member", event.sender)] state_event = await self.store.get_event(state_event_id) sender_name = name_from_member_event(state_event) if sender_name is not None and room_name is not None: return self.email_subjects.message_from_person_in_room % { "person": sender_name, "room": room_name, "app": self.app_name, } elif sender_name is not None: return self.email_subjects.message_from_person % { "person": sender_name, "app": self.app_name, } else: # There's more than one notification for this room, so just # say there are several if room_name is not None: return self.email_subjects.messages_in_room % { "room": room_name, "app": self.app_name, } else: # If the room doesn't have a name, say who the messages # are from explicitly to avoid, "messages in the Bob room" sender_ids = list({ notif_events[n["event_id"]].sender for n in notifs_by_room[room_id] }) member_events = await self.store.get_events([ room_state_ids[room_id][("m.room.member", s)] for s in sender_ids ]) return self.email_subjects.messages_from_person % { "person": descriptor_from_member_events(member_events.values()), "app": self.app_name, } else: # Stuff's happened in multiple different rooms # ...but we still refer to the 'reason' room which triggered the mail if reason["room_name"] is not None: return self.email_subjects.messages_in_room_and_others % { "room": reason["room_name"], "app": self.app_name, } else: # If the reason room doesn't have a name, say who the messages # are from explicitly to avoid, "messages in the Bob room" room_id = reason["room_id"] sender_ids = list({ notif_events[n["event_id"]].sender for n in notifs_by_room[room_id] }) member_events = await self.store.get_events([ room_state_ids[room_id][("m.room.member", s)] for s in sender_ids ]) return self.email_subjects.messages_from_person_and_others % { "person": descriptor_from_member_events( member_events.values()), "app": self.app_name, }
async def _make_summary_text_from_member_events( self, room_id: str, notifs: List[EmailPushAction], room_state_ids: StateMap[str], notif_events: Dict[str, EventBase], ) -> str: """ Make a summary text for the email when only a single room has notifications. Args: room_id: The ID of the room. notifs: The push actions for this room. room_state_ids: The state map for the room. notif_events: A map of event ID -> notification event. Returns: The summary text. """ # If the room doesn't have a name, say who the messages # are from explicitly to avoid, "messages in the Bob room" # Find the latest event ID for each sender, note that the notifications # are already in descending received_ts. sender_ids = {} for n in notifs: sender = notif_events[n.event_id].sender if sender not in sender_ids: sender_ids[sender] = n.event_id # Get the actual member events (in order to calculate a pretty name for # the room). member_event_ids = [] member_events = {} for sender_id, event_id in sender_ids.items(): type_state_key = ("m.room.member", sender_id) sender_state_event_id = room_state_ids.get(type_state_key) if sender_state_event_id: member_event_ids.append(sender_state_event_id) else: # Attempt to check the historical state for the room. historical_state = ( await self._state_storage_controller.get_state_for_event( event_id, StateFilter.from_types((type_state_key, )))) sender_state_event = historical_state.get(type_state_key) if sender_state_event: member_events[event_id] = sender_state_event member_events.update(await self.store.get_events(member_event_ids)) if not member_events: # No member events were found! Maybe the room is empty? # Fallback to the room ID (note that if there was a room name this # would already have been used previously). return self.email_subjects.messages_in_room % { "room": room_id, "app": self.app_name, } # There was a single sender. if len(member_events) == 1: return self.email_subjects.messages_from_person % { "person": descriptor_from_member_events( member_events.values()), "app": self.app_name, } # There was more than one sender, use the first one and a tweaked template. return self.email_subjects.messages_from_person_and_others % { "person": descriptor_from_member_events(list(member_events.values())[:1]), "app": self.app_name, }
def make_summary_text(self, notifs_by_room, state_by_room, notif_events, user_id, reason): if len(notifs_by_room) == 1: # Only one room has new stuff room_id = notifs_by_room.keys()[0] # If the room has some kind of name, use it, but we don't # want the generated-from-names one here otherwise we'll # end up with, "new message from Bob in the Bob room" room_name = yield calculate_room_name( self.store, state_by_room[room_id], user_id, fallback_to_members=False ) my_member_event = state_by_room[room_id][("m.room.member", user_id)] if my_member_event.content["membership"] == "invite": inviter_member_event = state_by_room[room_id][ ("m.room.member", my_member_event.sender) ] inviter_name = name_from_member_event(inviter_member_event) if room_name is None: defer.returnValue(INVITE_FROM_PERSON % { "person": inviter_name, "app": self.app_name }) else: defer.returnValue(INVITE_FROM_PERSON_TO_ROOM % { "person": inviter_name, "room": room_name, "app": self.app_name, }) sender_name = None if len(notifs_by_room[room_id]) == 1: # There is just the one notification, so give some detail event = notif_events[notifs_by_room[room_id][0]["event_id"]] if ("m.room.member", event.sender) in state_by_room[room_id]: state_event = state_by_room[room_id][("m.room.member", event.sender)] sender_name = name_from_member_event(state_event) if sender_name is not None and room_name is not None: defer.returnValue(MESSAGE_FROM_PERSON_IN_ROOM % { "person": sender_name, "room": room_name, "app": self.app_name, }) elif sender_name is not None: defer.returnValue(MESSAGE_FROM_PERSON % { "person": sender_name, "app": self.app_name, }) else: # There's more than one notification for this room, so just # say there are several if room_name is not None: defer.returnValue(MESSAGES_IN_ROOM % { "room": room_name, "app": self.app_name, }) else: # If the room doesn't have a name, say who the messages # are from explicitly to avoid, "messages in the Bob room" sender_ids = list(set([ notif_events[n['event_id']].sender for n in notifs_by_room[room_id] ])) defer.returnValue(MESSAGES_FROM_PERSON % { "person": descriptor_from_member_events([ state_by_room[room_id][("m.room.member", s)] for s in sender_ids ]), "app": self.app_name, }) else: # Stuff's happened in multiple different rooms # ...but we still refer to the 'reason' room which triggered the mail if reason['room_name'] is not None: defer.returnValue(MESSAGES_IN_ROOM_AND_OTHERS % { "room": reason['room_name'], "app": self.app_name, }) else: # If the reason room doesn't have a name, say who the messages # are from explicitly to avoid, "messages in the Bob room" sender_ids = list(set([ notif_events[n['event_id']].sender for n in notifs_by_room[reason['room_id']] ])) defer.returnValue(MESSAGES_FROM_PERSON_AND_OTHERS % { "person": descriptor_from_member_events([ state_by_room[reason['room_id']][("m.room.member", s)] for s in sender_ids ]), "app": self.app_name, })