Changeset fb6819d in Klonkt
- Timestamp:
- 06/29/2026 09:59:19 PM (2 months ago)
- Branches:
- main
- Children:
- f2796d3
- Parents:
- 7475ff3
- File:
-
- 1 edited
-
src/services/ActivityPubService.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
r7475ff3 rfb6819d 1500 1500 // reblog (matched on actor+object — no record of the original Announce needed). 1501 1501 const fanout = (kind === 'boost' || kind === 'unboost'); // also goes to our followers 1502 const followersCol = `${me}/followers`; 1503 // Address the original author in cc so their server (Mastodon, WordPress/ActivityPub, …) 1504 // attributes the boost to their post and notifies them — without this, a shared-inbox 1505 // receiver has nothing to route the Announce to. Non-fragment activity ids + a `published` 1506 // stamp keep us aligned with what Mastodon emits. 1507 const audience = authorUri ? [followersCol, authorUri] : [followersCol]; 1502 1508 let act; 1503 1509 if (kind === 'unboost' || kind === 'unlike') { … … 1507 1513 act = { 1508 1514 '@context': 'https://www.w3.org/ns/activitystreams', 1509 id: `${me} #undo-${Date.now()}-${rid()}`, type: 'Undo', actor: me,1510 object: { id: `${me} #${inner.toLowerCase()}-${Date.now()}-${rid()}`, type: inner, actor: me, object: targetNoteId },1515 id: `${me}/undo/${Date.now()}-${rid()}`, type: 'Undo', actor: me, 1516 object: { id: `${me}/${inner.toLowerCase()}/${Date.now()}-${rid()}`, type: inner, actor: me, object: targetNoteId }, 1511 1517 }; 1512 if (kind === 'unboost') { act.to = [PUBLIC]; act.cc = [`${me}/followers`]; }1518 if (kind === 'unboost') { act.to = [PUBLIC]; act.cc = audience; } 1513 1519 } else { 1514 1520 const type = kind === 'boost' ? 'Announce' : 'Like'; 1515 1521 act = { 1516 1522 '@context': 'https://www.w3.org/ns/activitystreams', 1517 id: `${me} #${type.toLowerCase()}-${Date.now()}-${rid()}`,1523 id: `${me}/${type.toLowerCase()}/${Date.now()}-${rid()}`, 1518 1524 type, actor: me, object: targetNoteId, 1519 1525 }; 1520 if (type === 'Announce') { act. to = [PUBLIC]; act.cc = [`${me}/followers`]; }1526 if (type === 'Announce') { act.published = new Date().toISOString(); act.to = [PUBLIC]; act.cc = audience; } 1521 1527 } 1522 1528 const inboxes = new Set(); 1523 if (authorUri) { const a = await fetchActor(authorUri).catch(() => null); if (a) inboxes.add((a.endpoints && a.endpoints.sharedInbox) || a.inbox); } 1529 // Author first, via their PERSONAL inbox (not the shared one) so a multi-user receiver 1530 // routes the Announce/Like to the right post unambiguously. 1531 if (authorUri) { const a = await fetchActor(authorUri).catch(() => null); if (a) inboxes.add(a.inbox || (a.endpoints && a.endpoints.sharedInbox)); } 1524 1532 if (fanout) { for (const f of fStmts().list.all(site.slug)) inboxes.add(f.shared_inbox || f.inbox); } 1525 let delivered = 0; 1526 for (const inbox of [...inboxes].filter(Boolean)) { try { const st = await deliver(inbox, act, `${me}#main-key`, keys.private_pem); if (st >= 200 && st < 300) delivered++; } catch { /* best-effort */ } } 1527 console.log('[AP]', kind, site.slug, '→', targetNoteId, 'delivered', delivered); 1528 return { ok: true, delivered }; 1533 // Queue each delivery (immediate attempt + backoff retries on failure via ap_delivery) 1534 // instead of a single fire-and-forget POST, so a transient hiccup at the receiver doesn't 1535 // silently lose the boost — same durability a new post (deliverCreate) already gets. 1536 let queued = 0; 1537 for (const inbox of [...inboxes].filter(Boolean)) { deliverWithRetry(site.slug, inbox, act, `${me}#main-key`, keys.private_pem); queued++; } 1538 console.log('[AP]', kind, site.slug, '→', targetNoteId, 'queued', queued, 'inbox(es)'); 1539 return { ok: true, delivered: queued }; 1529 1540 } 1530 1541
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)