improvement: better default push rules
This commit is contained in:
		
							parent
							
								
									e7803e310a
								
							
						
					
					
						commit
						02fe030b2a
					
				
					 5 changed files with 359 additions and 80 deletions
				
			
		|  | @ -204,33 +204,7 @@ pub fn register_route( | |||
|         &EventType::PushRules, | ||||
|         serde_json::to_value(ruma::events::push_rules::PushRulesEvent { | ||||
|             content: ruma::events::push_rules::PushRulesEventContent { | ||||
|                 global: ruma::events::push_rules::Ruleset { | ||||
|                     content: vec![], | ||||
|                     override_: vec![ruma::events::push_rules::ConditionalPushRule { | ||||
|                         actions: vec![ruma::events::push_rules::Action::DontNotify], | ||||
|                         default: true, | ||||
|                         enabled: false, | ||||
|                         rule_id: ".m.rule.master".to_owned(), | ||||
|                         conditions: vec![], | ||||
|                     }], | ||||
|                     room: vec![], | ||||
|                     sender: vec![], | ||||
|                     underride: vec![ruma::events::push_rules::ConditionalPushRule { | ||||
|                         actions: vec![ | ||||
|                             ruma::events::push_rules::Action::Notify, | ||||
|                             ruma::events::push_rules::Action::SetTweak(ruma::push::Tweak::Sound( | ||||
|                                 "default".to_owned(), | ||||
|                             )), | ||||
|                         ], | ||||
|                         default: true, | ||||
|                         enabled: true, | ||||
|                         rule_id: ".m.rule.message".to_owned(), | ||||
|                         conditions: vec![ruma::events::push_rules::PushCondition::EventMatch { | ||||
|                             key: "type".to_owned(), | ||||
|                             pattern: "m.room.message".to_owned(), | ||||
|                         }], | ||||
|                     }], | ||||
|                 }, | ||||
|                 global: crate::push_rules::default_pushrules(&user_id), | ||||
|             }, | ||||
|         }) | ||||
|         .expect("data is valid, we just created it") | ||||
|  | @ -502,8 +476,7 @@ pub fn set_displayname_route( | |||
|                 displayname: body.displayname.clone(), | ||||
|                 ..serde_json::from_value::<EventJson<_>>( | ||||
|                     db.rooms | ||||
|                         .room_state(&room_id)? | ||||
|                         .get(&(EventType::RoomMember, user_id.to_string())) | ||||
|                         .room_state_get(&room_id, &EventType::RoomMember, &user_id.to_string())? | ||||
|                         .ok_or_else(|| { | ||||
|                             Error::bad_database( | ||||
|                                 "Tried to send displayname update for user not in the room.", | ||||
|  | @ -593,8 +566,7 @@ pub fn set_avatar_url_route( | |||
|                 avatar_url: body.avatar_url.clone(), | ||||
|                 ..serde_json::from_value::<EventJson<_>>( | ||||
|                     db.rooms | ||||
|                         .room_state(&room_id)? | ||||
|                         .get(&(EventType::RoomMember, user_id.to_string())) | ||||
|                         .room_state_get(&room_id, &EventType::RoomMember, &user_id.to_string())? | ||||
|                         .ok_or_else(|| { | ||||
|                             Error::bad_database( | ||||
|                                 "Tried to send avatar url update for user not in the room.", | ||||
|  | @ -1267,8 +1239,7 @@ pub fn join_room_by_id_route( | |||
| 
 | ||||
|     let event = db | ||||
|         .rooms | ||||
|         .room_state(&body.room_id)? | ||||
|         .get(&(EventType::RoomMember, user_id.to_string())) | ||||
|         .room_state_get(&body.room_id, &EventType::RoomMember, &user_id.to_string())? | ||||
|         .map_or_else( | ||||
|             || { | ||||
|                 // There was no existing membership event
 | ||||
|  | @ -1348,11 +1319,10 @@ pub fn leave_room_route( | |||
|     _room_id: String, | ||||
| ) -> ConduitResult<leave_room::Response> { | ||||
|     let user_id = body.user_id.as_ref().expect("user is authenticated"); | ||||
|     let state = db.rooms.room_state(&body.room_id)?; | ||||
| 
 | ||||
|     let mut event = serde_json::from_value::<EventJson<member::MemberEventContent>>( | ||||
|         state | ||||
|             .get(&(EventType::RoomMember, user_id.to_string())) | ||||
|         db.rooms | ||||
|             .room_state_get(&body.room_id, &EventType::RoomMember, &user_id.to_string())? | ||||
|             .ok_or(Error::BadRequest( | ||||
|                 ErrorKind::BadState, | ||||
|                 "Cannot leave a room you are not a member of.", | ||||
|  | @ -1387,12 +1357,11 @@ pub fn kick_user_route( | |||
|     _room_id: String, | ||||
| ) -> ConduitResult<kick_user::Response> { | ||||
|     let user_id = body.user_id.as_ref().expect("user is authenticated"); | ||||
|     let state = db.rooms.room_state(&body.room_id)?; | ||||
| 
 | ||||
|     let mut event = | ||||
|         serde_json::from_value::<EventJson<ruma::events::room::member::MemberEventContent>>( | ||||
|             state | ||||
|                 .get(&(EventType::RoomMember, user_id.to_string())) | ||||
|             db.rooms | ||||
|                 .room_state_get(&body.room_id, &EventType::RoomMember, &user_id.to_string())? | ||||
|                 .ok_or(Error::BadRequest( | ||||
|                     ErrorKind::BadState, | ||||
|                     "Cannot kick member that's not in the room.", | ||||
|  | @ -1428,12 +1397,12 @@ pub fn ban_user_route( | |||
|     _room_id: String, | ||||
| ) -> ConduitResult<ban_user::Response> { | ||||
|     let user_id = body.user_id.as_ref().expect("user is authenticated"); | ||||
|     let state = db.rooms.room_state(&body.room_id)?; | ||||
| 
 | ||||
|     // TODO: reason
 | ||||
| 
 | ||||
|     let event = state | ||||
|         .get(&(EventType::RoomMember, user_id.to_string())) | ||||
|     let event = db | ||||
|         .rooms | ||||
|         .room_state_get(&body.room_id, &EventType::RoomMember, &user_id.to_string())? | ||||
|         .map_or( | ||||
|             Ok::<_, Error>(member::MemberEventContent { | ||||
|                 membership: member::MembershipState::Ban, | ||||
|  | @ -1475,12 +1444,11 @@ pub fn unban_user_route( | |||
|     _room_id: String, | ||||
| ) -> ConduitResult<unban_user::Response> { | ||||
|     let user_id = body.user_id.as_ref().expect("user is authenticated"); | ||||
|     let state = db.rooms.room_state(&body.room_id)?; | ||||
| 
 | ||||
|     let mut event = | ||||
|         serde_json::from_value::<EventJson<ruma::events::room::member::MemberEventContent>>( | ||||
|             state | ||||
|                 .get(&(EventType::RoomMember, user_id.to_string())) | ||||
|             db.rooms | ||||
|                 .room_state_get(&body.room_id, &EventType::RoomMember, &user_id.to_string())? | ||||
|                 .ok_or(Error::BadRequest( | ||||
|                     ErrorKind::BadState, | ||||
|                     "Cannot unban a user who is not banned.", | ||||
|  | @ -1642,7 +1610,8 @@ pub async fn get_public_rooms_filtered_route( | |||
|         .map(|room_id| { | ||||
|             let room_id = room_id?; | ||||
| 
 | ||||
|             let state = db.rooms.room_state(&room_id)?; | ||||
|             // TODO: Do not load full state?
 | ||||
|             let state = db.rooms.room_state_full(&room_id)?; | ||||
| 
 | ||||
|             let chunk = directory::PublicRoomsChunk { | ||||
|                 aliases: Vec::new(), | ||||
|  | @ -1775,9 +1744,29 @@ pub fn search_users_route( | |||
| } | ||||
| 
 | ||||
| #[get("/_matrix/client/r0/rooms/<_room_id>/members")] | ||||
| pub fn get_member_events_route(_room_id: String) -> ConduitResult<get_member_events::Response> { | ||||
|     warn!("TODO: get_member_events_route"); | ||||
|     Ok(get_member_events::Response { chunk: Vec::new() }.into()) | ||||
| pub fn get_member_events_route( | ||||
|     db: State<'_, Database>, | ||||
|     //body: Ruma<create_message_event::Request>,
 | ||||
|     _room_id: String, | ||||
| ) -> ConduitResult<get_member_events::Response> { | ||||
|     //let user_id = body.user_id.as_ref().expect("user is authenticated");
 | ||||
| 
 | ||||
|     //if !db.rooms.is_joined(user_id, &body.room_id)? {
 | ||||
|     //    return Err(Error::BadRequest(
 | ||||
|     //        ErrorKind::Forbidden,
 | ||||
|     //        "You don't have permission to view this room.",
 | ||||
|     //    ));
 | ||||
|     //}
 | ||||
| 
 | ||||
|     Ok(get_member_events::Response { | ||||
|         chunk: Vec::new(),/*db
 | ||||
|             .rooms | ||||
|             .room_state_type(&body.room_id, &EventType::RoomMember)? | ||||
|             .values() | ||||
|             .map(|pdu| pdu.to_member_event()) | ||||
|             .collect(),*/ | ||||
|     } | ||||
|     .into()) | ||||
| } | ||||
| 
 | ||||
| #[get("/_matrix/client/r0/thirdparty/protocols")] | ||||
|  | @ -1951,7 +1940,7 @@ pub fn get_state_events_route( | |||
|     Ok(get_state_events::Response { | ||||
|         room_state: db | ||||
|             .rooms | ||||
|             .room_state(&body.room_id)? | ||||
|             .room_state_full(&body.room_id)? | ||||
|             .values() | ||||
|             .map(|pdu| pdu.to_state_event()) | ||||
|             .collect(), | ||||
|  | @ -1979,10 +1968,9 @@ pub fn get_state_events_for_key_route( | |||
|         )); | ||||
|     } | ||||
| 
 | ||||
|     let state = db.rooms.room_state(&body.room_id)?; | ||||
| 
 | ||||
|     let event = state | ||||
|         .get(&(body.event_type.clone(), body.state_key.clone())) | ||||
|     let event = db | ||||
|         .rooms | ||||
|         .room_state_get(&body.room_id, &body.event_type, &body.state_key)? | ||||
|         .ok_or(Error::BadRequest( | ||||
|             ErrorKind::NotFound, | ||||
|             "State event not found.", | ||||
|  | @ -2014,17 +2002,16 @@ pub fn get_state_events_for_empty_key_route( | |||
|         )); | ||||
|     } | ||||
| 
 | ||||
|     let state = db.rooms.room_state(&body.room_id)?; | ||||
| 
 | ||||
|     let event = state | ||||
|         .get(&(body.event_type.clone(), "".to_owned())) | ||||
|     let event = db | ||||
|         .rooms | ||||
|         .room_state_get(&body.room_id, &body.event_type, "")? | ||||
|         .ok_or(Error::BadRequest( | ||||
|             ErrorKind::NotFound, | ||||
|             "State event not found.", | ||||
|         ))?; | ||||
| 
 | ||||
|     Ok(get_state_events_for_empty_key::Response { | ||||
|         content: serde_json::value::to_raw_value(event) | ||||
|         content: serde_json::value::to_raw_value(&event) | ||||
|             .map_err(|_| Error::bad_database("Invalid event content in database"))?, | ||||
|     } | ||||
|     .into()) | ||||
|  | @ -2068,7 +2055,7 @@ pub fn sync_route( | |||
|                     let content = serde_json::from_value::< | ||||
|                         EventJson<ruma::events::room::member::MemberEventContent>, | ||||
|                     >(pdu.content.clone()) | ||||
|                     .map_err(|_| Error::bad_database("Invalid PDU in database."))? | ||||
|                     .expect("EventJson::from_value always works") | ||||
|                     .deserialize() | ||||
|                     .map_err(|_| Error::bad_database("Invalid PDU in database."))?; | ||||
|                     if content.membership == ruma::events::room::member::MembershipState::Join { | ||||
|  | @ -2081,7 +2068,7 @@ pub fn sync_route( | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         let state = db.rooms.room_state(&room_id)?; | ||||
|         let members = db.rooms.room_state_type(&room_id, &EventType::RoomMember)?; | ||||
| 
 | ||||
|         let (joined_member_count, invited_member_count, heroes) = if send_member_count { | ||||
|             let joined_member_count = db.rooms.room_members(&room_id).count(); | ||||
|  | @ -2111,8 +2098,8 @@ pub fn sync_route( | |||
|                             let current_content = serde_json::from_value::< | ||||
|                                 EventJson<ruma::events::room::member::MemberEventContent>, | ||||
|                             >( | ||||
|                                 state | ||||
|                                     .get(&(EventType::RoomMember, state_key.clone())) | ||||
|                                 members | ||||
|                                     .get(state_key) | ||||
|                                     .ok_or_else(|| { | ||||
|                                         Error::bad_database( | ||||
|                                             "A user that joined once has no member event anymore.", | ||||
|  | @ -2264,7 +2251,8 @@ pub fn sync_route( | |||
|             // TODO: state before timeline
 | ||||
|             state: sync_events::State { | ||||
|                 events: if joined_since_last_sync { | ||||
|                     state | ||||
|                     db.rooms | ||||
|                         .room_state_full(&room_id)? | ||||
|                         .into_iter() | ||||
|                         .map(|(_, pdu)| pdu.to_state_event()) | ||||
|                         .collect() | ||||
|  | @ -2337,7 +2325,7 @@ pub fn sync_route( | |||
|             invite_state: sync_events::InviteState { | ||||
|                 events: db | ||||
|                     .rooms | ||||
|                     .room_state(&room_id)? | ||||
|                     .room_state_full(&room_id)? | ||||
|                     .into_iter() | ||||
|                     .map(|(_, pdu)| pdu.to_stripped_state_event()) | ||||
|                     .collect(), | ||||
|  | @ -2496,7 +2484,7 @@ pub fn get_context_route( | |||
|         events_after, | ||||
|         state: db // TODO: State at event
 | ||||
|             .rooms | ||||
|             .room_state(&body.room_id)? | ||||
|             .room_state_full(&body.room_id)? | ||||
|             .values() | ||||
|             .map(|pdu| pdu.to_state_event()) | ||||
|             .collect(), | ||||
|  |  | |||
|  | @ -56,7 +56,10 @@ impl Rooms { | |||
|     } | ||||
| 
 | ||||
|     /// Returns the full room state.
 | ||||
|     pub fn room_state(&self, room_id: &RoomId) -> Result<HashMap<(EventType, String), PduEvent>> { | ||||
|     pub fn room_state_full( | ||||
|         &self, | ||||
|         room_id: &RoomId, | ||||
|     ) -> Result<HashMap<(EventType, String), PduEvent>> { | ||||
|         let mut hashmap = HashMap::new(); | ||||
|         for pdu in self | ||||
|             .roomstateid_pdu | ||||
|  | @ -78,6 +81,58 @@ impl Rooms { | |||
|         Ok(hashmap) | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the full room state.
 | ||||
|     pub fn room_state_type( | ||||
|         &self, | ||||
|         room_id: &RoomId, | ||||
|         event_type: &EventType, | ||||
|     ) -> Result<HashMap<String, PduEvent>> { | ||||
|         let mut prefix = room_id.to_string().as_bytes().to_vec(); | ||||
|         prefix.push(0xff); | ||||
|         prefix.extend_from_slice(&event_type.to_string().as_bytes()); | ||||
| 
 | ||||
|         let mut hashmap = HashMap::new(); | ||||
|         for pdu in self | ||||
|             .roomstateid_pdu | ||||
|             .scan_prefix(&prefix) | ||||
|             .values() | ||||
|             .map(|value| { | ||||
|                 Ok::<_, Error>( | ||||
|                     serde_json::from_slice::<PduEvent>(&value?) | ||||
|                         .map_err(|_| Error::bad_database("Invalid PDU in db."))?, | ||||
|                 ) | ||||
|             }) | ||||
|         { | ||||
|             let pdu = pdu?; | ||||
|             let state_key = pdu.state_key.clone().ok_or_else(|| { | ||||
|                 Error::bad_database("Room state contains event without state_key.") | ||||
|             })?; | ||||
|             hashmap.insert(state_key, pdu); | ||||
|         } | ||||
|         Ok(hashmap) | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the full room state.
 | ||||
|     pub fn room_state_get( | ||||
|         &self, | ||||
|         room_id: &RoomId, | ||||
|         event_type: &EventType, | ||||
|         state_key: &str, | ||||
|     ) -> Result<Option<PduEvent>> { | ||||
|         let mut key = room_id.to_string().as_bytes().to_vec(); | ||||
|         key.push(0xff); | ||||
|         key.extend_from_slice(&event_type.to_string().as_bytes()); | ||||
|         key.push(0xff); | ||||
|         key.extend_from_slice(&state_key.as_bytes()); | ||||
| 
 | ||||
|         self.roomstateid_pdu.get(&key)?.map_or(Ok(None), |value| { | ||||
|             Ok::<_, Error>(Some( | ||||
|                 serde_json::from_slice::<PduEvent>(&value) | ||||
|                     .map_err(|_| Error::bad_database("Invalid PDU in db."))?, | ||||
|             )) | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the `count` of this pdu's id.
 | ||||
|     pub fn get_pdu_count(&self, event_id: &EventId) -> Result<Option<u64>> { | ||||
|         self.eventid_pduid | ||||
|  | @ -212,8 +267,7 @@ impl Rooms { | |||
|         // Is the event authorized?
 | ||||
|         if let Some(state_key) = &state_key { | ||||
|             let power_levels = self | ||||
|                 .room_state(&room_id)? | ||||
|                 .get(&(EventType::RoomPowerLevels, "".to_owned())) | ||||
|                 .room_state_get(&room_id, &EventType::RoomPowerLevels, "")? | ||||
|                 .map_or_else( | ||||
|                     || { | ||||
|                         Ok::<_, Error>(power_levels::PowerLevelsEventContent { | ||||
|  | @ -244,8 +298,7 @@ impl Rooms { | |||
|                     }, | ||||
|                 )?; | ||||
|             let sender_membership = self | ||||
|                 .room_state(&room_id)? | ||||
|                 .get(&(EventType::RoomMember, sender.to_string())) | ||||
|                 .room_state_get(&room_id, &EventType::RoomMember, &sender.to_string())? | ||||
|                 .map_or(Ok::<_, Error>(member::MembershipState::Leave), |pdu| { | ||||
|                     Ok( | ||||
|                         serde_json::from_value::<EventJson<member::MemberEventContent>>( | ||||
|  | @ -280,8 +333,11 @@ impl Rooms { | |||
|                     })?; | ||||
| 
 | ||||
|                     let current_membership = self | ||||
|                         .room_state(&room_id)? | ||||
|                         .get(&(EventType::RoomMember, target_user_id.to_string())) | ||||
|                         .room_state_get( | ||||
|                             &room_id, | ||||
|                             &EventType::RoomMember, | ||||
|                             &target_user_id.to_string(), | ||||
|                         )? | ||||
|                         .map_or(Ok::<_, Error>(member::MembershipState::Leave), |pdu| { | ||||
|                             Ok( | ||||
|                                 serde_json::from_value::<EventJson<member::MemberEventContent>>( | ||||
|  | @ -315,8 +371,7 @@ impl Rooms { | |||
|                     ); | ||||
| 
 | ||||
|                     let join_rules = | ||||
|                         self.room_state(&room_id)? | ||||
|                             .get(&(EventType::RoomJoinRules, "".to_owned())) | ||||
|                         self.room_state_get(&room_id, &EventType::RoomJoinRules, "")? | ||||
|                             .map_or(Ok::<_, Error>(join_rules::JoinRule::Public), |pdu| { | ||||
|                                 Ok(serde_json::from_value::< | ||||
|                                     EventJson<join_rules::JoinRulesEventContent>, | ||||
|  | @ -446,12 +501,8 @@ impl Rooms { | |||
|             + 1; | ||||
| 
 | ||||
|         let mut unsigned = unsigned.unwrap_or_default(); | ||||
|         // TODO: Optimize this to not load the whole room state?
 | ||||
|         if let Some(state_key) = &state_key { | ||||
|             if let Some(prev_pdu) = self | ||||
|                 .room_state(&room_id)? | ||||
|                 .get(&(event_type.clone(), state_key.to_owned())) | ||||
|             { | ||||
|             if let Some(prev_pdu) = self.room_state_get(&room_id, &event_type, &state_key)? { | ||||
|                 unsigned.insert("prev_content".to_owned(), prev_pdu.content.clone()); | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| #![feature(proc_macro_hygiene, decl_macro)] | ||||
| #![warn(rust_2018_idioms)] | ||||
| 
 | ||||
| pub mod push_rules; | ||||
| 
 | ||||
| mod client_server; | ||||
| mod database; | ||||
| mod error; | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ use ruma::{ | |||
|     api::federation::EventHash, | ||||
|     events::{ | ||||
|         collections::all::{RoomEvent, StateEvent}, | ||||
|         room::member::MemberEvent, | ||||
|         stripped::AnyStrippedStateEvent, | ||||
|         EventJson, EventType, | ||||
|     }, | ||||
|  | @ -95,4 +96,9 @@ impl PduEvent { | |||
|         serde_json::from_str::<EventJson<AnyStrippedStateEvent>>(&json) | ||||
|             .expect("EventJson::from_str always works") | ||||
|     } | ||||
|     pub fn to_member_event(&self) -> EventJson<MemberEvent> { | ||||
|         let json = serde_json::to_string(&self).expect("PDUs are always valid"); | ||||
|         serde_json::from_str::<EventJson<MemberEvent>>(&json) | ||||
|             .expect("EventJson::from_str always works") | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										232
									
								
								src/push_rules.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								src/push_rules.rs
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,232 @@ | |||
| use ruma::{ | ||||
|     events::push_rules::{ | ||||
|         ConditionalPushRule, PatternedPushRule, PushCondition, PushRule, Ruleset, | ||||
|     }, | ||||
|     identifiers::UserId, | ||||
|     push::{Action, Tweak}, | ||||
| }; | ||||
| 
 | ||||
| pub fn default_pushrules(user_id: &UserId) -> Ruleset { | ||||
|     Ruleset { | ||||
|         content: vec![contains_user_name_rule(&user_id)], | ||||
|         override_: vec![ | ||||
|             master_rule(), | ||||
|             suppress_notices_rule(), | ||||
|             invite_for_me_rule(), | ||||
|             member_event_rule(), | ||||
|             contains_display_name_rule(), | ||||
|             tombstone_rule(), | ||||
|             roomnotif_rule(), | ||||
|         ], | ||||
|         room: vec![], | ||||
|         sender: vec![], | ||||
|         underride: vec![ | ||||
|             call_rule(), | ||||
|             encrypted_room_one_to_one_rule(), | ||||
|             room_one_to_one_rule(), | ||||
|             message_rule(), | ||||
|             encrypted_rule(), | ||||
|         ], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn master_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![Action::DontNotify], | ||||
|         default: true, | ||||
|         enabled: false, | ||||
|         rule_id: ".m.rule.master".to_owned(), | ||||
|         conditions: vec![], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn suppress_notices_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![Action::DontNotify], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.suppress_notices".to_owned(), | ||||
|         conditions: vec![PushCondition::EventMatch { | ||||
|             key: "content.msgtype".to_owned(), | ||||
|             pattern: "m.notice".to_owned(), | ||||
|         }], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn invite_for_me_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![ | ||||
|             Action::Notify, | ||||
|             Action::SetTweak(Tweak::Sound("default".to_owned())), | ||||
|             Action::SetTweak(Tweak::Highlight(false)), | ||||
|         ], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.invite_for_me".to_owned(), | ||||
|         conditions: vec![PushCondition::EventMatch { | ||||
|             key: "content.membership".to_owned(), | ||||
|             pattern: "m.invite".to_owned(), | ||||
|         }], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn member_event_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![Action::DontNotify], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.member_event".to_owned(), | ||||
|         conditions: vec![PushCondition::EventMatch { | ||||
|             key: "content.membership".to_owned(), | ||||
|             pattern: "type".to_owned(), | ||||
|         }], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn contains_display_name_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![ | ||||
|             Action::Notify, | ||||
|             Action::SetTweak(Tweak::Sound("default".to_owned())), | ||||
|             Action::SetTweak(Tweak::Highlight(true)), | ||||
|         ], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.contains_display_name".to_owned(), | ||||
|         conditions: vec![PushCondition::ContainsDisplayName], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn tombstone_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(true))], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.tombstone".to_owned(), | ||||
|         conditions: vec![ | ||||
|             PushCondition::EventMatch { | ||||
|                 key: "type".to_owned(), | ||||
|                 pattern: "m.room.tombstone".to_owned(), | ||||
|             }, | ||||
|             PushCondition::EventMatch { | ||||
|                 key: "state_key".to_owned(), | ||||
|                 pattern: "".to_owned(), | ||||
|             }, | ||||
|         ], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn roomnotif_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(true))], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.roomnotif".to_owned(), | ||||
|         conditions: vec![ | ||||
|             PushCondition::EventMatch { | ||||
|                 key: "content.body".to_owned(), | ||||
|                 pattern: "@room".to_owned(), | ||||
|             }, | ||||
|             PushCondition::SenderNotificationPermission { | ||||
|                 key: "room".to_owned(), | ||||
|             }, | ||||
|         ], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn contains_user_name_rule(user_id: &UserId) -> PatternedPushRule { | ||||
|     PatternedPushRule { | ||||
|         actions: vec![ | ||||
|             Action::Notify, | ||||
|             Action::SetTweak(Tweak::Sound("default".to_owned())), | ||||
|             Action::SetTweak(Tweak::Highlight(true)), | ||||
|         ], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.contains_user_name".to_owned(), | ||||
|         pattern: user_id.localpart().to_owned(), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn call_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![ | ||||
|             Action::Notify, | ||||
|             Action::SetTweak(Tweak::Sound("ring".to_owned())), | ||||
|             Action::SetTweak(Tweak::Highlight(false)), | ||||
|         ], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.call".to_owned(), | ||||
|         conditions: vec![PushCondition::EventMatch { | ||||
|             key: "type".to_owned(), | ||||
|             pattern: "m.call.invite".to_owned(), | ||||
|         }], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn encrypted_room_one_to_one_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![ | ||||
|             Action::Notify, | ||||
|             Action::SetTweak(Tweak::Sound("default".to_owned())), | ||||
|             Action::SetTweak(Tweak::Highlight(false)), | ||||
|         ], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.encrypted_room_one_to_one".to_owned(), | ||||
|         conditions: vec![ | ||||
|             PushCondition::RoomMemberCount { is: "2".to_owned() }, | ||||
|             PushCondition::EventMatch { | ||||
|                 key: "type".to_owned(), | ||||
|                 pattern: "m.room.encrypted".to_owned(), | ||||
|             }, | ||||
|         ], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn room_one_to_one_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![ | ||||
|             Action::Notify, | ||||
|             Action::SetTweak(Tweak::Sound("default".to_owned())), | ||||
|             Action::SetTweak(Tweak::Highlight(false)), | ||||
|         ], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.room_one_to_one".to_owned(), | ||||
|         conditions: vec![ | ||||
|             PushCondition::RoomMemberCount { is: "2".to_owned() }, | ||||
|             PushCondition::EventMatch { | ||||
|                 key: "type".to_owned(), | ||||
|                 pattern: "m.room.message".to_owned(), | ||||
|             }, | ||||
|         ], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn message_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(false))], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.message".to_owned(), | ||||
|         conditions: vec![PushCondition::EventMatch { | ||||
|             key: "type".to_owned(), | ||||
|             pattern: "m.room.message".to_owned(), | ||||
|         }], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn encrypted_rule() -> ConditionalPushRule { | ||||
|     ConditionalPushRule { | ||||
|         actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(false))], | ||||
|         default: true, | ||||
|         enabled: true, | ||||
|         rule_id: ".m.rule.encrypted".to_owned(), | ||||
|         conditions: vec![PushCondition::EventMatch { | ||||
|             key: "type".to_owned(), | ||||
|             pattern: "m.room.encrypted".to_owned(), | ||||
|         }], | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in a new issue