3 activities::generate_activity_id,
4 activity_queue::send_activity,
6 check_is_apub_id_valid,
8 fetcher::get_or_fetch_and_upsert_user,
18 use activitystreams::{
20 kind::{CreateType, DeleteType, UndoType, UpdateType},
26 object::{kind::NoteType, Note, Tombstone},
31 private_message::{PrivateMessage, PrivateMessageForm},
35 use lemmy_structs::blocking;
36 use lemmy_utils::{location_info, utils::convert_datetime, LemmyError};
39 #[async_trait::async_trait(?Send)]
40 impl ToApub for PrivateMessage {
43 async fn to_apub(&self, pool: &DbPool) -> Result<Note, LemmyError> {
44 let mut private_message = Note::new();
46 let creator_id = self.creator_id;
47 let creator = blocking(pool, move |conn| User_::read(conn, creator_id)).await??;
49 let recipient_id = self.recipient_id;
50 let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
53 .set_context(activitystreams::context())
54 .set_id(Url::parse(&self.ap_id.to_owned())?)
55 .set_published(convert_datetime(self.published))
56 .set_content(self.content.to_owned())
57 .set_to(recipient.actor_id)
58 .set_attributed_to(creator.actor_id);
60 if let Some(u) = self.updated {
61 private_message.set_updated(convert_datetime(u));
67 fn to_tombstone(&self) -> Result<Tombstone, LemmyError> {
68 create_tombstone(self.deleted, &self.ap_id, self.updated, NoteType::Note)
72 #[async_trait::async_trait(?Send)]
73 impl FromApub for PrivateMessageForm {
76 /// Parse an ActivityPub note received from another instance into a Lemmy Private message
79 context: &LemmyContext,
80 expected_domain: Option<Url>,
81 ) -> Result<PrivateMessageForm, LemmyError> {
82 let creator_actor_id = note
84 .context(location_info!())?
87 .context(location_info!())?;
89 let creator = get_or_fetch_and_upsert_user(&creator_actor_id, context).await?;
90 let recipient_actor_id = note
92 .context(location_info!())?
95 .context(location_info!())?;
96 let recipient = get_or_fetch_and_upsert_user(&recipient_actor_id, context).await?;
97 let ap_id = note.id_unchecked().context(location_info!())?.to_string();
98 check_is_apub_id_valid(&Url::parse(&ap_id)?)?;
100 Ok(PrivateMessageForm {
101 creator_id: creator.id,
102 recipient_id: recipient.id,
105 .context(location_info!())?
106 .as_single_xsd_string()
107 .context(location_info!())?
109 published: note.published().map(|u| u.to_owned().naive_local()),
110 updated: note.updated().map(|u| u.to_owned().naive_local()),
113 ap_id: Some(check_actor_domain(note, expected_domain)?),
119 #[async_trait::async_trait(?Send)]
120 impl ApubObjectType for PrivateMessage {
121 /// Send out information about a newly created private message
122 async fn send_create(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
123 let note = self.to_apub(context.pool()).await?;
125 let recipient_id = self.recipient_id;
126 let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
128 let mut create = Create::new(creator.actor_id.to_owned(), note.into_any_base()?);
129 let to = recipient.get_inbox_url()?;
131 .set_context(activitystreams::context())
132 .set_id(generate_activity_id(CreateType::Create)?)
135 insert_activity(creator.id, create.clone(), true, context.pool()).await?;
137 send_activity(context.activity_queue(), create, creator, vec![to])?;
141 /// Send out information about an edited post, to the followers of the community.
142 async fn send_update(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
143 let note = self.to_apub(context.pool()).await?;
145 let recipient_id = self.recipient_id;
146 let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
148 let mut update = Update::new(creator.actor_id.to_owned(), note.into_any_base()?);
149 let to = recipient.get_inbox_url()?;
151 .set_context(activitystreams::context())
152 .set_id(generate_activity_id(UpdateType::Update)?)
155 insert_activity(creator.id, update.clone(), true, context.pool()).await?;
157 send_activity(context.activity_queue(), update, creator, vec![to])?;
161 async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
162 let note = self.to_apub(context.pool()).await?;
164 let recipient_id = self.recipient_id;
165 let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
167 let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
168 let to = recipient.get_inbox_url()?;
170 .set_context(activitystreams::context())
171 .set_id(generate_activity_id(DeleteType::Delete)?)
174 insert_activity(creator.id, delete.clone(), true, context.pool()).await?;
176 send_activity(context.activity_queue(), delete, creator, vec![to])?;
180 async fn send_undo_delete(
183 context: &LemmyContext,
184 ) -> Result<(), LemmyError> {
185 let note = self.to_apub(context.pool()).await?;
187 let recipient_id = self.recipient_id;
188 let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
190 let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
191 let to = recipient.get_inbox_url()?;
193 .set_context(activitystreams::context())
194 .set_id(generate_activity_id(DeleteType::Delete)?)
197 // Undo that fake activity
198 let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
200 .set_context(activitystreams::context())
201 .set_id(generate_activity_id(UndoType::Undo)?)
204 insert_activity(creator.id, undo.clone(), true, context.pool()).await?;
206 send_activity(context.activity_queue(), undo, creator, vec![to])?;
210 async fn send_remove(&self, _mod_: &User_, _context: &LemmyContext) -> Result<(), LemmyError> {
214 async fn send_undo_remove(
217 _context: &LemmyContext,
218 ) -> Result<(), LemmyError> {