48 lines
1.6 KiB
C#
48 lines
1.6 KiB
C#
using PrivaPub.Federation.Actors;
|
|||
|
|
using PrivaPub.Federation.Rendering;
|
||
|
|
|
||
|
|
using System.Security.Cryptography;
|
||
|
|
using System.Text;
|
||
|
|
using System.Text.Json.Nodes;
|
||
|
|
|
||
|
|
namespace PrivaPub.Federation.Outbox
|
||
|
|
{
|
||
|
|
public interface IGroupDistributor
|
||
|
|
{
|
||
|
|
Task Announce(LocalActor group, JsonObject activity, string objectUri, bool isNewPost, CancellationToken token);
|
||
|
|
}
|
||
|
|
|
||
|
|
public class GroupDistributor : IGroupDistributor
|
||
|
|
{
|
||
|
|
readonly IDeliveryService _delivery;
|
||
|
|
|
||
|
|
public GroupDistributor(IDeliveryService delivery)
|
||
|
|
{
|
||
|
|
_delivery = delivery;
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task Announce(LocalActor group, JsonObject activity, string objectUri, bool isNewPost, CancellationToken token)
|
||
|
|
{
|
||
|
|
if (group is not { IsCircle: false, Kind: Models.Federation.LocalActorKind.Group })
|
||
|
|
return;
|
||
|
|
var embedded = (JsonObject)activity.DeepClone();
|
||
|
|
embedded.Remove("@context");
|
||
|
|
embedded["audience"] ??= group.Uri;
|
||
|
|
var key = Convert.ToHexStringLower(SHA256.HashData(Encoding.UTF8.GetBytes(activity["id"]?.GetValue<string>() ?? embedded.ToJsonString())))[..24];
|
||
|
|
var announce = new JsonObject
|
||
|
|
{
|
||
|
|
["@context"] = ActivityPubRenderer.Context(),
|
||
|
|
["id"] = group.ActivityUri($"announce-{key}"),
|
||
|
|
["type"] = "Announce",
|
||
|
|
["actor"] = group.Uri,
|
||
|
|
["to"] = new JsonArray(ActivityPubRenderer.Public),
|
||
|
|
["cc"] = new JsonArray(group.Followers),
|
||
|
|
["audience"] = group.Uri,
|
||
|
|
["object"] = embedded
|
||
|
|
};
|
||
|
|
await _delivery.EnqueueToFollowers(group, announce, token);
|
||
|
|
if (isNewPost && !string.IsNullOrEmpty(objectUri))
|
||
|
|
await _delivery.EnqueueToFollowers(group, ActivityPubRenderer.Announce(group, objectUri, $"announce-object-{key}"), token);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|