smsforwarder 1.0.0 → 1.1.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 +4 -4
- package/package.json +1 -1
- package/smsforwarder.mjs +17 -9
package/README.md
CHANGED
|
@@ -7,14 +7,14 @@ Install [SMS Forwarder](https://smsforwarder.app/download/) on the phone that re
|
|
|
7
7
|
```sh
|
|
8
8
|
npm install -g smsforwarder
|
|
9
9
|
smsforwarder login sk_your_key
|
|
10
|
-
CODE=$(smsforwarder code --
|
|
10
|
+
CODE=$(smsforwarder code --timeout 90)
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
`code` waits
|
|
13
|
+
`code` waits for the newest code to arrive and prints only the code. It exits with status 2 if nothing arrives in time. If other codes arrived in the same window it says so on stderr; `smsforwarder messages --codes` lists them so you can pick by the text.
|
|
14
14
|
|
|
15
15
|
```
|
|
16
|
-
smsforwarder code [--
|
|
17
|
-
smsforwarder messages [--
|
|
16
|
+
smsforwarder code [--timeout sec] [--since time] [--json]
|
|
17
|
+
smsforwarder messages [--minutes n] [--codes] [--limit n] [--json]
|
|
18
18
|
smsforwarder devices
|
|
19
19
|
smsforwarder webhook set <url> | rm | test
|
|
20
20
|
smsforwarder mcp # MCP config for Claude, Cursor and other AI tools
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smsforwarder",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Get SMS verification codes from your own phone in scripts and AI agents. CLI for SMS Forwarder (smsforwarder.app).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": { "smsforwarder": "smsforwarder.mjs" },
|
package/smsforwarder.mjs
CHANGED
|
@@ -11,13 +11,12 @@ const HELP = `SMS Forwarder — verification codes from your phone, in your term
|
|
|
11
11
|
|
|
12
12
|
Usage:
|
|
13
13
|
smsforwarder login <api-key> Save your API key (from the phone app)
|
|
14
|
-
smsforwarder code [options] Wait for the
|
|
15
|
-
--from <text> Only codes from this service / sender (e.g. Google, 淘宝)
|
|
16
|
-
--contains <text> Only messages containing this text
|
|
14
|
+
smsforwarder code [options] Wait for the newest verification code and print it
|
|
17
15
|
--timeout <sec> How long to wait, max 120 (default 60)
|
|
18
16
|
--since <time> Only messages after this ISO time / unix ms (default: 2 minutes ago)
|
|
19
|
-
--json Print the whole
|
|
20
|
-
smsforwarder messages [--
|
|
17
|
+
--json Print the whole result as JSON, including other codes that arrived in the same window
|
|
18
|
+
smsforwarder messages [--minutes n] [--codes] [--limit n] [--json]
|
|
19
|
+
Messages from the last n minutes (default 10), newest first
|
|
21
20
|
smsforwarder devices List connected phones
|
|
22
21
|
smsforwarder webhook set <url> Send every new message to your URL (prints the signing secret)
|
|
23
22
|
smsforwarder webhook rm Stop sending to the webhook
|
|
@@ -58,7 +57,7 @@ function apiKey() {
|
|
|
58
57
|
async function call(method, path, body) {
|
|
59
58
|
const res = await fetch(API + path, {
|
|
60
59
|
method,
|
|
61
|
-
headers: { authorization: `Bearer ${apiKey()}`, "content-type": "application/json", "user-agent": "smsforwarder-cli/1.
|
|
60
|
+
headers: { authorization: `Bearer ${apiKey()}`, "content-type": "application/json", "user-agent": "smsforwarder-cli/1.1.0" },
|
|
62
61
|
body: body ? JSON.stringify(body) : undefined,
|
|
63
62
|
});
|
|
64
63
|
const data = await res.json().catch(() => ({}));
|
|
@@ -83,6 +82,9 @@ function ago(iso) {
|
|
|
83
82
|
|
|
84
83
|
const { pos, opt } = parse(process.argv.slice(2));
|
|
85
84
|
const cmd = pos[0];
|
|
85
|
+
for (const gone of ["from", "contains"]) {
|
|
86
|
+
if (opt[gone] !== undefined) die(`--${gone} is gone: who sends a code can't be predicted. Take the newest code, or list recent messages and pick by text.`);
|
|
87
|
+
}
|
|
86
88
|
|
|
87
89
|
switch (cmd) {
|
|
88
90
|
case "login": {
|
|
@@ -98,14 +100,20 @@ switch (cmd) {
|
|
|
98
100
|
case "code":
|
|
99
101
|
case "wait": {
|
|
100
102
|
const timeout = Math.min(Number(opt.timeout ?? 60) || 60, 120);
|
|
101
|
-
const { status, data } = await call("GET", "/v1/codes/wait" + qs({
|
|
103
|
+
const { status, data } = await call("GET", "/v1/codes/wait" + qs({ since: opt.since, timeout }));
|
|
102
104
|
if (status === 404 || !data.code) die(`No code arrived within ${timeout}s.`, 2);
|
|
103
|
-
|
|
105
|
+
if (opt.json) console.log(JSON.stringify(data, null, 2));
|
|
106
|
+
else {
|
|
107
|
+
console.log(data.code);
|
|
108
|
+
if (data.otherCodes?.length) {
|
|
109
|
+
process.stderr.write(`${data.otherCodes.length} other code(s) arrived in the same window; run \`smsforwarder messages --codes\` to pick by text.\n`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
104
112
|
break;
|
|
105
113
|
}
|
|
106
114
|
case "messages":
|
|
107
115
|
case "ls": {
|
|
108
|
-
const { data } = await call("GET", "/v1/messages" + qs({
|
|
116
|
+
const { data } = await call("GET", "/v1/messages" + qs({ minutes: opt.minutes ?? 10, limit: opt.limit ?? 20, codes_only: opt.codes ? "true" : undefined }));
|
|
109
117
|
if (opt.json) {
|
|
110
118
|
console.log(JSON.stringify(data.messages, null, 2));
|
|
111
119
|
break;
|