@evanp/activitypub-bot 0.48.1 → 0.49.0
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/CHANGELOG.md +11 -0
- package/lib/botcontext.js +4 -0
- package/lib/bots/mastodonrelayclient.js +48 -6
- package/lib/remoteobjectcache.js +1 -1
- package/lib/routes/nodeinfo.js +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,17 @@ and this project adheres to
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.49.0] - 2026-06-28
|
|
13
|
+
|
|
14
|
+
- New forceUnsubscribe argument for MastodonRelayClient, to force it
|
|
15
|
+
to unsubscribe unconditionally to an array of actors.
|
|
16
|
+
- Missing required `instance` property in /nodeinfo/2.2.
|
|
17
|
+
|
|
18
|
+
## [0.48.2] - 2026-06-04
|
|
19
|
+
|
|
20
|
+
- Immediate expiry for actors.
|
|
21
|
+
- Include required 'instance' property in nodeinfo 2.2.
|
|
22
|
+
|
|
12
23
|
## [0.48.1] - 2026-05-28
|
|
13
24
|
|
|
14
25
|
- 401 Unauthorized for authentication errors
|
package/lib/botcontext.js
CHANGED
|
@@ -10,7 +10,7 @@ const ANNOUNCE = `${NS}Announce`
|
|
|
10
10
|
export default class MastodonRelayClientBot extends Bot {
|
|
11
11
|
#relay
|
|
12
12
|
#relayForwarding
|
|
13
|
-
|
|
13
|
+
#forceUnsubscribe
|
|
14
14
|
constructor (username, options = {}) {
|
|
15
15
|
if (typeof username !== 'string') {
|
|
16
16
|
throw new Error('username must be a string')
|
|
@@ -29,6 +29,16 @@ export default class MastodonRelayClientBot extends Bot {
|
|
|
29
29
|
this.#relayForwarding = ('relayForwarding' in options)
|
|
30
30
|
? options.relayForwarding
|
|
31
31
|
: true
|
|
32
|
+
if (options.forceUnsubscribe) {
|
|
33
|
+
if (!Array.isArray(options.forceUnsubscribe)) {
|
|
34
|
+
throw new Error('forceUnsubscribe option must be an array')
|
|
35
|
+
}
|
|
36
|
+
const fus = new Set(options.forceUnsubscribe)
|
|
37
|
+
if (this.#relay.some(x => fus.has(x))) {
|
|
38
|
+
throw new Error('forceUnsubscribe option must not overlap with relay option')
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
this.#forceUnsubscribe = options.forceUnsubscribe || []
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
get type () {
|
|
@@ -50,6 +60,22 @@ export default class MastodonRelayClientBot extends Bot {
|
|
|
50
60
|
'Initialising relay client'
|
|
51
61
|
)
|
|
52
62
|
|
|
63
|
+
assert.ok(Array.isArray(this.#forceUnsubscribe))
|
|
64
|
+
|
|
65
|
+
for (const id of this.#forceUnsubscribe) {
|
|
66
|
+
const actor = await this._context.getObject(id)
|
|
67
|
+
if (actor) {
|
|
68
|
+
try {
|
|
69
|
+
await this.#unfollowRelay(actor)
|
|
70
|
+
} catch (err) {
|
|
71
|
+
this._context.logger.warn(
|
|
72
|
+
{ err, actorId: id },
|
|
73
|
+
'Error unfollowing actor; skipping'
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
53
79
|
assert.ok(Array.isArray(this.#relay))
|
|
54
80
|
|
|
55
81
|
const toFollow = new Set(this.#relay)
|
|
@@ -107,20 +133,36 @@ export default class MastodonRelayClientBot extends Bot {
|
|
|
107
133
|
}
|
|
108
134
|
|
|
109
135
|
async #unfollowRelay (actor) {
|
|
110
|
-
const activityId = await this.#getFollowActivity(actor)
|
|
111
136
|
this._context.logger.info(
|
|
112
|
-
{ relay: actor.id
|
|
137
|
+
{ relay: actor.id },
|
|
113
138
|
'Unfollowing relay'
|
|
114
139
|
)
|
|
115
|
-
|
|
140
|
+
let activityId
|
|
141
|
+
try {
|
|
142
|
+
activityId = await this.#getFollowActivity(actor)
|
|
143
|
+
this._context.logger.info(
|
|
144
|
+
{ relay: actor.id, activityId },
|
|
145
|
+
'Follow activity found when unfollowing relay'
|
|
146
|
+
)
|
|
147
|
+
} catch (err) {
|
|
148
|
+
this._context.logger.warn(
|
|
149
|
+
{ relay: actor.id },
|
|
150
|
+
'No follow activity found when unfollowing relay'
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
const undo = {
|
|
116
154
|
to: actor.id,
|
|
117
155
|
type: 'Undo',
|
|
118
156
|
object: {
|
|
119
|
-
id: activityId,
|
|
120
157
|
type: 'Follow',
|
|
158
|
+
actor: this._context.botActorId,
|
|
121
159
|
object: 'https://www.w3.org/ns/activitystreams#Public'
|
|
122
160
|
}
|
|
123
|
-
}
|
|
161
|
+
}
|
|
162
|
+
if (activityId) {
|
|
163
|
+
undo.object.id = activityId
|
|
164
|
+
}
|
|
165
|
+
await this._context.doActivity(undo)
|
|
124
166
|
this._context.logger.info(
|
|
125
167
|
{ relay: actor.id },
|
|
126
168
|
'Clearing follow data'
|
package/lib/remoteobjectcache.js
CHANGED
|
@@ -147,7 +147,7 @@ export class RemoteObjectCache {
|
|
|
147
147
|
if (as2obj.isActivity()) {
|
|
148
148
|
offset = 24 * 60 * 60 * 1000
|
|
149
149
|
} else if (as2obj.inbox) {
|
|
150
|
-
offset =
|
|
150
|
+
offset = -1000
|
|
151
151
|
} else if (KEY_TYPES.includes(as2obj.type)) {
|
|
152
152
|
offset = -1000
|
|
153
153
|
} else if (COLLECTION_TYPES.includes(as2obj.type)) {
|
package/lib/routes/nodeinfo.js
CHANGED