thelounge-plugin-ntfy 1.3.0 → 1.4.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 +8 -4
- package/index.js +96 -3
- package/package.json +1 -1
- package/src/config.js +102 -9
- package/src/handler.js +10 -3
package/README.md
CHANGED
|
@@ -24,8 +24,10 @@ This plugin introduces the `/ntfy` command, subcommands are:
|
|
|
24
24
|
- `/ntfy status`: Show the ntfy listener status for this network
|
|
25
25
|
- `/ntfy test`: Send a test notification
|
|
26
26
|
- `/ntfy config`: Config commands
|
|
27
|
-
- `/ntfy config set <setting_key> <setting_value>`: Set a configuration setting
|
|
28
|
-
- `/ntfy config remove <setting_key>`: Set a configuration setting to null
|
|
27
|
+
- `/ntfy config set <setting_key> <setting_value>`: Set a global configuration setting
|
|
28
|
+
- `/ntfy config remove <setting_key>`: Set a global configuration setting to null
|
|
29
|
+
- `/ntfy config network set <setting_key> <setting_value>`: Set a per-network setting for this network
|
|
30
|
+
- `/ntfy config network remove <setting_key>`: Remove per-network setting for this network
|
|
29
31
|
- `/ntfy config print`: Print the current configuration with warnings if any
|
|
30
32
|
|
|
31
33
|
## Setup
|
|
@@ -46,12 +48,14 @@ To start/stop sending push notifications in the desired network, enter:
|
|
|
46
48
|
|
|
47
49
|
## Private Messages
|
|
48
50
|
|
|
49
|
-
By default, you will only be notified when you are mentioned, **this includes messages sent privately to you**. If you want to be notified of all private messages, enter this command and start the notifier like usual:
|
|
51
|
+
By default, you will only be notified when you are mentioned, **this includes messages sent privately to you**. If you want to be notified of all private messages on a specific network, enter this command while connected to that network and start the notifier like usual:
|
|
50
52
|
|
|
51
53
|
```
|
|
52
|
-
/ntfy config set config.notify_on_private_messages true
|
|
54
|
+
/ntfy config network set config.notify_on_private_messages true
|
|
53
55
|
```
|
|
54
56
|
|
|
57
|
+
This setting is per-network, so you can enable it for some networks and disable it for others.
|
|
58
|
+
|
|
55
59
|
## License
|
|
56
60
|
|
|
57
61
|
This plugin is licensed under [MIT](https://opensource.org/license/mit)
|
package/index.js
CHANGED
|
@@ -6,6 +6,8 @@ const {
|
|
|
6
6
|
setRootDir,
|
|
7
7
|
loadUserConfig,
|
|
8
8
|
saveUserSetting,
|
|
9
|
+
saveNetworkSetting,
|
|
10
|
+
PER_NETWORK_KEYS,
|
|
9
11
|
} = require("./src/config.js");
|
|
10
12
|
|
|
11
13
|
// user -> Map<network.uuid -> handler and client>
|
|
@@ -26,10 +28,16 @@ const ntfyCommand = {
|
|
|
26
28
|
);
|
|
27
29
|
say(`/${command} test - Send a test notification`);
|
|
28
30
|
say(
|
|
29
|
-
`/${command} config set <setting_key> <setting_value> - Set a configuration setting`,
|
|
31
|
+
`/${command} config set <setting_key> <setting_value> - Set a global configuration setting`,
|
|
30
32
|
);
|
|
31
33
|
say(
|
|
32
|
-
`/${command} config remove <setting_key> - Set configuration setting to null`,
|
|
34
|
+
`/${command} config remove <setting_key> - Set global configuration setting to null`,
|
|
35
|
+
);
|
|
36
|
+
say(
|
|
37
|
+
`/${command} config network set <setting_key> <setting_value> - Set a per-network setting for this network`,
|
|
38
|
+
);
|
|
39
|
+
say(
|
|
40
|
+
`/${command} config network remove <setting_key> - Remove per-network setting for this network`,
|
|
33
41
|
);
|
|
34
42
|
say(
|
|
35
43
|
`/${command} config print - Print the current configuration with warnings if any`,
|
|
@@ -229,13 +237,26 @@ const ntfyCommand = {
|
|
|
229
237
|
const [userConfig, errors] = loadUserConfig(client.client.name);
|
|
230
238
|
|
|
231
239
|
const sensitiveKeys = new Set(["ntfy.password", "ntfy.token"]);
|
|
240
|
+
const perNetworkKeys = new Set([
|
|
241
|
+
"config.notify_on_private_messages",
|
|
242
|
+
]);
|
|
232
243
|
|
|
233
244
|
const printConfig = (obj, parentKey = "") => {
|
|
234
245
|
for (const key in obj) {
|
|
235
246
|
const value = obj[key];
|
|
236
247
|
const fullKey = parentKey ? `${parentKey}.${key}` : key;
|
|
237
248
|
|
|
238
|
-
if (
|
|
249
|
+
if (perNetworkKeys.has(fullKey)) {
|
|
250
|
+
// Special handling for per-network settings
|
|
251
|
+
if (typeof value === "object" && value !== null) {
|
|
252
|
+
const networkValue = value[network.uuid];
|
|
253
|
+
say(
|
|
254
|
+
`${fullKey}=${networkValue !== undefined ? networkValue : "(not set for this network)"}`,
|
|
255
|
+
);
|
|
256
|
+
} else {
|
|
257
|
+
say(`${fullKey}=(not set for this network)`);
|
|
258
|
+
}
|
|
259
|
+
} else if (typeof value === "object" && value !== null) {
|
|
239
260
|
printConfig(value, fullKey);
|
|
240
261
|
} else if (sensitiveKeys.has(fullKey) && value) {
|
|
241
262
|
say(`${fullKey}=********`);
|
|
@@ -268,6 +289,78 @@ const ntfyCommand = {
|
|
|
268
289
|
break;
|
|
269
290
|
}
|
|
270
291
|
|
|
292
|
+
case "network": {
|
|
293
|
+
const networkArgs = subsubcommand.slice(1);
|
|
294
|
+
|
|
295
|
+
if (networkArgs.length === 0) {
|
|
296
|
+
helpMessage();
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (typeof networkArgs[0] !== "string") {
|
|
301
|
+
helpMessage();
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
switch (networkArgs[0].toLowerCase()) {
|
|
306
|
+
case "set": {
|
|
307
|
+
const setArgs = networkArgs.slice(1);
|
|
308
|
+
|
|
309
|
+
if (setArgs.length < 2) {
|
|
310
|
+
say("Usage: /ntfy config network set <setting_key> <value>");
|
|
311
|
+
say(
|
|
312
|
+
`Available per-network settings: ${Array.from(PER_NETWORK_KEYS).join(", ")}`,
|
|
313
|
+
);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const settingKey = setArgs[0];
|
|
318
|
+
const settingValue = setArgs.slice(1).join(" ");
|
|
319
|
+
const response = saveNetworkSetting(
|
|
320
|
+
client.client.name,
|
|
321
|
+
settingKey,
|
|
322
|
+
network.uuid,
|
|
323
|
+
settingValue,
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
say(response);
|
|
327
|
+
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
case "remove": {
|
|
332
|
+
const removeArgs = networkArgs.slice(1);
|
|
333
|
+
|
|
334
|
+
if (removeArgs.length < 1) {
|
|
335
|
+
say("Usage: /ntfy config network remove <setting_key>");
|
|
336
|
+
say(
|
|
337
|
+
`Available per-network settings: ${Array.from(PER_NETWORK_KEYS).join(", ")}`,
|
|
338
|
+
);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const settingKey = removeArgs[0];
|
|
343
|
+
const response = saveNetworkSetting(
|
|
344
|
+
client.client.name,
|
|
345
|
+
settingKey,
|
|
346
|
+
network.uuid,
|
|
347
|
+
null,
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
say(response);
|
|
351
|
+
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
default: {
|
|
356
|
+
helpMessage();
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
|
|
271
364
|
default: {
|
|
272
365
|
helpMessage();
|
|
273
366
|
break;
|
package/package.json
CHANGED
package/src/config.js
CHANGED
|
@@ -21,20 +21,21 @@ const DEFAULT_CONFIG = {
|
|
|
21
21
|
token: null,
|
|
22
22
|
},
|
|
23
23
|
config: {
|
|
24
|
-
notify_on_private_messages: false
|
|
24
|
+
notify_on_private_messages: {}, // Per-network: { "network-uuid": true/false }
|
|
25
25
|
},
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
const
|
|
28
|
+
const GLOBAL_KEYS = new Set([
|
|
29
29
|
"ntfy.server",
|
|
30
30
|
"ntfy.topic",
|
|
31
31
|
"ntfy.username",
|
|
32
32
|
"ntfy.password",
|
|
33
33
|
"ntfy.token",
|
|
34
|
-
"config.notify_on_private_messages",
|
|
35
34
|
]);
|
|
35
|
+
const GLOBAL_BOOLEAN_KEYS = new Set([]);
|
|
36
36
|
|
|
37
|
-
const
|
|
37
|
+
const PER_NETWORK_KEYS = new Set(["config.notify_on_private_messages"]);
|
|
38
|
+
const PER_NETWORK_BOOLEAN_KEYS = new Set(["config.notify_on_private_messages"]);
|
|
38
39
|
|
|
39
40
|
const SENSITIVE_KEYS = new Set(["ntfy.password", "ntfy.token"]);
|
|
40
41
|
|
|
@@ -110,8 +111,9 @@ const userConfigSchema = {
|
|
|
110
111
|
required: ["notify_on_private_messages"],
|
|
111
112
|
properties: {
|
|
112
113
|
notify_on_private_messages: {
|
|
113
|
-
type: "
|
|
114
|
-
|
|
114
|
+
type: "object",
|
|
115
|
+
additionalProperties: { type: ["boolean", "string"] },
|
|
116
|
+
default: {},
|
|
115
117
|
},
|
|
116
118
|
},
|
|
117
119
|
},
|
|
@@ -227,7 +229,7 @@ function saveUserSetting(username, settingKey, settingValue) {
|
|
|
227
229
|
throw new Error("Root directory is not set");
|
|
228
230
|
}
|
|
229
231
|
|
|
230
|
-
if (
|
|
232
|
+
if (GLOBAL_KEYS.has(settingKey)) {
|
|
231
233
|
let userConfig = loadUserConfig(username)[0];
|
|
232
234
|
|
|
233
235
|
const keys = settingKey.split(".");
|
|
@@ -245,7 +247,7 @@ function saveUserSetting(username, settingKey, settingValue) {
|
|
|
245
247
|
return `Error: expected value to be a string`;
|
|
246
248
|
}
|
|
247
249
|
|
|
248
|
-
if (
|
|
250
|
+
if (GLOBAL_BOOLEAN_KEYS.has(settingKey)) {
|
|
249
251
|
try {
|
|
250
252
|
settingValue = settingValue
|
|
251
253
|
? JSON.parse(settingValue.toLowerCase())
|
|
@@ -276,12 +278,103 @@ function saveUserSetting(username, settingKey, settingValue) {
|
|
|
276
278
|
}
|
|
277
279
|
|
|
278
280
|
return `Invalid setting ${settingKey}, allowed settings are: ${Array.from(
|
|
279
|
-
|
|
281
|
+
GLOBAL_KEYS,
|
|
280
282
|
).join(", ")}`;
|
|
281
283
|
}
|
|
282
284
|
|
|
285
|
+
function saveNetworkSetting(username, settingKey, networkUuid, settingValue) {
|
|
286
|
+
if (!rootDir) {
|
|
287
|
+
throw new Error("Root directory is not set");
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (!PER_NETWORK_KEYS.has(settingKey)) {
|
|
291
|
+
return `Invalid per-network setting ${settingKey}, allowed settings are: ${Array.from(
|
|
292
|
+
PER_NETWORK_KEYS,
|
|
293
|
+
).join(", ")}`;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
let userConfig = loadUserConfig(username)[0];
|
|
297
|
+
|
|
298
|
+
const keys = settingKey.split(".");
|
|
299
|
+
|
|
300
|
+
let curr = userConfig;
|
|
301
|
+
|
|
302
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
303
|
+
const key = keys[i];
|
|
304
|
+
if (key in curr) {
|
|
305
|
+
curr = curr[key];
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const finalKey = keys[keys.length - 1];
|
|
310
|
+
|
|
311
|
+
if (!curr[finalKey] || typeof curr[finalKey] !== "object") {
|
|
312
|
+
curr[finalKey] = {};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (settingValue === null) {
|
|
316
|
+
delete curr[finalKey][networkUuid];
|
|
317
|
+
} else if (PER_NETWORK_BOOLEAN_KEYS.has(settingKey)) {
|
|
318
|
+
try {
|
|
319
|
+
const boolValue = JSON.parse(settingValue.toLowerCase());
|
|
320
|
+
|
|
321
|
+
if (typeof boolValue !== "boolean") {
|
|
322
|
+
return `Invalid value for ${settingKey}, expected a boolean`;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
curr[finalKey][networkUuid] = boolValue;
|
|
326
|
+
} catch {
|
|
327
|
+
return `Invalid value for ${settingKey}, expected a boolean (true/false)`;
|
|
328
|
+
}
|
|
329
|
+
} else {
|
|
330
|
+
curr[finalKey][networkUuid] = settingValue;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const configToSave = encryptSensitiveFields(userConfig);
|
|
334
|
+
|
|
335
|
+
const userConfigPath = path.join(rootDir, "config", `${username}.json`);
|
|
336
|
+
|
|
337
|
+
fs.mkdirSync(path.dirname(userConfigPath), { recursive: true });
|
|
338
|
+
fs.writeFileSync(
|
|
339
|
+
userConfigPath,
|
|
340
|
+
JSON.stringify(configToSave, null, 2),
|
|
341
|
+
"utf-8",
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
return "Success";
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function getNetworkSetting(
|
|
348
|
+
userConfig,
|
|
349
|
+
settingKey,
|
|
350
|
+
networkUuid,
|
|
351
|
+
defaultValue = false,
|
|
352
|
+
) {
|
|
353
|
+
const keys = settingKey.split(".");
|
|
354
|
+
|
|
355
|
+
let curr = userConfig;
|
|
356
|
+
|
|
357
|
+
for (const key of keys) {
|
|
358
|
+
if (curr && typeof curr === "object" && key in curr) {
|
|
359
|
+
curr = curr[key];
|
|
360
|
+
} else {
|
|
361
|
+
return defaultValue;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (curr && typeof curr === "object" && networkUuid in curr) {
|
|
366
|
+
return curr[networkUuid];
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return defaultValue;
|
|
370
|
+
}
|
|
371
|
+
|
|
283
372
|
module.exports = {
|
|
284
373
|
setRootDir,
|
|
285
374
|
loadUserConfig,
|
|
286
375
|
saveUserSetting,
|
|
376
|
+
saveNetworkSetting,
|
|
377
|
+
getNetworkSetting,
|
|
378
|
+
PER_NETWORK_KEYS,
|
|
379
|
+
PER_NETWORK_BOOLEAN_KEYS,
|
|
287
380
|
};
|
package/src/handler.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
const { loadUserConfig } = require("./config.js");
|
|
3
|
+
const { loadUserConfig, getNetworkSetting } = require("./config.js");
|
|
4
4
|
const { PluginLogger } = require("./logger.js");
|
|
5
5
|
|
|
6
6
|
function createHandler(client, network) {
|
|
@@ -23,7 +23,7 @@ function createHandler(client, network) {
|
|
|
23
23
|
// Mentions always notify
|
|
24
24
|
notify = true;
|
|
25
25
|
} else if (isPM) {
|
|
26
|
-
// PMs notify only if enabled in config
|
|
26
|
+
// PMs notify only if enabled in config for this network
|
|
27
27
|
const [uc, errors] = loadUserConfig(client.client.name);
|
|
28
28
|
|
|
29
29
|
if (errors.length > 0) {
|
|
@@ -32,7 +32,14 @@ function createHandler(client, network) {
|
|
|
32
32
|
|
|
33
33
|
userConfig = uc;
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
const notifyOnPMs = getNetworkSetting(
|
|
36
|
+
userConfig,
|
|
37
|
+
"config.notify_on_private_messages",
|
|
38
|
+
network.uuid,
|
|
39
|
+
false,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
if (notifyOnPMs) {
|
|
36
43
|
notify = true;
|
|
37
44
|
}
|
|
38
45
|
}
|