-#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct AnnounceActivity {
- to: PublicUrl,
- object: AnnouncableActivities,
- cc: Vec<Url>,
- #[serde(rename = "type")]
- kind: AnnounceType,
- #[serde(flatten)]
- common: ActivityCommonFields,
+impl AnnounceActivity {
+ pub(crate) fn new(
+ object: RawAnnouncableActivities,
+ community: &ApubCommunity,
+ context: &Data<LemmyContext>,
+ ) -> Result<AnnounceActivity, LemmyError> {
+ Ok(AnnounceActivity {
+ actor: community.id().into(),
+ to: vec![public()],
+ object: IdOrNestedObject::NestedObject(object),
+ cc: vec![community.followers_url.clone().into()],
+ kind: AnnounceType::Announce,
+ id: generate_activity_id(
+ &AnnounceType::Announce,
+ &context.settings().get_protocol_and_hostname(),
+ )?,
+ })
+ }
+
+ #[tracing::instrument(skip_all)]
+ pub async fn send(
+ object: RawAnnouncableActivities,
+ community: &ApubCommunity,
+ context: &Data<LemmyContext>,
+ ) -> Result<(), LemmyError> {
+ let announce = AnnounceActivity::new(object.clone(), community, context)?;
+ let inboxes = community.get_follower_inboxes(context).await?;
+ send_lemmy_activity(context, announce, community, inboxes.clone(), false).await?;
+
+ // Pleroma and Mastodon can't handle activities like Announce/Create/Page. So for
+ // compatibility, we also send Announce/Page so that they can follow Lemmy communities.
+ let object_parsed = object.try_into()?;
+ if let AnnouncableActivities::CreateOrUpdatePost(c) = object_parsed {
+ // Hack: need to convert Page into a format which can be sent as activity, which requires
+ // adding actor field.
+ let announcable_page = RawAnnouncableActivities {
+ id: generate_activity_id(
+ AnnounceType::Announce,
+ &context.settings().get_protocol_and_hostname(),
+ )?,
+ actor: c.actor.clone().into_inner(),
+ other: serde_json::to_value(c.object)?
+ .as_object()
+ .expect("is object")
+ .clone(),
+ };
+ let announce_compat = AnnounceActivity::new(announcable_page, community, context)?;
+ send_lemmy_activity(context, announce_compat, community, inboxes, false).await?;
+ }
+ Ok(())
+ }