Browse Source
It seems in order to test this I may also have to impl the email 3pid route? I need to call the set_pusher route somehow.pushers-rebased
6 changed files with 513 additions and 165 deletions
@ -0,0 +1,148 @@ |
|||||||
|
use crate::{Error, PduEvent, Result}; |
||||||
|
use ruma::{ |
||||||
|
api::client::r0::push::{Pusher, PusherKind}, |
||||||
|
events::{ |
||||||
|
room::{ |
||||||
|
member::MemberEventContent, |
||||||
|
message::{MessageEventContent, TextMessageEventContent}, |
||||||
|
}, |
||||||
|
EventType, |
||||||
|
}, |
||||||
|
push::{PushCondition, Ruleset}, |
||||||
|
UserId, |
||||||
|
}; |
||||||
|
|
||||||
|
#[derive(Debug, Clone)] |
||||||
|
pub struct PushData { |
||||||
|
/// UserId + pushkey -> Pusher
|
||||||
|
pub(super) senderkey_pusher: sled::Tree, |
||||||
|
} |
||||||
|
|
||||||
|
impl PushData { |
||||||
|
pub fn new(db: &sled::Db) -> Result<Self> { |
||||||
|
Ok(Self { |
||||||
|
senderkey_pusher: db.open_tree("senderkey_pusher")?, |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn set_pusher(&self, sender: &UserId, pusher: Pusher) -> Result<()> { |
||||||
|
let mut key = sender.as_bytes().to_vec(); |
||||||
|
key.extend_from_slice(pusher.pushkey.as_bytes()); |
||||||
|
|
||||||
|
self.senderkey_pusher.insert( |
||||||
|
key, |
||||||
|
&*serde_json::to_string(&pusher).expect("Pusher is valid JSON string"), |
||||||
|
)?; |
||||||
|
|
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn get_pusher(&self, sender: &UserId) -> Result<Vec<Pusher>> { |
||||||
|
self.senderkey_pusher |
||||||
|
.scan_prefix(sender.as_bytes()) |
||||||
|
.values() |
||||||
|
.map(|push: std::result::Result<sled::IVec, _>| { |
||||||
|
let push = push.map_err(|_| Error::bad_database("Invalid push bytes in db."))?; |
||||||
|
Ok(serde_json::from_slice(&*push) |
||||||
|
.map_err(|_| Error::bad_database("Invalid Pusher in db."))?) |
||||||
|
}) |
||||||
|
.collect::<Result<Vec<_>>>() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub async fn send_push_notice( |
||||||
|
user: &UserId, |
||||||
|
pusher: &Pusher, |
||||||
|
ruleset: Ruleset, |
||||||
|
pdu: &PduEvent, |
||||||
|
) -> Result<()> { |
||||||
|
for rule in ruleset.into_iter() { |
||||||
|
// TODO: can actions contain contradictory Actions
|
||||||
|
if rule |
||||||
|
.actions |
||||||
|
.iter() |
||||||
|
.any(|act| matches!(act, ruma::push::Action::DontNotify)) |
||||||
|
|| !rule.enabled |
||||||
|
{ |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
match rule.rule_id.as_str() { |
||||||
|
".m.rule.master" => {} |
||||||
|
".m.rule.suppress_notices" => {} |
||||||
|
".m.rule.invite_for_me" => {} |
||||||
|
".m.rule.member_event" => { |
||||||
|
if let EventType::RoomMember = &pdu.kind { |
||||||
|
// TODO use this?
|
||||||
|
let _member = serde_json::from_value::<MemberEventContent>(pdu.content.clone()) |
||||||
|
.map_err(|_| Error::bad_database("PDU contained bad message content"))?; |
||||||
|
if let Some(conditions) = rule.conditions { |
||||||
|
if conditions.iter().any(|cond| match cond { |
||||||
|
PushCondition::EventMatch { key, pattern } => { |
||||||
|
let mut json = |
||||||
|
serde_json::to_value(pdu).expect("PDU is valid JSON"); |
||||||
|
for key in key.split('.') { |
||||||
|
json = json[key].clone(); |
||||||
|
} |
||||||
|
// TODO: this is baddddd
|
||||||
|
json.to_string().contains(pattern) |
||||||
|
} |
||||||
|
_ => false, |
||||||
|
}) {} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
".m.rule.contains_display_name" => { |
||||||
|
if let EventType::RoomMessage = &pdu.kind { |
||||||
|
let msg_content = |
||||||
|
serde_json::from_value::<MessageEventContent>(pdu.content.clone()) |
||||||
|
.map_err(|_| { |
||||||
|
Error::bad_database("PDU contained bad message content") |
||||||
|
})?; |
||||||
|
if let MessageEventContent::Text(TextMessageEventContent { body, .. }) = |
||||||
|
&msg_content |
||||||
|
{ |
||||||
|
if body.contains(user.localpart()) { |
||||||
|
send_notice(user, &pusher, &pdu).await?; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
".m.rule.tombstone" => {} |
||||||
|
".m.rule.roomnotif" => {} |
||||||
|
".m.rule.contains_user_name" => { |
||||||
|
if let EventType::RoomMessage = &pdu.kind { |
||||||
|
let msg_content = |
||||||
|
serde_json::from_value::<MessageEventContent>(pdu.content.clone()) |
||||||
|
.map_err(|_| { |
||||||
|
Error::bad_database("PDU contained bad message content") |
||||||
|
})?; |
||||||
|
if let MessageEventContent::Text(TextMessageEventContent { body, .. }) = |
||||||
|
&msg_content |
||||||
|
{ |
||||||
|
if body.contains(user.localpart()) { |
||||||
|
send_notice(user, &pusher, &pdu).await?; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
".m.rule.call" => {} |
||||||
|
".m.rule.encrypted_room_one_to_one" => {} |
||||||
|
".m.rule.room_one_to_one" => {} |
||||||
|
".m.rule.message" => {} |
||||||
|
".m.rule.encrypted" => {} |
||||||
|
_ => {} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
|
||||||
|
async fn send_notice(_sender: &UserId, pusher: &Pusher, _event: &PduEvent) -> Result<()> { |
||||||
|
if let Some(PusherKind::Http) = pusher.kind { |
||||||
|
log::error!("YAHOOO"); |
||||||
|
} else { |
||||||
|
// EMAIL
|
||||||
|
todo!("send an email") |
||||||
|
} |
||||||
|
Ok(()) |
||||||
|
} |
||||||
Loading…
Reference in new issue