Skip to content

Commit

Permalink
Refactored the sending of the Update activity
Browse files Browse the repository at this point in the history
ref https://linear.app/ghost/issue/AP-592

This just pulls out some shared logic into the update actor function, I'm not
100% on colocated storage and AP network code but I think it's fine for now
while we work the structure out.
  • Loading branch information
allouis committed Dec 16, 2024
1 parent cc33f7c commit 25a8bd1
Showing 1 changed file with 32 additions and 58 deletions.
90 changes: 32 additions & 58 deletions src/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,33 +571,15 @@ export async function getSiteDataHandler(

// This is to ensure that the actor exists - e.g. for a brand new a site
await getUserData(apCtx, handle);
const updated = await updateSiteActor(

await updateSiteActor(
ctx.get('db'),
ctx.get('globaldb'),
apCtx,
ctx.get('logger'),
host,
);

// Publish activity if the site settings have changed
if (updated) {
const actor = await apCtx.getActor(handle);

const update = new Update({
id: apCtx.getObjectUri(Update, { id: uuidv4() }),
actor: actor?.id,
to: PUBLIC_COLLECTION,
object: actor?.id,
cc: apCtx.getFollowersUri('index'),
});

await ctx
.get('globaldb')
.set([update.id!.href], await update.toJsonLd());

await apCtx.sendActivity({ handle }, 'followers', update, {
preferSharedInbox: true,
});
}

return new Response(JSON.stringify(site), {
status: 200,
headers: {
Expand All @@ -606,7 +588,13 @@ export async function getSiteDataHandler(
});
}

async function updateSiteActor(db: KvStore, logger: Logger, host: string) {
async function updateSiteActor(
db: KvStore,
globaldb: KvStore,
apCtx: RequestContext<ContextData>,
logger: Logger,
host: string,
) {
const settings = await getSiteSettings(host);
const handle = ACTOR_DEFAULT_HANDLE;

Expand All @@ -618,7 +606,7 @@ async function updateSiteActor(db: KvStore, logger: Logger, host: string) {
current.name === settings.site.title &&
current.summary === settings.site.description
) {
logger.info('No site settings changed, nothing to do');
logger.info('No site settings changed, not updating site actor');
return false;
}

Expand All @@ -632,63 +620,49 @@ async function updateSiteActor(db: KvStore, logger: Logger, host: string) {

await db.set(['handle', handle], updated);

const actor = await apCtx.getActor(handle);

const update = new Update({
id: apCtx.getObjectUri(Update, { id: uuidv4() }),
actor: actor?.id,
to: PUBLIC_COLLECTION,
object: actor?.id,
cc: apCtx.getFollowersUri('index'),
});

await globaldb.set([update.id!.href], await update.toJsonLd());

await apCtx.sendActivity({ handle }, 'followers', update, {
preferSharedInbox: true,
});

return true;
}

export async function siteChangedWebhook(
ctx: Context<{ Variables: HonoContextVariables }>,
next: Next,
) {
try {
// Retrieve site settings from Ghost
const host = ctx.req.header('host') || '';
const db = ctx.get('db');
const globaldb = ctx.get('globaldb');
const logger = ctx.get('logger');
const handle = ACTOR_DEFAULT_HANDLE;

const updated = await updateSiteActor(db, logger, host);

if (!updated) {
return new Response(JSON.stringify({}), {
headers: {
'Content-Type': 'application/activity+json',
},
status: 200,
});
}

logger.info('Site settings changed, will notify followers');

// Publish activity if the site settings have changed
const apCtx = fedify.createContext(ctx.req.raw as Request, {
db,
globaldb: ctx.get('globaldb'),
logger: logger,
});

const actor = await apCtx.getActor(handle);

const update = new Update({
id: apCtx.getObjectUri(Update, { id: uuidv4() }),
actor: actor?.id,
to: PUBLIC_COLLECTION,
object: actor?.id,
cc: apCtx.getFollowersUri('index'),
globaldb,
logger,
});

await ctx
.get('globaldb')
.set([update.id!.href], await update.toJsonLd());
await apCtx.sendActivity({ handle }, 'followers', update, {
preferSharedInbox: true,
});
await updateSiteActor(db, globaldb, apCtx, logger, host);
} catch (err) {
ctx.get('logger').error('Site changed webhook failed: {error}', {
error: err,
});
}

// Return 200 OK
return new Response(JSON.stringify({}), {
headers: {
'Content-Type': 'application/activity+json',
Expand Down

0 comments on commit 25a8bd1

Please sign in to comment.