mirror of
https://github.com/LemmyNet/activitypub-federation-rust
synced 2024-11-10 06:04:19 +00:00
Option to include published
timestamp for sent activities
This commit is contained in:
parent
1b46dd6f80
commit
05ab30a1b9
5 changed files with 32 additions and 7 deletions
|
@ -15,7 +15,7 @@ axum = ["dep:axum", "dep:tower", "dep:hyper", "dep:http-body-util"]
|
|||
diesel = ["dep:diesel"]
|
||||
|
||||
[dependencies]
|
||||
chrono = { version = "0.4.34", features = ["clock"], default-features = false }
|
||||
chrono = { version = "0.4.34", features = ["clock", "serde"], default-features = false }
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
async-trait = "0.1.77"
|
||||
url = { version = "2.5.0", features = ["serde"] }
|
||||
|
|
|
@ -119,7 +119,7 @@ impl DbUser {
|
|||
if use_queue {
|
||||
queue_activity(&activity, self, recipients, data).await?;
|
||||
} else {
|
||||
let sends = SendActivityTask::prepare(&activity, self, recipients, data).await?;
|
||||
let sends = SendActivityTask::prepare(&activity, self, recipients, None, data).await?;
|
||||
for send in sends {
|
||||
send.sign_and_send(data).await?;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ where
|
|||
ActorType: Actor,
|
||||
{
|
||||
let config = &data.config;
|
||||
let tasks = build_tasks(activity, actor, inboxes, data).await?;
|
||||
let tasks = build_tasks(activity, actor, inboxes, None, data).await?;
|
||||
|
||||
for task in tasks {
|
||||
// Don't use the activity queue if this is in debug mode, send and wait directly
|
||||
|
|
|
@ -19,10 +19,10 @@ use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
|
|||
use reqwest_middleware::ClientWithMiddleware;
|
||||
use serde::Serialize;
|
||||
use std::{
|
||||
self,
|
||||
fmt::{Debug, Display},
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use tracing::debug;
|
||||
use url::Url;
|
||||
|
||||
|
@ -51,10 +51,13 @@ impl SendActivityTask {
|
|||
/// - `inboxes`: List of remote actor inboxes that should receive the activity. Ignores local actor
|
||||
/// inboxes. Should be built by calling [crate::traits::Actor::shared_inbox_or_inbox]
|
||||
/// for each target actor.
|
||||
/// - `published`: Time when the activity was created, so that recipient can apply activities
|
||||
/// in correct order.
|
||||
pub async fn prepare<Activity, Datatype, ActorType>(
|
||||
activity: &Activity,
|
||||
actor: &ActorType,
|
||||
inboxes: Vec<Url>,
|
||||
published: Option<DateTime<Utc>>,
|
||||
data: &Data<Datatype>,
|
||||
) -> Result<Vec<SendActivityTask>, Error>
|
||||
where
|
||||
|
@ -62,7 +65,7 @@ impl SendActivityTask {
|
|||
Datatype: Clone,
|
||||
ActorType: Actor,
|
||||
{
|
||||
build_tasks(activity, actor, inboxes, data).await
|
||||
build_tasks(activity, actor, inboxes, published, data).await
|
||||
}
|
||||
|
||||
/// convert a sendactivitydata to a request, signing and sending it
|
||||
|
@ -117,6 +120,7 @@ pub(crate) async fn build_tasks<'a, Activity, Datatype, ActorType>(
|
|||
activity: &'a Activity,
|
||||
actor: &ActorType,
|
||||
inboxes: Vec<Url>,
|
||||
published: Option<DateTime<Utc>>,
|
||||
data: &Data<Datatype>,
|
||||
) -> Result<Vec<SendActivityTask>, Error>
|
||||
where
|
||||
|
@ -127,7 +131,10 @@ where
|
|||
let config = &data.config;
|
||||
let actor_id = activity.actor();
|
||||
let activity_id = activity.id();
|
||||
let activity_serialized: Bytes = serde_json::to_vec(activity)
|
||||
let activity_serialized: Bytes = match published {
|
||||
Some(published) => serde_json::to_vec(&WithPublished::new(activity, published)),
|
||||
None => serde_json::to_vec(activity)
|
||||
}
|
||||
.map_err(|e| Error::SerializeOutgoingActivity(e, format!("{:?}", activity)))?
|
||||
.into();
|
||||
let private_key = get_pkey_cached(data, actor).await?;
|
||||
|
@ -210,6 +217,24 @@ pub(crate) fn generate_request_headers(inbox_url: &Url) -> HeaderMap {
|
|||
headers
|
||||
}
|
||||
|
||||
/// Wrapper struct that adds `published` field with timestamp to outgoing activities. Important that
|
||||
/// the timestamp includes milliseconds and timezone.
|
||||
#[derive(Serialize)]
|
||||
struct WithPublished<T> {
|
||||
published: DateTime<Utc>,
|
||||
#[serde(flatten)]
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<T> WithPublished<T> {
|
||||
pub fn new(inner: T, published: DateTime<Utc>) -> WithPublished<T> {
|
||||
Self {
|
||||
published,
|
||||
inner,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -343,7 +343,7 @@ pub mod tests {
|
|||
error::Error,
|
||||
fetch::object_id::ObjectId,
|
||||
http_signatures::{generate_actor_keypair, Keypair},
|
||||
protocol::{public_key::PublicKey, verification::verify_domains_match},
|
||||
protocol::{verification::verify_domains_match},
|
||||
};
|
||||
use activitystreams_kinds::{activity::FollowType, actor::PersonType};
|
||||
use once_cell::sync::Lazy;
|
||||
|
|
Loading…
Reference in a new issue