Skip to content

Commit

Permalink
Added handler for incoming likes (#33)
Browse files Browse the repository at this point in the history
refs [AP-283](https://linear.app/tryghost/issue/AP-283/handle-incoming-likes)

Added handler for incoming likes that adds the like activity to the actors
inbox and persists any relevant data to the database.
  • Loading branch information
mike182uk authored Aug 28, 2024
1 parent adf2431 commit 188a1d7
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
10 changes: 10 additions & 0 deletions features/handle-like.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Feature: Like(Article)
We want to handle Like(Article) activities in the Inbox

Scenario: We recieve a Like(Article) activity from someone we follow
Given an Actor "Alice"
And an Actor "Bob"
And a "Create(Article)" Activity "A" by "Alice"
And a "Like(A)" Activity "L" by "Bob"
When "Bob" sends "L" to the Inbox
Then "L" is in our Inbox
14 changes: 14 additions & 0 deletions features/step_definitions/stepdefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ async function createActivity(activityType, object, actor, remote = true) {
actor: actor,
};
}

if (activityType === 'Like') {
return {
'@context': [
'https://www.w3.org/ns/activitystreams',
'https://w3id.org/security/data-integrity/v1',
],
'type': 'Like',
'id': 'http://wiremock:8080/like/1',
'to': 'as:Public',
'object': object,
actor: actor,
};
}
}

async function createActor(name = 'Test', remote = true) {
Expand Down
4 changes: 4 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
Update,
Announce,
Context,
Like,
} from '@fedify/fedify';
import { federation } from '@fedify/fedify/x/hono';
import { Hono, Context as HonoContext } from 'hono';
Expand Down Expand Up @@ -47,6 +48,7 @@ import {
createDispatcher,
updateDispatcher,
handleAnnounce,
handleLike
} from './dispatchers';

import { followAction, inboxHandler, postPublishedWebhook, siteChangedWebhook } from './handlers';
Expand Down Expand Up @@ -115,6 +117,8 @@ inboxListener
.on(Create, ensureCorrectContext(handleCreate))
.onError(inboxErrorHandler)
.on(Announce, ensureCorrectContext(handleAnnounce))
.onError(inboxErrorHandler)
.on(Like, ensureCorrectContext(handleLike))
.onError(inboxErrorHandler);

fedify
Expand Down
64 changes: 64 additions & 0 deletions src/dispatchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
Actor,
Object as APObject,
Recipient,
Like,
} from '@fedify/fedify';
import { v4 as uuidv4 } from 'uuid';
import { addToList } from './kv-helpers';
Expand Down Expand Up @@ -229,6 +230,69 @@ export async function handleAnnounce(
await addToList(ctx.data.db, ['inbox'], announce.id.href);
}

export async function handleLike(
ctx: Context<ContextData>,
like: Like,
) {
console.log('Handling Like');

// Validate like
if (!like.id) {
console.log('Invalid Like - no id');
return;
}

if (!like.objectId) {
console.log('Invalid Like - no object id');
return;
}

// Validate sender
const sender = await like.getActor(ctx);

if (sender === null || sender.id === null) {
console.log('Sender missing, exit early');
return;
}

// Lookup liked object - If not found in globalDb, perform network lookup
let object = null;
let existing = await ctx.data.globaldb.get([like.objectId.href]) ?? null;

if (!existing) {
console.log('Object not found in globalDb, performing network lookup');

object = await like.getObject();
}

// Validate object
if (!existing && !object) {
console.log('Invalid Like - could not find object');
return;
}

if (object && !object.id) {
console.log('Invalid Like - could not find object id');
return;
}

// Persist like
const likeJson = await like.toJsonLd();
ctx.data.globaldb.set([like.id.href], likeJson);

// Persist object if not already persisted
if (!existing && object && object.id) {
console.log('Storing object in globalDb');

const objectJson = await object.toJsonLd();

ctx.data.globaldb.set([object.id.href], objectJson);
}

// Add to inbox
await addToList(ctx.data.db, ['inbox'], like.id.href);
}

export async function inboxErrorHandler(
ctx: Context<ContextData>,
error: unknown,
Expand Down

0 comments on commit 188a1d7

Please sign in to comment.