@evanp/activitypub-bot 0.20.1 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/activitydeliverer.js +44 -6
- package/lib/botcontext.js +5 -3
- package/lib/bots/relayserver.js +1 -1
- package/lib/routes/inbox.js +4 -0
- package/package.json +1 -1
package/lib/activitydeliverer.js
CHANGED
|
@@ -2,6 +2,10 @@ import BotMaker from './botmaker.js'
|
|
|
2
2
|
import assert from 'node:assert'
|
|
3
3
|
import as2 from './activitystreams.js'
|
|
4
4
|
import PQueue from 'p-queue'
|
|
5
|
+
import * as ttlcachePkg from '@isaacs/ttlcache'
|
|
6
|
+
|
|
7
|
+
const TTLCache =
|
|
8
|
+
ttlcachePkg.TTLCache ?? ttlcachePkg.default ?? ttlcachePkg
|
|
5
9
|
|
|
6
10
|
const NS = 'https://www.w3.org/ns/activitystreams#'
|
|
7
11
|
|
|
@@ -19,7 +23,8 @@ const COLLECTION_TYPES = [
|
|
|
19
23
|
export class ActivityDeliverer {
|
|
20
24
|
static #MAX_ALL_QUEUE = 16
|
|
21
25
|
static #MAX_BOT_QUEUE = 32
|
|
22
|
-
|
|
26
|
+
static #TTL_SEEN_PUBLIC = 3 * 24 * 60 * 60 * 1000 // 3 days
|
|
27
|
+
static #MAX_SEEN_PUBLIC = 1000000
|
|
23
28
|
#actorStorage
|
|
24
29
|
#activityHandler
|
|
25
30
|
#formatter
|
|
@@ -27,6 +32,7 @@ export class ActivityDeliverer {
|
|
|
27
32
|
#client
|
|
28
33
|
#deliverAllQueue
|
|
29
34
|
#deliverBotQueue
|
|
35
|
+
#seenPublic
|
|
30
36
|
|
|
31
37
|
constructor (actorStorage, activityHandler, formatter, logger, client) {
|
|
32
38
|
this.#actorStorage = actorStorage
|
|
@@ -36,6 +42,10 @@ export class ActivityDeliverer {
|
|
|
36
42
|
this.#logger = logger.child({ class: this.constructor.name })
|
|
37
43
|
this.#deliverAllQueue = new PQueue({ max: ActivityDeliverer.#MAX_ALL_QUEUE })
|
|
38
44
|
this.#deliverBotQueue = new PQueue({ max: ActivityDeliverer.#MAX_BOT_QUEUE })
|
|
45
|
+
this.#seenPublic = new TTLCache({
|
|
46
|
+
ttl: ActivityDeliverer.#TTL_SEEN_PUBLIC,
|
|
47
|
+
max: ActivityDeliverer.#MAX_SEEN_PUBLIC
|
|
48
|
+
})
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
getActor (activity) {
|
|
@@ -53,6 +63,38 @@ export class ActivityDeliverer {
|
|
|
53
63
|
return r
|
|
54
64
|
}
|
|
55
65
|
|
|
66
|
+
isPublic (activity) {
|
|
67
|
+
for (const prop of ['to', 'cc', 'audience']) {
|
|
68
|
+
const vals = activity.get(prop)
|
|
69
|
+
if (vals) {
|
|
70
|
+
for (const val of vals) {
|
|
71
|
+
if (this.#isPublic(val)) {
|
|
72
|
+
return true
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async deliverPublic (activity, bots) {
|
|
81
|
+
if (!this.#seenPublic.has(activity.id)) {
|
|
82
|
+
await Promise.all(Object.values(bots).map(async (bot) => {
|
|
83
|
+
let result
|
|
84
|
+
try {
|
|
85
|
+
result = await bot.onPublic(activity)
|
|
86
|
+
} catch (err) {
|
|
87
|
+
this.#logger.warn(
|
|
88
|
+
{ err, activity: activity.id, bot: bot.id },
|
|
89
|
+
'Error handling public activity for bot'
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
return result
|
|
93
|
+
}))
|
|
94
|
+
this.#seenPublic.set(activity.id, true)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
56
98
|
async deliverTo (activity, bot) {
|
|
57
99
|
this.#deliverBotQueue.add(() =>
|
|
58
100
|
this.#deliverTo(activity, bot)
|
|
@@ -99,7 +141,7 @@ export class ActivityDeliverer {
|
|
|
99
141
|
this.#logger.debug(`Checking recipient ${recipient.id}`)
|
|
100
142
|
if (this.#isPublic(recipient)) {
|
|
101
143
|
this.#logger.debug(`Public recipient for ${activity.id}`)
|
|
102
|
-
await this
|
|
144
|
+
await this.deliverPublic(activity, bots)
|
|
103
145
|
} else if (this.#isLocal(recipient)) {
|
|
104
146
|
this.#logger.debug(`Local recipient for ${activity.id}`)
|
|
105
147
|
const parts = this.#formatter.unformat(recipient.id)
|
|
@@ -242,10 +284,6 @@ export class ActivityDeliverer {
|
|
|
242
284
|
return !!recipient.inbox?.first?.id
|
|
243
285
|
}
|
|
244
286
|
|
|
245
|
-
async #deliverPublic (activity, bots) {
|
|
246
|
-
await Promise.all(Object.values(bots).map(bot => bot.onPublic(activity)))
|
|
247
|
-
}
|
|
248
|
-
|
|
249
287
|
async #deliverLocalFollowersCollection (activity, username, bots, deliveredTo) {
|
|
250
288
|
const id = this.#formatter.format({ username })
|
|
251
289
|
const followed = await as2.import({ id })
|
package/lib/botcontext.js
CHANGED
|
@@ -369,10 +369,12 @@ export class BotContext {
|
|
|
369
369
|
const owners = obj.attributedTo
|
|
370
370
|
? Array.from(obj.attributedTo).map((owner) => owner.id)
|
|
371
371
|
: Array.from(obj.actor).map((owner) => owner.id)
|
|
372
|
+
const summary = `${this.#botId} shared "${await this.#nameOf(obj)}"`
|
|
372
373
|
const activity = await this.#doActivity({
|
|
373
374
|
type: 'Announce',
|
|
374
|
-
summary
|
|
375
|
-
|
|
375
|
+
summary,
|
|
376
|
+
summaryMap: {
|
|
377
|
+
en: summary
|
|
376
378
|
},
|
|
377
379
|
object: obj.id,
|
|
378
380
|
to: [
|
|
@@ -380,7 +382,7 @@ export class BotContext {
|
|
|
380
382
|
username: this.#botId,
|
|
381
383
|
collection: 'followers'
|
|
382
384
|
}),
|
|
383
|
-
'
|
|
385
|
+
'as:Public'
|
|
384
386
|
],
|
|
385
387
|
cc: owners
|
|
386
388
|
})
|
package/lib/bots/relayserver.js
CHANGED
package/lib/routes/inbox.js
CHANGED
|
@@ -65,6 +65,10 @@ router.post('/user/:username/inbox', async (req, res, next) => {
|
|
|
65
65
|
|
|
66
66
|
await deliverer.deliverTo(activity, bot)
|
|
67
67
|
|
|
68
|
+
if (deliverer.isPublic(activity)) {
|
|
69
|
+
await deliverer.deliverPublic(activity, bots)
|
|
70
|
+
}
|
|
71
|
+
|
|
68
72
|
res.status(202)
|
|
69
73
|
res.type('text/plain')
|
|
70
74
|
res.send(http.STATUS_CODES[202])
|