thelounge-plugin-ntfy 1.4.0 → 1.5.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 +3 -3
- package/index.js +182 -39
- package/package.json +1 -1
- package/src/config.js +22 -0
- package/src/handler.js +4 -4
package/README.md
CHANGED
|
@@ -19,9 +19,9 @@ Restart The Lounge after installation
|
|
|
19
19
|
|
|
20
20
|
This plugin introduces the `/ntfy` command, subcommands are:
|
|
21
21
|
|
|
22
|
-
- `/ntfy start`: Start the ntfy listener for the network
|
|
23
|
-
- `/ntfy stop`: Stop the ntfy listener for the network
|
|
24
|
-
- `/ntfy status`: Show the ntfy listener status for this network
|
|
22
|
+
- `/ntfy start [all]`: Start the ntfy listener for the network or all networks if 'all' is specified
|
|
23
|
+
- `/ntfy stop [all]`: Stop the ntfy listener for the network or all networks if 'all' is specified
|
|
24
|
+
- `/ntfy status [all]`: Show the ntfy listener status for this network or all networks if 'all' is specified
|
|
25
25
|
- `/ntfy test`: Send a test notification
|
|
26
26
|
- `/ntfy config`: Config commands
|
|
27
27
|
- `/ntfy config set <setting_key> <setting_value>`: Set a global configuration setting
|
package/index.js
CHANGED
|
@@ -21,10 +21,14 @@ const ntfyCommand = {
|
|
|
21
21
|
|
|
22
22
|
const helpMessage = () => {
|
|
23
23
|
say(`${command} command help:`);
|
|
24
|
-
say(`/${command} start - Start the ntfy listener for this network`);
|
|
25
|
-
say(`/${command} stop - Stop the ntfy listener for this network`);
|
|
26
24
|
say(
|
|
27
|
-
`/${command}
|
|
25
|
+
`/${command} start [all] - Start the ntfy listener for this network or all networks if 'all' is specified`,
|
|
26
|
+
);
|
|
27
|
+
say(
|
|
28
|
+
`/${command} stop [all] - Stop the ntfy listener for this network or all networks if 'all' is specified`,
|
|
29
|
+
);
|
|
30
|
+
say(
|
|
31
|
+
`/${command} status [all] - Show the ntfy listener status for this network or all networks if 'all' is specified`,
|
|
28
32
|
);
|
|
29
33
|
say(`/${command} test - Send a test notification`);
|
|
30
34
|
say(
|
|
@@ -59,82 +63,221 @@ const ntfyCommand = {
|
|
|
59
63
|
|
|
60
64
|
switch (subcommand[0].toLowerCase()) {
|
|
61
65
|
case "start": {
|
|
66
|
+
let all = false;
|
|
62
67
|
const [_, errors] = loadUserConfig(client.client.name);
|
|
68
|
+
const subsubcommand = subcommand.slice(1);
|
|
69
|
+
|
|
70
|
+
if (
|
|
71
|
+
typeof subsubcommand[0] === "string" &&
|
|
72
|
+
subsubcommand.length > 0 &&
|
|
73
|
+
subsubcommand[0].toLowerCase() === "all"
|
|
74
|
+
) {
|
|
75
|
+
all = true;
|
|
76
|
+
}
|
|
63
77
|
|
|
64
78
|
if (errors.length > 0) {
|
|
65
|
-
say(
|
|
79
|
+
say(
|
|
80
|
+
`Cannot start ntfy listener${all ? "s" : ""} due to invalid configuration:`,
|
|
81
|
+
);
|
|
82
|
+
|
|
66
83
|
for (const error of errors) {
|
|
67
84
|
say(`- ${error.instancePath} ${error.message}`);
|
|
68
85
|
}
|
|
86
|
+
|
|
69
87
|
return;
|
|
70
88
|
}
|
|
71
89
|
|
|
72
90
|
const userListeners = globalActiveListeners.get(client.client.name);
|
|
73
91
|
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
if (all) {
|
|
93
|
+
const networks = client.client.networks;
|
|
94
|
+
let started = 0;
|
|
95
|
+
let skipped = 0;
|
|
96
|
+
|
|
97
|
+
for (const net of networks) {
|
|
98
|
+
if (
|
|
99
|
+
userListeners &&
|
|
100
|
+
typeof userListeners.has === "function" &&
|
|
101
|
+
userListeners.has(net.uuid)
|
|
102
|
+
) {
|
|
103
|
+
skipped++;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const handler = createHandler(client, net);
|
|
108
|
+
net.irc.on("privmsg", handler);
|
|
109
|
+
|
|
110
|
+
if (!userListeners) {
|
|
111
|
+
const map = new Map();
|
|
112
|
+
map.set(net.uuid, { handler: handler, client: client });
|
|
113
|
+
globalActiveListeners.set(client.client.name, map);
|
|
114
|
+
} else {
|
|
115
|
+
userListeners.set(net.uuid, {
|
|
116
|
+
handler: handler,
|
|
117
|
+
client: client,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
82
120
|
|
|
83
|
-
|
|
84
|
-
|
|
121
|
+
started++;
|
|
122
|
+
}
|
|
85
123
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
124
|
+
if (started === 0 && skipped === 0) {
|
|
125
|
+
say("No networks available to start ntfy listeners");
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (started > 0) {
|
|
129
|
+
say(
|
|
130
|
+
`Started ntfy listener${started !== 1 ? "s" : ""} for ${started} network${started !== 1 ? "s" : ""}`,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
if (skipped > 0) {
|
|
134
|
+
say(
|
|
135
|
+
`Skipped ${skipped} network${skipped !== 1 ? "s" : ""} because ntfy listener is already running`,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
90
138
|
} else {
|
|
91
|
-
|
|
92
|
-
|
|
139
|
+
if (
|
|
140
|
+
userListeners &&
|
|
141
|
+
typeof userListeners.has === "function" &&
|
|
142
|
+
userListeners.has(network.uuid)
|
|
143
|
+
) {
|
|
144
|
+
say("ntfy listener is already running for this network");
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const handler = createHandler(client, network);
|
|
149
|
+
network.irc.on("privmsg", handler);
|
|
150
|
+
|
|
151
|
+
if (!userListeners) {
|
|
152
|
+
const map = new Map();
|
|
153
|
+
map.set(network.uuid, { handler: handler, client: client });
|
|
154
|
+
globalActiveListeners.set(client.client.name, map);
|
|
155
|
+
} else {
|
|
156
|
+
userListeners.set(network.uuid, {
|
|
157
|
+
handler: handler,
|
|
158
|
+
client: client,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
93
161
|
|
|
94
|
-
|
|
162
|
+
say("ntfy listener started for this network");
|
|
163
|
+
}
|
|
95
164
|
|
|
96
165
|
break;
|
|
97
166
|
}
|
|
98
167
|
|
|
99
168
|
case "stop": {
|
|
100
|
-
|
|
169
|
+
let all = false;
|
|
170
|
+
const subsubcommand = subcommand.slice(1);
|
|
101
171
|
|
|
102
172
|
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
173
|
+
typeof subsubcommand[0] === "string" &&
|
|
174
|
+
subsubcommand.length > 0 &&
|
|
175
|
+
subsubcommand[0].toLowerCase() === "all"
|
|
106
176
|
) {
|
|
107
|
-
|
|
108
|
-
return;
|
|
177
|
+
all = true;
|
|
109
178
|
}
|
|
110
179
|
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
180
|
+
const userListeners = globalActiveListeners.get(client.client.name);
|
|
181
|
+
|
|
182
|
+
if (all) {
|
|
183
|
+
const networks = client.client.networks;
|
|
184
|
+
let stopped = 0;
|
|
185
|
+
let skipped = 0;
|
|
186
|
+
|
|
187
|
+
for (const net of networks) {
|
|
188
|
+
if (
|
|
189
|
+
!userListeners ||
|
|
190
|
+
typeof userListeners.has !== "function" ||
|
|
191
|
+
!userListeners.has(net.uuid)
|
|
192
|
+
) {
|
|
193
|
+
skipped++;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const { handler } = userListeners.get(net.uuid);
|
|
198
|
+
net.irc.removeListener("privmsg", handler);
|
|
199
|
+
userListeners.delete(net.uuid);
|
|
200
|
+
stopped++;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (stopped === 0 && skipped === 0) {
|
|
204
|
+
say("No networks available to stop ntfy listeners");
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (stopped > 0) {
|
|
208
|
+
say(
|
|
209
|
+
`Stopped ntfy listener${stopped !== 1 ? "s" : ""} for ${stopped} network${stopped !== 1 ? "s" : ""}`,
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
if (skipped > 0) {
|
|
213
|
+
say(
|
|
214
|
+
`Skipped ${skipped} network${skipped !== 1 ? "s" : ""} because ntfy listener was not running`,
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
} else {
|
|
218
|
+
if (
|
|
219
|
+
!userListeners ||
|
|
220
|
+
typeof userListeners.has !== "function" ||
|
|
221
|
+
!userListeners.has(network.uuid)
|
|
222
|
+
) {
|
|
223
|
+
say("ntfy listener is not running for this network");
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const { handler } = userListeners.get(network.uuid);
|
|
228
|
+
network.irc.removeListener("privmsg", handler);
|
|
229
|
+
userListeners.delete(network.uuid);
|
|
114
230
|
|
|
115
|
-
|
|
231
|
+
say("ntfy listener stopped for this network");
|
|
232
|
+
}
|
|
116
233
|
|
|
117
234
|
break;
|
|
118
235
|
}
|
|
119
236
|
|
|
120
237
|
case "status": {
|
|
121
|
-
|
|
238
|
+
let all = false;
|
|
239
|
+
const subsubcommand = subcommand.slice(1);
|
|
122
240
|
|
|
123
241
|
if (
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
242
|
+
typeof subsubcommand[0] === "string" &&
|
|
243
|
+
subsubcommand.length > 0 &&
|
|
244
|
+
subsubcommand[0].toLowerCase() === "all"
|
|
127
245
|
) {
|
|
128
|
-
|
|
246
|
+
all = true;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const userListeners = globalActiveListeners.get(client.client.name);
|
|
250
|
+
|
|
251
|
+
if (all) {
|
|
252
|
+
const networks = client.client.networks;
|
|
253
|
+
for (const net of networks) {
|
|
254
|
+
if (
|
|
255
|
+
userListeners &&
|
|
256
|
+
typeof userListeners.has === "function" &&
|
|
257
|
+
userListeners.has(net.uuid)
|
|
258
|
+
) {
|
|
259
|
+
say(`${net.name}: running`);
|
|
260
|
+
} else {
|
|
261
|
+
say(`${net.name}: not running`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
129
264
|
} else {
|
|
130
|
-
|
|
265
|
+
if (
|
|
266
|
+
userListeners &&
|
|
267
|
+
typeof userListeners.has === "function" &&
|
|
268
|
+
userListeners.has(network.uuid)
|
|
269
|
+
) {
|
|
270
|
+
say("ntfy listener is running for this network");
|
|
271
|
+
} else {
|
|
272
|
+
say("ntfy listener is not running for this network");
|
|
273
|
+
}
|
|
131
274
|
}
|
|
132
275
|
|
|
133
276
|
break;
|
|
134
277
|
}
|
|
135
278
|
|
|
136
279
|
case "test": {
|
|
137
|
-
const { NtfyClient
|
|
280
|
+
const { NtfyClient } = await import("ntfy");
|
|
138
281
|
|
|
139
282
|
const [userConfig, errors] = loadUserConfig(client.client.name);
|
|
140
283
|
|
|
@@ -160,7 +303,7 @@ const ntfyCommand = {
|
|
|
160
303
|
const ntfyClient = new NtfyClient({
|
|
161
304
|
server: userConfig.ntfy.server,
|
|
162
305
|
topic: userConfig.ntfy.topic,
|
|
163
|
-
priority:
|
|
306
|
+
priority: userConfig.ntfy.priority,
|
|
164
307
|
tags: ["speech_balloon"],
|
|
165
308
|
authorization: ntfyAuth,
|
|
166
309
|
});
|
package/package.json
CHANGED
package/src/config.js
CHANGED
|
@@ -19,6 +19,7 @@ const DEFAULT_CONFIG = {
|
|
|
19
19
|
username: null,
|
|
20
20
|
password: null,
|
|
21
21
|
token: null,
|
|
22
|
+
priority: 3,
|
|
22
23
|
},
|
|
23
24
|
config: {
|
|
24
25
|
notify_on_private_messages: {}, // Per-network: { "network-uuid": true/false }
|
|
@@ -31,8 +32,10 @@ const GLOBAL_KEYS = new Set([
|
|
|
31
32
|
"ntfy.username",
|
|
32
33
|
"ntfy.password",
|
|
33
34
|
"ntfy.token",
|
|
35
|
+
"ntfy.priority",
|
|
34
36
|
]);
|
|
35
37
|
const GLOBAL_BOOLEAN_KEYS = new Set([]);
|
|
38
|
+
const GLOBAL_NUMERIC_KEYS = new Set(["ntfy.priority"]);
|
|
36
39
|
|
|
37
40
|
const PER_NETWORK_KEYS = new Set(["config.notify_on_private_messages"]);
|
|
38
41
|
const PER_NETWORK_BOOLEAN_KEYS = new Set(["config.notify_on_private_messages"]);
|
|
@@ -67,6 +70,13 @@ const userConfigSchema = {
|
|
|
67
70
|
nullable: true,
|
|
68
71
|
errorMessage: "Invalid ntfy token, must start with 'tk_'",
|
|
69
72
|
},
|
|
73
|
+
priority: {
|
|
74
|
+
type: "integer",
|
|
75
|
+
minimum: 1,
|
|
76
|
+
maximum: 5,
|
|
77
|
+
default: 3,
|
|
78
|
+
errorMessage: "Priority must be an integer between 1 and 5",
|
|
79
|
+
},
|
|
70
80
|
},
|
|
71
81
|
allOf: [
|
|
72
82
|
{
|
|
@@ -261,6 +271,18 @@ function saveUserSetting(username, settingKey, settingValue) {
|
|
|
261
271
|
}
|
|
262
272
|
}
|
|
263
273
|
|
|
274
|
+
if (GLOBAL_NUMERIC_KEYS.has(settingKey)) {
|
|
275
|
+
try {
|
|
276
|
+
settingValue = settingValue ? Number(settingValue) : NaN;
|
|
277
|
+
|
|
278
|
+
if (isNaN(settingValue) || typeof settingValue !== "number") {
|
|
279
|
+
return `Invalid value for ${settingKey}, expected a number`;
|
|
280
|
+
}
|
|
281
|
+
} catch {
|
|
282
|
+
return `Invalid value for ${settingKey}, expected a number`;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
264
286
|
curr[keys[keys.length - 1]] = settingValue;
|
|
265
287
|
|
|
266
288
|
const configToSave = encryptSensitiveFields(userConfig);
|
package/src/handler.js
CHANGED
|
@@ -19,8 +19,8 @@ function createHandler(client, network) {
|
|
|
19
19
|
let notify = false;
|
|
20
20
|
let userConfig;
|
|
21
21
|
|
|
22
|
-
if (mentioned) {
|
|
23
|
-
// Mentions always notify
|
|
22
|
+
if (mentioned && !isPM) {
|
|
23
|
+
// Mentions always notify in channels
|
|
24
24
|
notify = true;
|
|
25
25
|
} else if (isPM) {
|
|
26
26
|
// PMs notify only if enabled in config for this network
|
|
@@ -71,12 +71,12 @@ function createHandler(client, network) {
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
const { NtfyClient
|
|
74
|
+
const { NtfyClient } = await import("ntfy");
|
|
75
75
|
|
|
76
76
|
const ntfyClient = new NtfyClient({
|
|
77
77
|
server: userConfig.ntfy.server,
|
|
78
78
|
topic: userConfig.ntfy.topic,
|
|
79
|
-
priority:
|
|
79
|
+
priority: userConfig.ntfy.priority,
|
|
80
80
|
tags: ["speech_balloon"],
|
|
81
81
|
authorization: ntfyAuth,
|
|
82
82
|
});
|