@evanp/activitypub-bot 0.22.0 → 0.24.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/README.md +18 -0
- package/bin/activitypub-bot.js +19 -3
- package/lib/bots/relayclient.js +46 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -97,6 +97,24 @@ The path to the [config file](#config-file) for this server, which defines the u
|
|
|
97
97
|
|
|
98
98
|
Falls back to `BOTS_CONFIG_FILE` environment variable. The default is to use the shipped default bot config file, which defines an [OKBot](#okbot) named `ok` and a [DoNothingBot](#donothingbot) named `null`.
|
|
99
99
|
|
|
100
|
+
#### --delivery
|
|
101
|
+
|
|
102
|
+
The number of background delivery workers to run for this server. These workers accept and process remote activities that arrive at the server. If the server has a lot of traffic, and it's taking a while for bots to do their thing, increase this number.
|
|
103
|
+
|
|
104
|
+
Falls back to the `DELIVERY` environment variable. Default is 2.
|
|
105
|
+
|
|
106
|
+
#### --distribution
|
|
107
|
+
|
|
108
|
+
The number of background distribution workers to run for this server. These workers distribute bot activities to followers and other recipients on remote servers. If it's taking a while for bot activities to get to their recipients, increase this number.
|
|
109
|
+
|
|
110
|
+
Falls back to the `DISTRIBUTION` environment variable. Default is 8.
|
|
111
|
+
|
|
112
|
+
#### --index-file
|
|
113
|
+
|
|
114
|
+
Path to the HTML file to show for the home page of your server. The activitypub.bot server doesn't support any other files, so any images or CSS stylesheets or JavaScript in this page have to be hosted elsewhere. Or just skip them!
|
|
115
|
+
|
|
116
|
+
Falls back to the 'INDEX_FILE' environment variable. The default index file is in `web/index.html` and just says that this is an activitypub.bot server with a link to the GitHub repo.
|
|
117
|
+
|
|
100
118
|
### Config file
|
|
101
119
|
|
|
102
120
|
The config file defines the bots provided by this server.
|
package/bin/activitypub-bot.js
CHANGED
|
@@ -12,6 +12,9 @@ const { values } = parseArgs({
|
|
|
12
12
|
port: { type: 'string' },
|
|
13
13
|
'bots-config-file': { type: 'string' },
|
|
14
14
|
'log-level': { type: 'string' },
|
|
15
|
+
delivery: { type: 'string' },
|
|
16
|
+
distribution: { type: 'string' },
|
|
17
|
+
'index-file': { type: 'string' },
|
|
15
18
|
help: { type: 'boolean', short: 'h' }
|
|
16
19
|
},
|
|
17
20
|
allowPositionals: false
|
|
@@ -26,13 +29,16 @@ Options:
|
|
|
26
29
|
--port <number> Port to listen on
|
|
27
30
|
--bots-config-file <path> Path to bots config module
|
|
28
31
|
--log-level <level> Log level (e.g., info, debug)
|
|
32
|
+
--delivery <number> Number of background delivery workers
|
|
33
|
+
--distribution <number> Number of background distribution workers
|
|
34
|
+
--index-file <path> HTML page to show at root path
|
|
29
35
|
-h, --help Show this help
|
|
30
36
|
`)
|
|
31
37
|
process.exit(0)
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
const normalize = (value) => (value === '' ? undefined : value)
|
|
35
|
-
const
|
|
41
|
+
const parseNumber = (value) => {
|
|
36
42
|
if (!value) return undefined
|
|
37
43
|
const parsed = Number.parseInt(value, 10)
|
|
38
44
|
return Number.isNaN(parsed) ? undefined : parsed
|
|
@@ -40,21 +46,31 @@ const parsePort = (value) => {
|
|
|
40
46
|
|
|
41
47
|
const baseDir = dirname(fileURLToPath(import.meta.url))
|
|
42
48
|
const DEFAULT_BOTS_CONFIG_FILE = resolve(baseDir, '..', 'bots', 'index.js')
|
|
49
|
+
const DEFAULT_INDEX_FILE = resolve(baseDir, '..', 'web', 'index.html')
|
|
43
50
|
|
|
44
51
|
const DATABASE_URL = normalize(values['database-url']) || process.env.DATABASE_URL || 'sqlite::memory:'
|
|
45
52
|
const ORIGIN = normalize(values.origin) || process.env.ORIGIN || 'https://activitypubbot.test'
|
|
46
|
-
const PORT =
|
|
53
|
+
const PORT = parseNumber(normalize(values.port)) || parseNumber(process.env.PORT) || 9000 // HAL
|
|
47
54
|
const BOTS_CONFIG_FILE =
|
|
48
55
|
normalize(values['bots-config-file']) || process.env.BOTS_CONFIG_FILE || DEFAULT_BOTS_CONFIG_FILE
|
|
49
56
|
const LOG_LEVEL =
|
|
50
57
|
normalize(values['log-level']) ||
|
|
51
58
|
process.env.LOG_LEVEL ||
|
|
52
59
|
(process.env.NODE_ENV === 'test' ? 'silent' : 'info')
|
|
60
|
+
const DELIVERY = parseNumber(values.delivery) || parseNumber(process.env.DELIVERY) || 2
|
|
61
|
+
const DISTRIBUTION = parseNumber(values.distribution) || parseNumber(process.env.DISTRIBUTION) || 8
|
|
62
|
+
const INDEX_FILE = values['index-file'] || process.env.INDEX_FILE || DEFAULT_INDEX_FILE
|
|
53
63
|
|
|
54
64
|
const bots = (await import(BOTS_CONFIG_FILE)).default
|
|
55
65
|
|
|
56
66
|
const app = await makeApp({
|
|
57
|
-
databaseUrl: DATABASE_URL,
|
|
67
|
+
databaseUrl: DATABASE_URL,
|
|
68
|
+
origin: ORIGIN,
|
|
69
|
+
bots,
|
|
70
|
+
logLevel: LOG_LEVEL,
|
|
71
|
+
deliveryWorkerCount: DELIVERY,
|
|
72
|
+
distributionWorkerCount: DISTRIBUTION,
|
|
73
|
+
indexFileName: INDEX_FILE
|
|
58
74
|
})
|
|
59
75
|
|
|
60
76
|
const server = app.listen(parseInt(PORT), () => {
|
package/lib/bots/relayclient.js
CHANGED
|
@@ -2,10 +2,12 @@ import Bot from '../bot.js'
|
|
|
2
2
|
|
|
3
3
|
export default class RelayClientBot extends Bot {
|
|
4
4
|
#relay
|
|
5
|
+
#unsubscribe
|
|
5
6
|
|
|
6
|
-
constructor (username, relay) {
|
|
7
|
+
constructor (username, relay, unsubscribe = null) {
|
|
7
8
|
super(username)
|
|
8
9
|
this.#relay = relay
|
|
10
|
+
this.#unsubscribe = !!unsubscribe
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
get fullname () {
|
|
@@ -18,21 +20,61 @@ export default class RelayClientBot extends Bot {
|
|
|
18
20
|
|
|
19
21
|
async initialize (context) {
|
|
20
22
|
super.initialize(context)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
this._context.logger.debug(
|
|
24
|
+
{ relay: this.#relay, unsubscribe: this.#unsubscribe },
|
|
25
|
+
'Initialising relay client'
|
|
26
|
+
)
|
|
27
|
+
if (this.#unsubscribe) {
|
|
28
|
+
if (await this._context.hasData(`follow:${this.#relay}`)) {
|
|
29
|
+
await this.#unfollowRelay()
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
if (!(await this._context.hasData(`follow:${this.#relay}`))) {
|
|
33
|
+
await this.#followRelay()
|
|
34
|
+
}
|
|
23
35
|
}
|
|
24
36
|
}
|
|
25
37
|
|
|
26
38
|
async #followRelay () {
|
|
39
|
+
this._context.logger.debug(
|
|
40
|
+
{ relay: this.#relay },
|
|
41
|
+
'Following relay'
|
|
42
|
+
)
|
|
27
43
|
const activity = await this._context.doActivity({
|
|
28
44
|
to: this.#relay,
|
|
29
45
|
type: 'Follow',
|
|
30
46
|
object: 'https://www.w3.org/ns/activitystreams#Public'
|
|
31
47
|
})
|
|
48
|
+
this._context.logger.debug(
|
|
49
|
+
{ relay: this.#relay, activity: activity.id },
|
|
50
|
+
'Saving follow for later'
|
|
51
|
+
)
|
|
32
52
|
this._context.setData(`follow:${this.#relay}`, activity.id)
|
|
33
53
|
}
|
|
34
54
|
|
|
55
|
+
async #unfollowRelay () {
|
|
56
|
+
const activityId = await this._context.getData(`follow:${this.#relay}`)
|
|
57
|
+
this._context.logger.debug(
|
|
58
|
+
{ relay: this.#relay, activity: activityId },
|
|
59
|
+
'Unfollowing relay'
|
|
60
|
+
)
|
|
61
|
+
await this._context.doActivity({
|
|
62
|
+
to: this.#relay,
|
|
63
|
+
type: 'Undo',
|
|
64
|
+
object: {
|
|
65
|
+
id: activityId,
|
|
66
|
+
type: 'Follow',
|
|
67
|
+
object: 'https://www.w3.org/ns/activitystreams#Public'
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
this._context.logger.debug(
|
|
71
|
+
{ relay: this.#relay },
|
|
72
|
+
'Clearing follow data'
|
|
73
|
+
)
|
|
74
|
+
this._context.setData(`follow:${this.#relay}`, null)
|
|
75
|
+
}
|
|
76
|
+
|
|
35
77
|
async actorOK (actorId, activity) {
|
|
36
|
-
return (actorId === this.#relay)
|
|
78
|
+
return (actorId === this.#relay && !this.#unsubscribe)
|
|
37
79
|
}
|
|
38
80
|
}
|