@procedures/notify 0.55.2 → 0.56.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 +16 -0
- package/README.md +63 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/procedures.d.ts +1 -0
- package/dist/procedures.d.ts.map +1 -1
- package/dist/procedures.js +3 -1
- package/dist/procedures.js.map +1 -1
- package/dist/pushover-procedures.d.ts +20 -0
- package/dist/pushover-procedures.d.ts.map +1 -0
- package/dist/pushover-procedures.js +169 -0
- package/dist/pushover-procedures.js.map +1 -0
- package/dist/pushover.d.ts +247 -0
- package/dist/pushover.d.ts.map +1 -0
- package/dist/pushover.js +350 -0
- package/dist/pushover.js.map +1 -0
- package/package.json +18 -6
- package/src/index.ts +2 -0
- package/src/procedures.ts +3 -1
- package/src/pushover-procedures.ts +229 -0
- package/src/pushover.ts +530 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @procedures/notify
|
|
2
2
|
|
|
3
|
+
## 0.56.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7337fd4: `@procedures/notify` sends through Pushover. The change adds names and is backward compatible, so it is a patch.
|
|
8
|
+
|
|
9
|
+
- The new procedures are `notify.pushover.send`, `notify.pushover.receipt`, `notify.pushover.cancel`, `notify.pushover.validate` and `notify.pushover.limits`.
|
|
10
|
+
- `notify.pushover.send` with the priority `2` sends an emergency message. Pushover repeats it until the user acknowledges it, or until it expires.
|
|
11
|
+
- `notify.pushover.cancel` stops the repeats by a receipt, or by a tag. With a tag, a process that did not send the message can stop it.
|
|
12
|
+
- The procedures read the keys from `PUSHOVER_APP_TOKEN` and `PUSHOVER_USER_KEY`. Each variable name of `tokenEnv` and `userEnv` starts with `PUSHOVER_`.
|
|
13
|
+
- The new entry `./pushover` has pure request builders and extractors, and `callPushover`. The caller gives the fetch. The entry imports no Node built-in.
|
|
14
|
+
- A builder throws an error for input that Pushover refuses. An extractor gives each failure as a value with a `kind`, and does not throw.
|
|
15
|
+
- 13996cf: An automated dependency update changes the shipped files, so this PATCH ships them.
|
|
16
|
+
- Updated dependencies [13996cf]
|
|
17
|
+
- @procedures/client@0.56.0
|
|
18
|
+
|
|
3
19
|
## 0.55.2
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@procedures/notify)
|
|
4
4
|
|
|
5
|
-
Push notifications through ntfy (the public server or your own)
|
|
5
|
+
Push notifications through ntfy (the public server or your own) and through Pushover.
|
|
6
|
+
|
|
7
|
+
- With ntfy, each phone that subscribes to the topic gets the message.
|
|
8
|
+
- With Pushover, each device of the user gets the message. An emergency message repeats until the user acknowledges it.
|
|
6
9
|
|
|
7
10
|
## Install
|
|
8
11
|
|
|
@@ -16,7 +19,12 @@ A host registers the procedures with `createRegistry(notifyModule)`, or with `im
|
|
|
16
19
|
|
|
17
20
|
| Procedure | Effects | What it does |
|
|
18
21
|
| --- | --- | --- |
|
|
19
|
-
| `notify.send` | writes `network`, not destructive | Sends a notification with a title, a priority, tags and a tap address. |
|
|
22
|
+
| `notify.send` | writes `network`, not destructive | Sends a notification through ntfy with a title, a priority, tags and a tap address. |
|
|
23
|
+
| `notify.pushover.send` | writes `network`, not destructive | Sends a Pushover message. Priority `2` repeats until the user acknowledges it, and gives a receipt. |
|
|
24
|
+
| `notify.pushover.receipt` | reads `network` | Reads the receipt of an emergency message: acknowledged, the time, the device, expired. |
|
|
25
|
+
| `notify.pushover.cancel` | writes `network`, idempotent | Stops the repeats of an emergency message, by its receipt or by a tag. |
|
|
26
|
+
| `notify.pushover.validate` | reads `network` | Examines a user key and gives its devices. It sends no message. |
|
|
27
|
+
| `notify.pushover.limits` | reads `network` | Reads the monthly limit of messages of the application. |
|
|
20
28
|
|
|
21
29
|
## Example
|
|
22
30
|
|
|
@@ -29,3 +37,56 @@ await client.exec(["notify", "send"], { topic: "my-long-random-topic", title: "B
|
|
|
29
37
|
On the public server, anyone who knows a topic can read its messages. Use a long random topic name, and do not send private content. For a protected topic, `tokenEnv` names the environment variable with the access token.
|
|
30
38
|
|
|
31
39
|
The name starts with `NTFY_` or `NOTIFY_`, for example `NTFY_TOKEN`. The procedure refuses another name. The caller chooses the server, so another name lets it send a secret of the host, for example `GITHUB_TOKEN`, to its own server.
|
|
40
|
+
|
|
41
|
+
## Pushover
|
|
42
|
+
|
|
43
|
+
An emergency message has the priority `2`. Pushover repeats it each `retryMs` until the user acknowledges it, or until `expireMs` ends. The send gives a `receipt`. Then `notify.pushover.receipt` tells if the user acknowledged the message, and when.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
const sent = await client.exec(["notify", "pushover", "send"], {
|
|
47
|
+
message: "A test of the alerts",
|
|
48
|
+
priority: 2,
|
|
49
|
+
retryMs: 60_000,
|
|
50
|
+
expireMs: 3_600_000,
|
|
51
|
+
tags: ["test-1"],
|
|
52
|
+
});
|
|
53
|
+
await client.exec(["notify", "pushover", "cancel"], { tag: "test-1" });
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### The keys
|
|
57
|
+
|
|
58
|
+
The procedures read the API token from `PUSHOVER_APP_TOKEN` and the user key from `PUSHOVER_USER_KEY`. The input `user` can give the user key directly.
|
|
59
|
+
|
|
60
|
+
`tokenEnv` and `userEnv` can name other variables. Each name starts with `PUSHOVER_`, for example `PUSHOVER_APP_TOKEN_2`. The procedures refuse another name.
|
|
61
|
+
|
|
62
|
+
### The entry `./pushover`
|
|
63
|
+
|
|
64
|
+
`@procedures/notify/pushover` has pure functions. A browser can also use them.
|
|
65
|
+
|
|
66
|
+
- A request builder gives the URL, the method, the headers and the body of one call. It sends no request.
|
|
67
|
+
- An extractor reads the status, the headers and the body text of a response into a typed result.
|
|
68
|
+
- `callPushover` sends one request through the fetch that the caller gives, and reads the response with an extractor.
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import { callPushover, extractPushoverSent, pushoverSendRequest } from "@procedures/notify/pushover";
|
|
72
|
+
|
|
73
|
+
const request = pushoverSendRequest(token, {
|
|
74
|
+
user,
|
|
75
|
+
message: "A test of the alerts",
|
|
76
|
+
priority: 2,
|
|
77
|
+
emergency: { retryMs: 60_000, expireMs: 3_600_000, tags: ["test-1"] },
|
|
78
|
+
});
|
|
79
|
+
const sent = await callPushover(fetch, request, extractPushoverSent, { timeoutMs: 20_000 });
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
A request holds the API token. Do not log a request or its URL.
|
|
83
|
+
|
|
84
|
+
### Failures and pace
|
|
85
|
+
|
|
86
|
+
- A request builder throws an error when the input breaks a rule of the API. Pushover refuses such a request, and many refusals can block the address of the caller.
|
|
87
|
+
- An extractor and a procedure do not throw for a failure of Pushover. They give a value with `ok: false`, a `kind` and the `errors` of Pushover.
|
|
88
|
+
- The kinds are `network`, `timeout`, `server`, `rate-limited`, `auth` and `refused`.
|
|
89
|
+
- After `network`, `timeout` or `server`, wait `retryAfterMs` (5 seconds) or more. Then send the same request again.
|
|
90
|
+
- After `refused` or `auth`, do not send the same request again.
|
|
91
|
+
- After `rate-limited`, the application sent its messages of the month. Each send fails until `resetAt`.
|
|
92
|
+
- Read one receipt at most once in 5 seconds.
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC"}
|
package/dist/procedures.d.ts
CHANGED
|
@@ -9,5 +9,6 @@ import { type AnyProcedure } from "@procedures/client";
|
|
|
9
9
|
*/
|
|
10
10
|
export declare const NOTIFY_TOKEN_ENV: RegExp;
|
|
11
11
|
export declare const notifySendProcedure: AnyProcedure;
|
|
12
|
+
/** The procedures of the package: `notify.send` (ntfy) and the Pushover procedures. */
|
|
12
13
|
export declare const notifyProcedures: AnyProcedure[];
|
|
13
14
|
//# sourceMappingURL=procedures.d.ts.map
|
package/dist/procedures.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAmB,KAAK,YAAY,EAAyB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAmB,KAAK,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AAK/F;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAA0C,CAAC;AA2B1E,eAAO,MAAM,mBAAmB,EAAE,YAiBxB,CAAC;AAEX,uFAAuF;AACvF,eAAO,MAAM,gBAAgB,EAAE,YAAY,EAAiD,CAAC"}
|
package/dist/procedures.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { createProcedure } from "@procedures/client";
|
|
5
5
|
import * as z from "zod";
|
|
6
6
|
import { sendNotification } from "./notify.js";
|
|
7
|
+
import { pushoverProcedures } from "./pushover-procedures.js";
|
|
7
8
|
/**
|
|
8
9
|
* The names of the variables that `tokenEnv` of `notify.send` can name: `NTFY_` or `NOTIFY_`,
|
|
9
10
|
* then letters, digits and underscores (audit pass 2, O55). The caller chooses the server, so a
|
|
@@ -48,5 +49,6 @@ export const notifySendProcedure = createProcedure()
|
|
|
48
49
|
return { sent: true };
|
|
49
50
|
})
|
|
50
51
|
.build();
|
|
51
|
-
|
|
52
|
+
/** The procedures of the package: `notify.send` (ntfy) and the Pushover procedures. */
|
|
53
|
+
export const notifyProcedures = [notifySendProcedure, ...pushoverProcedures];
|
|
52
54
|
//# sourceMappingURL=procedures.js.map
|
package/dist/procedures.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"procedures.js","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAA4C,MAAM,oBAAoB,CAAC;AAC/F,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"procedures.js","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Pushover procedures of `@procedures/notify`: `notify.pushover.send`, `notify.pushover.receipt`,
|
|
3
|
+
* `notify.pushover.cancel`, `notify.pushover.validate` and `notify.pushover.limits`.
|
|
4
|
+
*
|
|
5
|
+
* Each procedure reads the API token from an environment variable, not from its input. Each one
|
|
6
|
+
* gives the result of its extractor: a failure is a value with `ok: false`, not an error.
|
|
7
|
+
*/
|
|
8
|
+
import { type AnyProcedure } from "@procedures/client";
|
|
9
|
+
/**
|
|
10
|
+
* The names of the variables that `tokenEnv` and `userEnv` can name: `PUSHOVER_`, then capital
|
|
11
|
+
* letters, digits and underscores. Thus a caller cannot send another secret of the host to Pushover.
|
|
12
|
+
*/
|
|
13
|
+
export declare const PUSHOVER_ENV: RegExp;
|
|
14
|
+
export declare const pushoverSendProcedure: AnyProcedure;
|
|
15
|
+
export declare const pushoverReceiptProcedure: AnyProcedure;
|
|
16
|
+
export declare const pushoverCancelProcedure: AnyProcedure;
|
|
17
|
+
export declare const pushoverValidateProcedure: AnyProcedure;
|
|
18
|
+
export declare const pushoverLimitsProcedure: AnyProcedure;
|
|
19
|
+
export declare const pushoverProcedures: AnyProcedure[];
|
|
20
|
+
//# sourceMappingURL=pushover-procedures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pushover-procedures.d.ts","sourceRoot":"","sources":["../src/pushover-procedures.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAmB,KAAK,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AAyB/F;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,MAAgC,CAAC;AAwD5D,eAAO,MAAM,qBAAqB,EAAE,YAiC1B,CAAC;AAQX,eAAO,MAAM,wBAAwB,EAAE,YAa7B,CAAC;AAWX,eAAO,MAAM,uBAAuB,EAAE,YAgB5B,CAAC;AAUX,eAAO,MAAM,yBAAyB,EAAE,YAkB9B,CAAC;AAKX,eAAO,MAAM,uBAAuB,EAAE,YAa5B,CAAC;AAEX,eAAO,MAAM,kBAAkB,EAAE,YAAY,EAM5C,CAAC"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Pushover procedures of `@procedures/notify`: `notify.pushover.send`, `notify.pushover.receipt`,
|
|
3
|
+
* `notify.pushover.cancel`, `notify.pushover.validate` and `notify.pushover.limits`.
|
|
4
|
+
*
|
|
5
|
+
* Each procedure reads the API token from an environment variable, not from its input. Each one
|
|
6
|
+
* gives the result of its extractor: a failure is a value with `ok: false`, not an error.
|
|
7
|
+
*/
|
|
8
|
+
import { createProcedure } from "@procedures/client";
|
|
9
|
+
import * as z from "zod";
|
|
10
|
+
import { PUSHOVER_EXPIRE_MAX_MS, PUSHOVER_KEY as KEY, PUSHOVER_LIMITS, PUSHOVER_RETRY_MIN_MS, callPushover, extractPushoverCancelled, extractPushoverLimits, extractPushoverReceipt, extractPushoverSent, extractPushoverValidated, pushoverCancelByTagRequest, pushoverCancelRequest, pushoverLimitsRequest, pushoverReceiptRequest, pushoverSendRequest, pushoverValidateRequest, } from "./pushover.js";
|
|
11
|
+
/**
|
|
12
|
+
* The names of the variables that `tokenEnv` and `userEnv` can name: `PUSHOVER_`, then capital
|
|
13
|
+
* letters, digits and underscores. Thus a caller cannot send another secret of the host to Pushover.
|
|
14
|
+
*/
|
|
15
|
+
export const PUSHOVER_ENV = /^PUSHOVER_[A-Z0-9_]+$/;
|
|
16
|
+
const envName = (fallback, what) => z
|
|
17
|
+
.string()
|
|
18
|
+
.regex(PUSHOVER_ENV, `${what} names a variable that starts with PUSHOVER_, for example ${fallback}`)
|
|
19
|
+
.default(fallback)
|
|
20
|
+
.describe(`The name of the environment variable with the ${what === "tokenEnv" ? "API token of the application" : "user key"} (default: ${fallback})`);
|
|
21
|
+
const common = {
|
|
22
|
+
tokenEnv: envName("PUSHOVER_APP_TOKEN", "tokenEnv"),
|
|
23
|
+
timeoutMs: z.number().int().positive().max(120_000).default(20_000).describe("The time limit, in milliseconds (default: 20000)"),
|
|
24
|
+
};
|
|
25
|
+
/** A result of a Pushover procedure: `ok`, and the fields of the success or of the failure. */
|
|
26
|
+
const ResultSchema = z.looseObject({ ok: z.boolean() });
|
|
27
|
+
function secret(name) {
|
|
28
|
+
const value = process.env[name]?.trim();
|
|
29
|
+
if (!value)
|
|
30
|
+
throw new Error(`Set the environment variable ${name}`);
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
async function call(request, extract, timeoutMs, ctx) {
|
|
34
|
+
return (await callPushover(fetch, request, extract, { timeoutMs, signal: ctx?.signal }));
|
|
35
|
+
}
|
|
36
|
+
const SendInputSchema = z.object({
|
|
37
|
+
user: z.string().optional().describe("The user key or the group key of the recipient. Without it, the procedure reads userEnv."),
|
|
38
|
+
userEnv: envName("PUSHOVER_USER_KEY", "userEnv"),
|
|
39
|
+
message: z.string().min(1).describe(`The text, ${PUSHOVER_LIMITS.message} characters at most`),
|
|
40
|
+
title: z.string().optional().describe(`The title, ${PUSHOVER_LIMITS.title} characters at most`),
|
|
41
|
+
url: z.string().optional().describe("An address that the notification opens"),
|
|
42
|
+
urlTitle: z.string().optional().describe("The text of the address"),
|
|
43
|
+
priority: z
|
|
44
|
+
.union([z.literal(-2), z.literal(-1), z.literal(0), z.literal(1), z.literal(2)])
|
|
45
|
+
.default(0)
|
|
46
|
+
.describe("-2 no notification, -1 no sound, 0 normal, 1 high, 2 emergency: it repeats until acknowledged (default: 0)"),
|
|
47
|
+
retryMs: z.number().int().min(PUSHOVER_RETRY_MIN_MS).optional().describe("Priority 2: the time between two repeats, 30000 or more"),
|
|
48
|
+
expireMs: z.number().int().positive().max(PUSHOVER_EXPIRE_MAX_MS).optional().describe("Priority 2: the time after which the repeats stop, 10800000 at most"),
|
|
49
|
+
callback: z.url().optional().describe("Priority 2: an address that gets a POST when the user acknowledges"),
|
|
50
|
+
tags: z.array(z.string().min(1)).max(20).optional().describe("Priority 2: tags, for notify.pushover.cancel with tag"),
|
|
51
|
+
sound: z.string().optional().describe("The name of a sound"),
|
|
52
|
+
devices: z.array(z.string()).optional().describe("The names of the devices that get the message (default: each device)"),
|
|
53
|
+
format: z.enum(["text", "html", "monospace"]).default("text").describe("The format of the text (default: text)"),
|
|
54
|
+
ttlMs: z.number().int().min(1000).optional().describe("The time after which the device deletes the message. Priority 2 ignores it."),
|
|
55
|
+
...common,
|
|
56
|
+
});
|
|
57
|
+
export const pushoverSendProcedure = createProcedure()
|
|
58
|
+
.path(["notify", "pushover", "send"])
|
|
59
|
+
.input(SendInputSchema)
|
|
60
|
+
.output(ResultSchema)
|
|
61
|
+
.meta({
|
|
62
|
+
description: "Send a Pushover message. Priority 2 repeats until the user acknowledges it, and gives a receipt.",
|
|
63
|
+
args: ["message"],
|
|
64
|
+
output: "json",
|
|
65
|
+
// It adds a message and deletes nothing. A second call sends a second message.
|
|
66
|
+
effects: { reads: [], writes: ["network"], destructive: false },
|
|
67
|
+
})
|
|
68
|
+
.handler(async (input, ctx) => {
|
|
69
|
+
const priority = input.priority;
|
|
70
|
+
if (priority === 2 && (input.retryMs === undefined || input.expireMs === undefined))
|
|
71
|
+
throw new Error("Priority 2 needs retryMs and expireMs");
|
|
72
|
+
const user = input.user ?? secret(input.userEnv);
|
|
73
|
+
const request = pushoverSendRequest(secret(input.tokenEnv), {
|
|
74
|
+
user,
|
|
75
|
+
message: input.message,
|
|
76
|
+
title: input.title,
|
|
77
|
+
url: input.url,
|
|
78
|
+
urlTitle: input.urlTitle,
|
|
79
|
+
priority,
|
|
80
|
+
emergency: priority === 2 && input.retryMs !== undefined && input.expireMs !== undefined
|
|
81
|
+
? { retryMs: input.retryMs, expireMs: input.expireMs, callback: input.callback, tags: input.tags }
|
|
82
|
+
: undefined,
|
|
83
|
+
sound: input.sound,
|
|
84
|
+
devices: input.devices,
|
|
85
|
+
format: input.format,
|
|
86
|
+
ttlMs: input.ttlMs,
|
|
87
|
+
});
|
|
88
|
+
return call(request, extractPushoverSent, input.timeoutMs, ctx);
|
|
89
|
+
})
|
|
90
|
+
.build();
|
|
91
|
+
const ReceiptInputSchema = z.object({
|
|
92
|
+
receipt: z.string().regex(KEY, "A receipt is 30 letters and digits").describe("The receipt of an emergency message"),
|
|
93
|
+
...common,
|
|
94
|
+
});
|
|
95
|
+
export const pushoverReceiptProcedure = createProcedure()
|
|
96
|
+
.path(["notify", "pushover", "receipt"])
|
|
97
|
+
.input(ReceiptInputSchema)
|
|
98
|
+
.output(ResultSchema)
|
|
99
|
+
.meta({
|
|
100
|
+
description: "Read the receipt of a Pushover emergency message: acknowledged, by which device, expired. Read it at most once in 5 s.",
|
|
101
|
+
args: ["receipt"],
|
|
102
|
+
output: "json",
|
|
103
|
+
effects: { reads: ["network"], writes: [], destructive: false },
|
|
104
|
+
})
|
|
105
|
+
.handler(async (input, ctx) => call(pushoverReceiptRequest(secret(input.tokenEnv), input.receipt), extractPushoverReceipt, input.timeoutMs, ctx))
|
|
106
|
+
.build();
|
|
107
|
+
const CancelInputSchema = z
|
|
108
|
+
.object({
|
|
109
|
+
receipt: z.string().regex(KEY, "A receipt is 30 letters and digits").optional().describe("The receipt of the message to stop"),
|
|
110
|
+
tag: z.string().min(1).optional().describe("Stop each emergency message of the application with this tag"),
|
|
111
|
+
...common,
|
|
112
|
+
})
|
|
113
|
+
.refine((input) => (input.receipt === undefined) !== (input.tag === undefined), { message: "Give receipt or tag, not both" });
|
|
114
|
+
export const pushoverCancelProcedure = createProcedure()
|
|
115
|
+
.path(["notify", "pushover", "cancel"])
|
|
116
|
+
.input(CancelInputSchema)
|
|
117
|
+
.output(ResultSchema)
|
|
118
|
+
.meta({
|
|
119
|
+
description: "Stop the repeats of a Pushover emergency message, by its receipt or by a tag",
|
|
120
|
+
args: [],
|
|
121
|
+
output: "json",
|
|
122
|
+
// It stops the repeats and deletes no message. A second cancel has no effect.
|
|
123
|
+
effects: { reads: [], writes: ["network"], destructive: false, idempotent: true },
|
|
124
|
+
})
|
|
125
|
+
.handler(async (input, ctx) => {
|
|
126
|
+
const token = secret(input.tokenEnv);
|
|
127
|
+
const request = input.receipt !== undefined ? pushoverCancelRequest(token, input.receipt) : pushoverCancelByTagRequest(token, input.tag ?? "");
|
|
128
|
+
return call(request, extractPushoverCancelled, input.timeoutMs, ctx);
|
|
129
|
+
})
|
|
130
|
+
.build();
|
|
131
|
+
const ValidateInputSchema = z.object({
|
|
132
|
+
user: z.string().optional().describe("The user key to examine. Without it, the procedure reads userEnv."),
|
|
133
|
+
userEnv: envName("PUSHOVER_USER_KEY", "userEnv"),
|
|
134
|
+
device: z.string().optional().describe("The name of a device to examine"),
|
|
135
|
+
...common,
|
|
136
|
+
});
|
|
137
|
+
export const pushoverValidateProcedure = createProcedure()
|
|
138
|
+
.path(["notify", "pushover", "validate"])
|
|
139
|
+
.input(ValidateInputSchema)
|
|
140
|
+
.output(ResultSchema)
|
|
141
|
+
.meta({
|
|
142
|
+
description: "Examine a Pushover user key: its active devices and licenses. It sends no message.",
|
|
143
|
+
args: [],
|
|
144
|
+
output: "json",
|
|
145
|
+
effects: { reads: ["network"], writes: [], destructive: false },
|
|
146
|
+
})
|
|
147
|
+
.handler(async (input, ctx) => call(pushoverValidateRequest(secret(input.tokenEnv), input.user ?? secret(input.userEnv), input.device), extractPushoverValidated, input.timeoutMs, ctx))
|
|
148
|
+
.build();
|
|
149
|
+
const LimitsInputSchema = z.object({ ...common });
|
|
150
|
+
export const pushoverLimitsProcedure = createProcedure()
|
|
151
|
+
.path(["notify", "pushover", "limits"])
|
|
152
|
+
.input(LimitsInputSchema)
|
|
153
|
+
.output(ResultSchema)
|
|
154
|
+
.meta({
|
|
155
|
+
description: "Read the monthly message limit of the Pushover application, the messages left and the reset time",
|
|
156
|
+
args: [],
|
|
157
|
+
output: "json",
|
|
158
|
+
effects: { reads: ["network"], writes: [], destructive: false },
|
|
159
|
+
})
|
|
160
|
+
.handler(async (input, ctx) => call(pushoverLimitsRequest(secret(input.tokenEnv)), extractPushoverLimits, input.timeoutMs, ctx))
|
|
161
|
+
.build();
|
|
162
|
+
export const pushoverProcedures = [
|
|
163
|
+
pushoverSendProcedure,
|
|
164
|
+
pushoverReceiptProcedure,
|
|
165
|
+
pushoverCancelProcedure,
|
|
166
|
+
pushoverValidateProcedure,
|
|
167
|
+
pushoverLimitsProcedure,
|
|
168
|
+
];
|
|
169
|
+
//# sourceMappingURL=pushover-procedures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pushover-procedures.js","sourceRoot":"","sources":["../src/pushover-procedures.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pushover (https://pushover.net) as pure functions. A request builder gives the URL, the method,
|
|
3
|
+
* the headers and the body of one call. An extractor reads the HTTP status, the headers and the
|
|
4
|
+
* body text of the response into a typed result. Neither function sends a request, so the caller
|
|
5
|
+
* gives the fetch: `globalThis.fetch`, a polite client or a fake server of a test.
|
|
6
|
+
*
|
|
7
|
+
* This entry imports no Node built-in, so a browser can also use it.
|
|
8
|
+
*
|
|
9
|
+
* Each time in this file is in milliseconds. The builders change a time to the whole seconds of
|
|
10
|
+
* Pushover, and the extractors change the seconds of Pushover to milliseconds.
|
|
11
|
+
*
|
|
12
|
+
* A request holds the API token of the application: in the body of a POST, or in the query of a
|
|
13
|
+
* GET. Do not log a request or its URL.
|
|
14
|
+
*/
|
|
15
|
+
/** The base of the Pushover API. */
|
|
16
|
+
export declare const PUSHOVER_API = "https://api.pushover.net/1";
|
|
17
|
+
/** The limits of the Pushover API, in characters (Unicode code points). */
|
|
18
|
+
export declare const PUSHOVER_LIMITS: {
|
|
19
|
+
readonly message: 1024;
|
|
20
|
+
readonly title: 250;
|
|
21
|
+
readonly url: 512;
|
|
22
|
+
readonly urlTitle: 100;
|
|
23
|
+
readonly device: 25;
|
|
24
|
+
readonly users: 50;
|
|
25
|
+
};
|
|
26
|
+
/** The shortest time between two repeats of an emergency message: 30 seconds. */
|
|
27
|
+
export declare const PUSHOVER_RETRY_MIN_MS = 30000;
|
|
28
|
+
/** The longest time that Pushover repeats an emergency message: 3 hours. */
|
|
29
|
+
export declare const PUSHOVER_EXPIRE_MAX_MS = 10800000;
|
|
30
|
+
/**
|
|
31
|
+
* The shortest wait before a call goes again after a server error or no answer: 5 seconds. It is
|
|
32
|
+
* also the shortest time between two reads of one receipt.
|
|
33
|
+
*/
|
|
34
|
+
export declare const PUSHOVER_MIN_WAIT_MS = 5000;
|
|
35
|
+
/**
|
|
36
|
+
* The priority of a message. `-2`: no notification. `-1`: no sound. `0`: normal. `1`: high, it
|
|
37
|
+
* passes the quiet hours of the user. `2`: emergency, it repeats until the user acknowledges it.
|
|
38
|
+
*/
|
|
39
|
+
export type PushoverPriority = -2 | -1 | 0 | 1 | 2;
|
|
40
|
+
/** The repeats of an emergency message (priority 2). */
|
|
41
|
+
export interface PushoverEmergency {
|
|
42
|
+
/** The time between two repeats: 30 seconds or more. Pushover sends 50 repeats at most. */
|
|
43
|
+
readonly retryMs: number;
|
|
44
|
+
/** The time after which the repeats stop: 3 hours or less. */
|
|
45
|
+
readonly expireMs: number;
|
|
46
|
+
/** An address on the internet that gets a POST when the user acknowledges the message. */
|
|
47
|
+
readonly callback?: string | undefined;
|
|
48
|
+
/** The tags of the receipt. `pushoverCancelByTagRequest` stops the repeats of each message with a tag. */
|
|
49
|
+
readonly tags?: readonly string[] | undefined;
|
|
50
|
+
}
|
|
51
|
+
/** One message of the messages API. */
|
|
52
|
+
export interface PushoverMessage {
|
|
53
|
+
/** The user key or the group key of the recipient, or up to 50 user keys with commas. */
|
|
54
|
+
readonly user: string;
|
|
55
|
+
readonly message: string;
|
|
56
|
+
/** The title. Without a title, the device shows the name of the application. */
|
|
57
|
+
readonly title?: string | undefined;
|
|
58
|
+
/** An address that the notification opens. */
|
|
59
|
+
readonly url?: string | undefined;
|
|
60
|
+
readonly urlTitle?: string | undefined;
|
|
61
|
+
/** The priority (default `0`). Priority `2` needs `emergency`. */
|
|
62
|
+
readonly priority?: PushoverPriority | undefined;
|
|
63
|
+
/** The repeats of an emergency message. Only priority `2` takes them. */
|
|
64
|
+
readonly emergency?: PushoverEmergency | undefined;
|
|
65
|
+
/** The name of a sound of Pushover, or of a custom sound of the user. */
|
|
66
|
+
readonly sound?: string | undefined;
|
|
67
|
+
/** The names of the devices of the user that get the message. Without names, each device gets it. */
|
|
68
|
+
readonly devices?: readonly string[] | undefined;
|
|
69
|
+
/** The time that the notification shows, in milliseconds since the Unix epoch. */
|
|
70
|
+
readonly timestampMs?: number | undefined;
|
|
71
|
+
/** The format of the text (default `text`). */
|
|
72
|
+
readonly format?: "text" | "html" | "monospace" | undefined;
|
|
73
|
+
/** The time after which the device deletes the message. Priority `2` ignores it. */
|
|
74
|
+
readonly ttlMs?: number | undefined;
|
|
75
|
+
}
|
|
76
|
+
/** One call of the Pushover API. Its fields fit the `init` of `fetch`. */
|
|
77
|
+
export interface PushoverRequest {
|
|
78
|
+
readonly url: string;
|
|
79
|
+
readonly method: "GET" | "POST";
|
|
80
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
81
|
+
/** The form body of a POST. It holds the API token. */
|
|
82
|
+
readonly body?: string;
|
|
83
|
+
}
|
|
84
|
+
/** The parts of an HTTP response that an extractor reads. A `Response` of `fetch` and its text fit it. */
|
|
85
|
+
export interface PushoverResponse {
|
|
86
|
+
/** The HTTP status. */
|
|
87
|
+
readonly status: number;
|
|
88
|
+
/** The body text. */
|
|
89
|
+
readonly text: string;
|
|
90
|
+
/** The headers. Only `pushoverSendRequest` gives headers that the extractor reads. */
|
|
91
|
+
readonly headers?: {
|
|
92
|
+
get(name: string): string | null;
|
|
93
|
+
} | undefined;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The kind of a failure.
|
|
97
|
+
* - `network`: the request did not reach Pushover, or no answer came.
|
|
98
|
+
* - `timeout`: no answer came in the time limit.
|
|
99
|
+
* - `server`: Pushover had an error. The same request can go again after `retryAfterMs`.
|
|
100
|
+
* - `rate-limited`: the account sent its messages of the month. Each request fails until `resetAt`.
|
|
101
|
+
* - `auth`: Pushover refused the API token.
|
|
102
|
+
* - `refused`: Pushover refused the input, for example a user key that it does not know. The same
|
|
103
|
+
* request fails again, and many refusals in a few minutes can block the address of the caller.
|
|
104
|
+
*/
|
|
105
|
+
export type PushoverFailureKind = "network" | "timeout" | "server" | "rate-limited" | "auth" | "refused";
|
|
106
|
+
/** A call that failed. An extractor does not throw: it gives a failure. */
|
|
107
|
+
export interface PushoverFailure {
|
|
108
|
+
readonly ok: false;
|
|
109
|
+
readonly kind: PushoverFailureKind;
|
|
110
|
+
/** The HTTP status. It is `0` when no answer came. */
|
|
111
|
+
readonly status: number;
|
|
112
|
+
/** The errors that Pushover gives, or a description of the failure. */
|
|
113
|
+
readonly errors: readonly string[];
|
|
114
|
+
/** The id of the request, for the support of Pushover. */
|
|
115
|
+
readonly request?: string;
|
|
116
|
+
/** The shortest wait before the same request goes again. Only `server`, `network` and `timeout` have it. */
|
|
117
|
+
readonly retryAfterMs?: number;
|
|
118
|
+
/** The time of the reset of the monthly limit, in milliseconds since the epoch, when Pushover gives it. */
|
|
119
|
+
readonly resetAt?: number;
|
|
120
|
+
}
|
|
121
|
+
/** The monthly limit of the application, from the headers of a send or from `pushoverLimitsRequest`. */
|
|
122
|
+
export interface PushoverLimits {
|
|
123
|
+
readonly limit: number;
|
|
124
|
+
readonly remaining: number;
|
|
125
|
+
/** The time of the reset, in milliseconds since the epoch. */
|
|
126
|
+
readonly resetAt: number;
|
|
127
|
+
}
|
|
128
|
+
/** A message that Pushover queued. */
|
|
129
|
+
export interface PushoverSent {
|
|
130
|
+
readonly ok: true;
|
|
131
|
+
readonly request: string;
|
|
132
|
+
/** The receipt of an emergency message. Only priority `2` gives a receipt. */
|
|
133
|
+
readonly receipt?: string;
|
|
134
|
+
readonly limits?: PushoverLimits;
|
|
135
|
+
}
|
|
136
|
+
/** The state of the receipt of an emergency message. */
|
|
137
|
+
export interface PushoverReceipt {
|
|
138
|
+
readonly ok: true;
|
|
139
|
+
readonly acknowledged: boolean;
|
|
140
|
+
/** The time of the acknowledgment, in milliseconds since the epoch. */
|
|
141
|
+
readonly acknowledgedAt?: number;
|
|
142
|
+
/** The user key of the first user that acknowledged. */
|
|
143
|
+
readonly acknowledgedBy?: string;
|
|
144
|
+
/** The device of the first user that acknowledged. */
|
|
145
|
+
readonly acknowledgedByDevice?: string;
|
|
146
|
+
/** The time of the last repeat. */
|
|
147
|
+
readonly lastDeliveredAt?: number;
|
|
148
|
+
/** True when the repeats stopped at their expiry. */
|
|
149
|
+
readonly expired: boolean;
|
|
150
|
+
/** The time at which the repeats stop. */
|
|
151
|
+
readonly expiresAt: number;
|
|
152
|
+
readonly calledBack: boolean;
|
|
153
|
+
readonly calledBackAt?: number;
|
|
154
|
+
}
|
|
155
|
+
/** A cancel that Pushover accepted. */
|
|
156
|
+
export interface PushoverCancelled {
|
|
157
|
+
readonly ok: true;
|
|
158
|
+
readonly request?: string;
|
|
159
|
+
/** The count of messages that a cancel by tag stopped, when Pushover gives it. */
|
|
160
|
+
readonly cancelled?: number;
|
|
161
|
+
}
|
|
162
|
+
/** A user key that Pushover knows. */
|
|
163
|
+
export interface PushoverValidated {
|
|
164
|
+
readonly ok: true;
|
|
165
|
+
/** True for the key of a group. */
|
|
166
|
+
readonly group: boolean;
|
|
167
|
+
/** The names of the active devices. */
|
|
168
|
+
readonly devices: readonly string[];
|
|
169
|
+
/** The platforms of the licenses of the user, for example `iOS`. */
|
|
170
|
+
readonly licenses: readonly string[];
|
|
171
|
+
}
|
|
172
|
+
/** The monthly limit, from `pushoverLimitsRequest`. */
|
|
173
|
+
export interface PushoverLimitsRead {
|
|
174
|
+
readonly ok: true;
|
|
175
|
+
readonly limits: PushoverLimits;
|
|
176
|
+
}
|
|
177
|
+
/** The acknowledgment that Pushover sends to the `callback` address of an emergency message. */
|
|
178
|
+
export interface PushoverCallback {
|
|
179
|
+
readonly receipt: string;
|
|
180
|
+
readonly acknowledgedAt: number;
|
|
181
|
+
readonly acknowledgedBy?: string;
|
|
182
|
+
readonly acknowledgedByDevice?: string;
|
|
183
|
+
}
|
|
184
|
+
/** The form of an API token, a user key, a group key and a receipt: 30 letters and digits. */
|
|
185
|
+
export declare const PUSHOVER_KEY: RegExp;
|
|
186
|
+
/**
|
|
187
|
+
* This function gives the request that sends one message. It throws an error when the input
|
|
188
|
+
* breaks a rule of the API. Pushover refuses such a request, and many refusals can block the
|
|
189
|
+
* address of the caller.
|
|
190
|
+
*/
|
|
191
|
+
export declare function pushoverSendRequest(token: string, message: PushoverMessage): PushoverRequest;
|
|
192
|
+
/**
|
|
193
|
+
* This function gives the request that reads the receipt of an emergency message. Read one receipt
|
|
194
|
+
* at most once in 5 seconds (`PUSHOVER_MIN_WAIT_MS`). Pushover keeps a receipt for one week.
|
|
195
|
+
*/
|
|
196
|
+
export declare function pushoverReceiptRequest(token: string, receipt: string): PushoverRequest;
|
|
197
|
+
/** This function gives the request that stops the repeats of one emergency message. A second cancel has no effect. */
|
|
198
|
+
export declare function pushoverCancelRequest(token: string, receipt: string): PushoverRequest;
|
|
199
|
+
/**
|
|
200
|
+
* This function gives the request that stops the repeats of each emergency message of the
|
|
201
|
+
* application with the tag. A copy of a system that did not send the message can stop it.
|
|
202
|
+
*/
|
|
203
|
+
export declare function pushoverCancelByTagRequest(token: string, tag: string): PushoverRequest;
|
|
204
|
+
/** This function gives the request that examines a user key, and one device of the user when `device` names it. */
|
|
205
|
+
export declare function pushoverValidateRequest(token: string, user: string, device?: string): PushoverRequest;
|
|
206
|
+
/** This function gives the request that reads the monthly limit of the application. */
|
|
207
|
+
export declare function pushoverLimitsRequest(token: string): PushoverRequest;
|
|
208
|
+
/** This function reads the response of `pushoverSendRequest`. It does not throw. */
|
|
209
|
+
export declare function extractPushoverSent(response: PushoverResponse): PushoverSent | PushoverFailure;
|
|
210
|
+
/** This function reads the response of `pushoverReceiptRequest`. It does not throw. */
|
|
211
|
+
export declare function extractPushoverReceipt(response: PushoverResponse): PushoverReceipt | PushoverFailure;
|
|
212
|
+
/** This function reads the response of `pushoverCancelRequest` or `pushoverCancelByTagRequest`. It does not throw. */
|
|
213
|
+
export declare function extractPushoverCancelled(response: PushoverResponse): PushoverCancelled | PushoverFailure;
|
|
214
|
+
/** This function reads the response of `pushoverValidateRequest`. A user key that Pushover does not know is a `refused` failure. */
|
|
215
|
+
export declare function extractPushoverValidated(response: PushoverResponse): PushoverValidated | PushoverFailure;
|
|
216
|
+
/** This function reads the response of `pushoverLimitsRequest`. It does not throw. */
|
|
217
|
+
export declare function extractPushoverLimits(response: PushoverResponse): PushoverLimitsRead | PushoverFailure;
|
|
218
|
+
/**
|
|
219
|
+
* This function reads the form body that Pushover posts to the `callback` address when a user
|
|
220
|
+
* acknowledges an emergency message. It gives `undefined` for another body. Pushover sends the post
|
|
221
|
+
* again each minute until the address answers 2xx.
|
|
222
|
+
*/
|
|
223
|
+
export declare function extractPushoverCallback(body: string): PushoverCallback | undefined;
|
|
224
|
+
/** The part of `fetch` that `callPushover` uses. `globalThis.fetch` fits this type. */
|
|
225
|
+
export type PushoverFetch = (url: string, init: {
|
|
226
|
+
method: string;
|
|
227
|
+
headers: Record<string, string>;
|
|
228
|
+
body?: string;
|
|
229
|
+
signal: AbortSignal;
|
|
230
|
+
}) => Promise<{
|
|
231
|
+
readonly status: number;
|
|
232
|
+
text(): Promise<string>;
|
|
233
|
+
readonly headers: {
|
|
234
|
+
get(name: string): string | null;
|
|
235
|
+
};
|
|
236
|
+
}>;
|
|
237
|
+
/**
|
|
238
|
+
* This function sends one request through the fetch and reads the response with the extractor. It
|
|
239
|
+
* does not throw for a failure of the network or a time limit: it gives a failure of the kind
|
|
240
|
+
* `network` or `timeout`. It throws only the reason of `signal`, when the caller aborts. It does not
|
|
241
|
+
* send a request again: the caller keeps the pace and the retries.
|
|
242
|
+
*/
|
|
243
|
+
export declare function callPushover<Result>(fetch: PushoverFetch, request: PushoverRequest, extract: (response: PushoverResponse) => Result | PushoverFailure, options: {
|
|
244
|
+
readonly timeoutMs: number;
|
|
245
|
+
readonly signal?: AbortSignal | undefined;
|
|
246
|
+
}): Promise<Result | PushoverFailure>;
|
|
247
|
+
//# sourceMappingURL=pushover.d.ts.map
|