♻️ Refactor the follow activitypub process

This commit is contained in:
2025-12-31 22:52:31 +08:00
parent add9fa49e5
commit c11b30d0bb
2 changed files with 86 additions and 101 deletions

View File

@@ -39,6 +39,7 @@ public class ActivityPubActivityHandler(
{ {
return await db.Posts.FirstOrDefaultAsync(p => p.Id == id); return await db.Posts.FirstOrDefaultAsync(p => p.Id == id);
} }
return null; return null;
} }
@@ -122,49 +123,33 @@ public class ActivityPubActivityHandler(
} }
var actor = await GetOrCreateActorAsync(actorUri); var actor = await GetOrCreateActorAsync(actorUri);
var targetUsername = ExtractUsernameFromUri(objectUri); // This might be fail, but we assume it works great.
var targetPublisher = await db.Publishers var targetActor = await GetOrCreateActorAsync(objectUri);
.FirstOrDefaultAsync(p => p.Name == targetUsername);
if (targetPublisher == null)
{
logger.LogWarning("Target publisher not found: {Uri}, ExtractedUsername: {Username}",
objectUri, targetUsername);
return false;
}
var localActor = await deliveryService.GetLocalActorAsync(targetPublisher.Id);
if (localActor == null)
{
logger.LogWarning("Target publisher has no enabled fediverse actor");
return false;
}
logger.LogInformation("Target publisher found: {PublisherName} (ID: {Id})",
targetPublisher.Name, targetPublisher.Id);
var existingRelationship = await db.FediverseRelationships var existingRelationship = await db.FediverseRelationships
.FirstOrDefaultAsync(r => .FirstOrDefaultAsync(r =>
r.ActorId == actor.Id && r.ActorId == actor.Id &&
r.TargetActorId == localActor.Id); r.TargetActorId == targetActor.Id);
switch (existingRelationship) switch (existingRelationship)
{ {
case { State: RelationshipState.Accepted }: case { State: RelationshipState.Accepted }:
logger.LogInformation("Follow relationship already exists and is accepted. ActorId: {ActorId}, PublisherId: {PublisherId}", logger.LogInformation(
actor.Id, targetPublisher.Id); "Follow relationship already exists and is accepted. ActorId: {ActorId}, TargetId: {TargetId}",
actor.Id, targetActor.Id);
return true; return true;
case null: case null:
existingRelationship = new SnFediverseRelationship existingRelationship = new SnFediverseRelationship
{ {
ActorId = actor.Id, ActorId = actor.Id,
TargetActorId = localActor.Id, TargetActorId = targetActor.Id,
State = RelationshipState.Accepted, State = RelationshipState.Accepted,
FollowedBackAt = SystemClock.Instance.GetCurrentInstant() FollowedBackAt = SystemClock.Instance.GetCurrentInstant()
}; };
db.FediverseRelationships.Add(existingRelationship); db.FediverseRelationships.Add(existingRelationship);
logger.LogInformation("Created new follow relationship. ActorId: {ActorId}, TargetActorId: {TargetActorId}", logger.LogInformation(
actor.Id, localActor.Id); "Created new follow relationship. ActorId: {ActorId}, TargetActorId: {TargetId}",
actor.Id, targetActor.Id);
break; break;
default: default:
existingRelationship.State = RelationshipState.Accepted; existingRelationship.State = RelationshipState.Accepted;
@@ -177,7 +162,7 @@ public class ActivityPubActivityHandler(
await db.SaveChangesAsync(); await db.SaveChangesAsync();
await deliveryService.SendAcceptActivityAsync( await deliveryService.SendAcceptActivityAsync(
targetPublisher.Id, targetActor,
actorUri, actorUri,
activityId ?? "" activityId ?? ""
); );
@@ -210,6 +195,7 @@ public class ActivityPubActivityHandler(
logger.LogWarning("Local actor not found for accept object: {ObjectUri}", objectUri); logger.LogWarning("Local actor not found for accept object: {ObjectUri}", objectUri);
return false; return false;
} }
relationship = new SnFediverseRelationship relationship = new SnFediverseRelationship
{ {
ActorId = localActor.Id, ActorId = localActor.Id,
@@ -304,11 +290,15 @@ public class ActivityPubActivityHandler(
var content = new SnPost var content = new SnPost
{ {
FediverseUri = contentUri, FediverseUri = contentUri,
FediverseType = objectType == "Article" ? FediverseContentType.FediverseArticle : FediverseContentType.FediverseNote, FediverseType = objectType == "Article"
? FediverseContentType.FediverseArticle
: FediverseContentType.FediverseNote,
Title = objectDict.GetValueOrDefault("name")?.ToString(), Title = objectDict.GetValueOrDefault("name")?.ToString(),
Description = objectDict.GetValueOrDefault("summary")?.ToString(), Description = objectDict.GetValueOrDefault("summary")?.ToString(),
Content = objectDict.GetValueOrDefault("content")?.ToString(), Content = objectDict.GetValueOrDefault("content")?.ToString(),
ContentType = objectDict.GetValueOrDefault("contentMap") != null ? PostContentType.Html : PostContentType.Markdown, ContentType = objectDict.GetValueOrDefault("contentMap") != null
? PostContentType.Html
: PostContentType.Markdown,
PublishedAt = ParseInstant(objectDict.GetValueOrDefault("published")), PublishedAt = ParseInstant(objectDict.GetValueOrDefault("published")),
EditedAt = ParseInstant(objectDict.GetValueOrDefault("updated")), EditedAt = ParseInstant(objectDict.GetValueOrDefault("updated")),
ActorId = actor.Id, ActorId = actor.Id,
@@ -500,8 +490,8 @@ public class ActivityPubActivityHandler(
var actor = await db.FediverseActors var actor = await db.FediverseActors
.FirstOrDefaultAsync(a => a.Uri == actorUri); .FirstOrDefaultAsync(a => a.Uri == actorUri);
if (actor == null) if (actor != null) return actor;
{
var instance = await GetOrCreateInstanceAsync(actorUri); var instance = await GetOrCreateInstanceAsync(actorUri);
actor = new SnFediverseActor actor = new SnFediverseActor
{ {
@@ -514,7 +504,6 @@ public class ActivityPubActivityHandler(
await db.SaveChangesAsync(); await db.SaveChangesAsync();
await discoveryService.FetchActorDataAsync(actor); await discoveryService.FetchActorDataAsync(actor);
}
return actor; return actor;
} }

View File

@@ -29,16 +29,12 @@ public class ActivityPubDeliveryService(
} }
public async Task<bool> SendAcceptActivityAsync( public async Task<bool> SendAcceptActivityAsync(
Guid publisherId, SnFediverseActor actor,
string followerActorUri, string followerActorUri,
string followActivityId string followActivityId
) )
{ {
var publisher = await db.Publishers.FindAsync(publisherId); var actorUrl = actor.Uri;
if (publisher == null)
return false;
var actorUrl = $"https://{Domain}/activitypub/actors/{publisher.Name}";
var followerActor = await db.FediverseActors var followerActor = await db.FediverseActors
.FirstOrDefaultAsync(a => a.Uri == followerActorUri); .FirstOrDefaultAsync(a => a.Uri == followerActorUri);