♻️ Refactor the follow activitypub process
This commit is contained in:
@@ -26,10 +26,10 @@ public class ActivityPubActivityHandler(
|
|||||||
{
|
{
|
||||||
var uri = new Uri(objectUri);
|
var uri = new Uri(objectUri);
|
||||||
var domain = uri.Host;
|
var domain = uri.Host;
|
||||||
|
|
||||||
// Remote post
|
// Remote post
|
||||||
if (domain != Domain) return await db.Posts.FirstOrDefaultAsync(c => c.FediverseUri == objectUri);
|
if (domain != Domain) return await db.Posts.FirstOrDefaultAsync(c => c.FediverseUri == objectUri);
|
||||||
|
|
||||||
// Local post, extract ID from path like /posts/{guid}
|
// Local post, extract ID from path like /posts/{guid}
|
||||||
var path = uri.AbsolutePath.Trim('/');
|
var path = uri.AbsolutePath.Trim('/');
|
||||||
var segments = path.Split('/');
|
var segments = path.Split('/');
|
||||||
@@ -39,36 +39,37 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> HandleIncomingActivityAsync(
|
public async Task<bool> HandleIncomingActivityAsync(
|
||||||
HttpContext context,
|
HttpContext context,
|
||||||
string username,
|
string username,
|
||||||
Dictionary<string, object> activity
|
Dictionary<string, object> activity
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
logger.LogInformation("Incoming activity request. Username: {Username}, Path: {Path}",
|
logger.LogInformation("Incoming activity request. Username: {Username}, Path: {Path}",
|
||||||
username, context.Request.Path);
|
username, context.Request.Path);
|
||||||
|
|
||||||
var activityType = activity.GetValueOrDefault("type")?.ToString();
|
var activityType = activity.GetValueOrDefault("type")?.ToString();
|
||||||
var activityId = activity.GetValueOrDefault("id")?.ToString();
|
var activityId = activity.GetValueOrDefault("id")?.ToString();
|
||||||
var actor = activity.GetValueOrDefault("actor")?.ToString();
|
var actor = activity.GetValueOrDefault("actor")?.ToString();
|
||||||
|
|
||||||
logger.LogInformation("Activity details - Type: {Type}, ID: {Id}, Actor: {Actor}",
|
logger.LogInformation("Activity details - Type: {Type}, ID: {Id}, Actor: {Actor}",
|
||||||
activityType, activityId, actor);
|
activityType, activityId, actor);
|
||||||
|
|
||||||
if (!signatureService.VerifyIncomingRequest(context, out var actorUri))
|
if (!signatureService.VerifyIncomingRequest(context, out var actorUri))
|
||||||
{
|
{
|
||||||
logger.LogWarning("Failed to verify signature for incoming activity. Type: {Type}, From: {Actor}",
|
logger.LogWarning("Failed to verify signature for incoming activity. Type: {Type}, From: {Actor}",
|
||||||
activityType, actor);
|
activityType, actor);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(actorUri))
|
if (string.IsNullOrEmpty(actorUri))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
logger.LogInformation("Signature verified successfully. Handling {Type} from {ActorUri}",
|
logger.LogInformation("Signature verified successfully. Handling {Type} from {ActorUri}",
|
||||||
activityType, actorUri);
|
activityType, actorUri);
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -111,60 +112,44 @@ public class ActivityPubActivityHandler(
|
|||||||
{
|
{
|
||||||
var objectUri = activity.GetValueOrDefault("object")?.ToString();
|
var objectUri = activity.GetValueOrDefault("object")?.ToString();
|
||||||
var activityId = activity.GetValueOrDefault("id")?.ToString();
|
var activityId = activity.GetValueOrDefault("id")?.ToString();
|
||||||
|
|
||||||
logger.LogInformation("Handling Follow. Actor: {ActorUri}, Target: {ObjectUri}, ActivityId: {Id}",
|
logger.LogInformation("Handling Follow. Actor: {ActorUri}, Target: {ObjectUri}, ActivityId: {Id}",
|
||||||
actorUri, objectUri, activityId);
|
actorUri, objectUri, activityId);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(objectUri))
|
if (string.IsNullOrEmpty(objectUri))
|
||||||
{
|
{
|
||||||
logger.LogWarning("Follow activity missing object field");
|
logger.LogWarning("Follow activity missing object field");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var actor = await GetOrCreateActorAsync(actorUri);
|
|
||||||
var targetUsername = ExtractUsernameFromUri(objectUri);
|
|
||||||
var targetPublisher = await db.Publishers
|
|
||||||
.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);
|
var actor = await GetOrCreateActorAsync(actorUri);
|
||||||
if (localActor == null)
|
// This might be fail, but we assume it works great.
|
||||||
{
|
var targetActor = await GetOrCreateActorAsync(objectUri);
|
||||||
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 ?? ""
|
||||||
);
|
);
|
||||||
@@ -192,9 +177,9 @@ public class ActivityPubActivityHandler(
|
|||||||
var objectUri = activity.GetValueOrDefault("object")?.ToString();
|
var objectUri = activity.GetValueOrDefault("object")?.ToString();
|
||||||
if (string.IsNullOrEmpty(objectUri))
|
if (string.IsNullOrEmpty(objectUri))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var actor = await GetOrCreateActorAsync(actorUri);
|
var actor = await GetOrCreateActorAsync(actorUri);
|
||||||
|
|
||||||
var relationship = await db.FediverseRelationships
|
var relationship = await db.FediverseRelationships
|
||||||
.Include(r => r.Actor)
|
.Include(r => r.Actor)
|
||||||
.Include(r => r.TargetActor)
|
.Include(r => r.TargetActor)
|
||||||
@@ -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,
|
||||||
@@ -226,7 +212,7 @@ public class ActivityPubActivityHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
logger.LogInformation("Handled accept from {Actor}", actorUri);
|
logger.LogInformation("Handled accept from {Actor}", actorUri);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -236,24 +222,24 @@ public class ActivityPubActivityHandler(
|
|||||||
var objectUri = activity.GetValueOrDefault("object")?.ToString();
|
var objectUri = activity.GetValueOrDefault("object")?.ToString();
|
||||||
if (string.IsNullOrEmpty(objectUri))
|
if (string.IsNullOrEmpty(objectUri))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var actor = await GetOrCreateActorAsync(actorUri);
|
var actor = await GetOrCreateActorAsync(actorUri);
|
||||||
|
|
||||||
var relationship = await db.FediverseRelationships
|
var relationship = await db.FediverseRelationships
|
||||||
.FirstOrDefaultAsync(r =>
|
.FirstOrDefaultAsync(r =>
|
||||||
r.TargetActorId == actor.Id);
|
r.TargetActorId == actor.Id);
|
||||||
|
|
||||||
if (relationship == null)
|
if (relationship == null)
|
||||||
{
|
{
|
||||||
logger.LogWarning("No relationship found for reject");
|
logger.LogWarning("No relationship found for reject");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
relationship.State = RelationshipState.Rejected;
|
relationship.State = RelationshipState.Rejected;
|
||||||
relationship.RejectReason = "Remote rejected follow";
|
relationship.RejectReason = "Remote rejected follow";
|
||||||
|
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
logger.LogInformation("Handled reject from {Actor}", actorUri);
|
logger.LogInformation("Handled reject from {Actor}", actorUri);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -278,37 +264,41 @@ public class ActivityPubActivityHandler(
|
|||||||
var objectValue = activity.GetValueOrDefault("object");
|
var objectValue = activity.GetValueOrDefault("object");
|
||||||
if (objectValue is not Dictionary<string, object> objectDict)
|
if (objectValue is not Dictionary<string, object> objectDict)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var objectType = objectDict.GetValueOrDefault("type")?.ToString();
|
var objectType = objectDict.GetValueOrDefault("type")?.ToString();
|
||||||
if (objectType != "Note" && objectType != "Article")
|
if (objectType != "Note" && objectType != "Article")
|
||||||
{
|
{
|
||||||
logger.LogInformation("Skipping non-note content type: {Type}", objectType);
|
logger.LogInformation("Skipping non-note content type: {Type}", objectType);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var actor = await GetOrCreateActorAsync(actorUri);
|
var actor = await GetOrCreateActorAsync(actorUri);
|
||||||
|
|
||||||
var contentUri = objectDict.GetValueOrDefault("id")?.ToString();
|
var contentUri = objectDict.GetValueOrDefault("id")?.ToString();
|
||||||
if (string.IsNullOrEmpty(contentUri))
|
if (string.IsNullOrEmpty(contentUri))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var existingContent = await db.Posts
|
var existingContent = await db.Posts
|
||||||
.FirstOrDefaultAsync(c => c.FediverseUri == contentUri);
|
.FirstOrDefaultAsync(c => c.FediverseUri == contentUri);
|
||||||
|
|
||||||
if (existingContent != null)
|
if (existingContent != null)
|
||||||
{
|
{
|
||||||
logger.LogInformation("Content already exists: {Uri}", contentUri);
|
logger.LogInformation("Content already exists: {Uri}", contentUri);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
@@ -319,10 +309,10 @@ public class ActivityPubActivityHandler(
|
|||||||
Visibility = PostVisibility.Public,
|
Visibility = PostVisibility.Public,
|
||||||
Metadata = BuildMetadataFromActivity(objectDict)
|
Metadata = BuildMetadataFromActivity(objectDict)
|
||||||
};
|
};
|
||||||
|
|
||||||
db.Posts.Add(content);
|
db.Posts.Add(content);
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
logger.LogInformation("Created federated content: {Uri}", contentUri);
|
logger.LogInformation("Created federated content: {Uri}", contentUri);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -341,19 +331,19 @@ public class ActivityPubActivityHandler(
|
|||||||
logger.LogWarning("Content not found for like: {Uri}", objectUri);
|
logger.LogWarning("Content not found for like: {Uri}", objectUri);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var existingReaction = await db.PostReactions
|
var existingReaction = await db.PostReactions
|
||||||
.FirstOrDefaultAsync(r =>
|
.FirstOrDefaultAsync(r =>
|
||||||
r.ActorId == actor.Id &&
|
r.ActorId == actor.Id &&
|
||||||
r.PostId == content.Id &&
|
r.PostId == content.Id &&
|
||||||
r.Symbol == "thumb_up");
|
r.Symbol == "thumb_up");
|
||||||
|
|
||||||
if (existingReaction != null)
|
if (existingReaction != null)
|
||||||
{
|
{
|
||||||
logger.LogInformation("Like already exists");
|
logger.LogInformation("Like already exists");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var reaction = new SnPostReaction
|
var reaction = new SnPostReaction
|
||||||
{
|
{
|
||||||
FediverseUri = activity.GetValueOrDefault("id")?.ToString() ?? Guid.NewGuid().ToString(),
|
FediverseUri = activity.GetValueOrDefault("id")?.ToString() ?? Guid.NewGuid().ToString(),
|
||||||
@@ -366,12 +356,12 @@ public class ActivityPubActivityHandler(
|
|||||||
CreatedAt = SystemClock.Instance.GetCurrentInstant(),
|
CreatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||||
UpdatedAt = SystemClock.Instance.GetCurrentInstant()
|
UpdatedAt = SystemClock.Instance.GetCurrentInstant()
|
||||||
};
|
};
|
||||||
|
|
||||||
db.PostReactions.Add(reaction);
|
db.PostReactions.Add(reaction);
|
||||||
content.Upvotes++;
|
content.Upvotes++;
|
||||||
|
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
logger.LogInformation("Handled like from {Actor}", actorUri);
|
logger.LogInformation("Handled like from {Actor}", actorUri);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -437,10 +427,10 @@ public class ActivityPubActivityHandler(
|
|||||||
logger.LogInformation("Undid follow relationship failed, no target actor uri provided.");
|
logger.LogInformation("Undid follow relationship failed, no target actor uri provided.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var actor = await GetOrCreateActorAsync(actorUri);
|
var actor = await GetOrCreateActorAsync(actorUri);
|
||||||
var targetActor = await GetOrCreateActorAsync(targetActorUri);
|
var targetActor = await GetOrCreateActorAsync(targetActorUri);
|
||||||
|
|
||||||
var relationship = await db.FediverseRelationships
|
var relationship = await db.FediverseRelationships
|
||||||
.FirstOrDefaultAsync(r => r.ActorId == actor.Id && r.TargetActorId == targetActor.Id);
|
.FirstOrDefaultAsync(r => r.ActorId == actor.Id && r.TargetActorId == targetActor.Id);
|
||||||
|
|
||||||
@@ -499,23 +489,22 @@ 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);
|
||||||
|
actor = new SnFediverseActor
|
||||||
{
|
{
|
||||||
var instance = await GetOrCreateInstanceAsync(actorUri);
|
Uri = actorUri,
|
||||||
actor = new SnFediverseActor
|
Username = ExtractUsernameFromUri(actorUri),
|
||||||
{
|
DisplayName = ExtractUsernameFromUri(actorUri),
|
||||||
Uri = actorUri,
|
InstanceId = instance.Id
|
||||||
Username = ExtractUsernameFromUri(actorUri),
|
};
|
||||||
DisplayName = ExtractUsernameFromUri(actorUri),
|
db.FediverseActors.Add(actor);
|
||||||
InstanceId = instance.Id
|
await db.SaveChangesAsync();
|
||||||
};
|
|
||||||
db.FediverseActors.Add(actor);
|
await discoveryService.FetchActorDataAsync(actor);
|
||||||
await db.SaveChangesAsync();
|
|
||||||
|
|
||||||
await discoveryService.FetchActorDataAsync(actor);
|
|
||||||
}
|
|
||||||
|
|
||||||
return actor;
|
return actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,7 +513,7 @@ public class ActivityPubActivityHandler(
|
|||||||
var domain = ExtractDomainFromUri(actorUri);
|
var domain = ExtractDomainFromUri(actorUri);
|
||||||
var instance = await db.FediverseInstances
|
var instance = await db.FediverseInstances
|
||||||
.FirstOrDefaultAsync(i => i.Domain == domain);
|
.FirstOrDefaultAsync(i => i.Domain == domain);
|
||||||
|
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
{
|
{
|
||||||
instance = new SnFediverseInstance
|
instance = new SnFediverseInstance
|
||||||
@@ -536,7 +525,7 @@ public class ActivityPubActivityHandler(
|
|||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
await discoveryService.FetchInstanceMetadataAsync(instance);
|
await discoveryService.FetchInstanceMetadataAsync(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,13 +544,13 @@ public class ActivityPubActivityHandler(
|
|||||||
{
|
{
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (value is Instant instant)
|
if (value is Instant instant)
|
||||||
return instant;
|
return instant;
|
||||||
|
|
||||||
if (DateTimeOffset.TryParse(value.ToString(), out var dateTimeOffset))
|
if (DateTimeOffset.TryParse(value.ToString(), out var dateTimeOffset))
|
||||||
return Instant.FromDateTimeOffset(dateTimeOffset);
|
return Instant.FromDateTimeOffset(dateTimeOffset);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,4 +635,4 @@ public class ActivityPubActivityHandler(
|
|||||||
|
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user