Document config options and log auto-reply timing
This commit is contained in:
33
README.md
33
README.md
@@ -52,6 +52,39 @@ Put a JSON5 config at `~/.warelay/warelay.json`. Examples:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Options reference (JSON5)
|
||||||
|
|
||||||
|
- `inbound.allowFrom?: string[]` — optional allowlist of E.164 numbers (no `whatsapp:` prefix). If set, only these senders trigger auto-replies.
|
||||||
|
- `inbound.reply.mode: "text" | "command"`
|
||||||
|
- `text` — send `inbound.reply.text` after templating.
|
||||||
|
- `command` — run `inbound.reply.command` (argv array) after templating; trimmed stdout becomes the reply.
|
||||||
|
- `inbound.reply.text?: string` — used when `mode` is `text`; supports `{{Body}}`, `{{From}}`, `{{To}}`, `{{MessageSid}}`.
|
||||||
|
- `inbound.reply.command?: string[]` — argv for the command to run; templated per element.
|
||||||
|
- `inbound.reply.template?: string` — optional string prepended as the second argv element (handy for adding a prompt prefix).
|
||||||
|
|
||||||
|
Example with an allowlist and Claude CLI one-shot (uses a sample number):
|
||||||
|
|
||||||
|
```json5
|
||||||
|
{
|
||||||
|
inbound: {
|
||||||
|
allowFrom: ["+15551230000"],
|
||||||
|
reply: {
|
||||||
|
mode: "command",
|
||||||
|
command: [
|
||||||
|
"claude",
|
||||||
|
"--print",
|
||||||
|
"--output-format",
|
||||||
|
"text",
|
||||||
|
"--dangerously-skip-permissions",
|
||||||
|
"--system-prompt",
|
||||||
|
"You are an auto-reply bot on WhatsApp. Respond concisely.",
|
||||||
|
"{{Body}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
During dev you can run without building: `pnpm dev -- <subcommand>` (e.g. `pnpm dev -- send --to +1...`). Auto-replies apply in webhook and polling modes.
|
During dev you can run without building: `pnpm dev -- <subcommand>` (e.g. `pnpm dev -- send --to +1...`). Auto-replies apply in webhook and polling modes.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ type TwilioRequestOptions = {
|
|||||||
uri: string;
|
uri: string;
|
||||||
params?: Record<string, string | number>;
|
params?: Record<string, string | number>;
|
||||||
form?: Record<string, string>;
|
form?: Record<string, string>;
|
||||||
|
body?: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
type TwilioSender = { sid: string; sender_id: string };
|
type TwilioSender = { sid: string; sender_id: string };
|
||||||
@@ -390,8 +391,8 @@ async function getReplyFromConfig(
|
|||||||
const finalArgv = templatePrefix
|
const finalArgv = templatePrefix
|
||||||
? [argv[0], templatePrefix, ...argv.slice(1)]
|
? [argv[0], templatePrefix, ...argv.slice(1)]
|
||||||
: argv;
|
: argv;
|
||||||
|
const started = Date.now();
|
||||||
try {
|
try {
|
||||||
if (globalVerbose) console.log(`RUN `);
|
|
||||||
const { stdout } = await execFileAsync(finalArgv[0], finalArgv.slice(1), {
|
const { stdout } = await execFileAsync(finalArgv[0], finalArgv.slice(1), {
|
||||||
maxBuffer: 1024 * 1024,
|
maxBuffer: 1024 * 1024,
|
||||||
});
|
});
|
||||||
@@ -399,9 +400,13 @@ async function getReplyFromConfig(
|
|||||||
logVerbose(
|
logVerbose(
|
||||||
`Command auto-reply stdout (trimmed): ${trimmed || "<empty>"}`,
|
`Command auto-reply stdout (trimmed): ${trimmed || "<empty>"}`,
|
||||||
);
|
);
|
||||||
|
logVerbose(`Command auto-reply finished in ${Date.now() - started}ms`);
|
||||||
return trimmed || undefined;
|
return trimmed || undefined;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Command auto-reply failed", err);
|
console.error(
|
||||||
|
`Command auto-reply failed after ${Date.now() - started}ms`,
|
||||||
|
err,
|
||||||
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user