mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-04-28 03:49:31 +00:00
fix: messaging UX — silence doctor, fix groupPolicy, drop early WhatsApp pairing (#2607)
* fix: messaging UX — silence doctor, fix groupPolicy, remove early WhatsApp pairing - Set groupPolicy to "open" for both Telegram and WhatsApp (was "allowlist" with empty allowFrom, causing doctor warnings) - Suppress doctor warning spam by redirecting openclaw config set stdout to /dev/null - Remove WhatsApp pairing prompt (appeared immediately after QR scan before user could message the bot — now just tells them the command) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: improve Telegram/WhatsApp pairing instructions Add step-by-step instructions for Telegram pairing so users know to search for their bot in Telegram and message it. Improve WhatsApp post-link instructions to explain how contacts pair. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: pre-select Telegram in setup options as recommended channel Telegram has the smoothest setup UX (bot token + pairing code) compared to WhatsApp (QR scan + separate device). Pre-select it alongside Chrome in the multiselect and label it as "recommended" in the hint. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ca5fe851cd
commit
9f51244cb2
5 changed files with 29 additions and 39 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@openrouter/spawn",
|
||||
"version": "0.17.16",
|
||||
"version": "0.17.17",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"spawn": "cli.js"
|
||||
|
|
|
|||
|
|
@ -176,12 +176,15 @@ async function promptSetupOptions(agentName: string): Promise<Set<string> | unde
|
|||
// 1. Arrow keys work immediately (multiple items to navigate)
|
||||
// 2. Users can explicitly skip all steps without pressing Enter on an empty list
|
||||
// 3. Users who accidentally select another option can deselect it and choose None
|
||||
const hasBrowserDefault = filteredSteps.some((s) => s.value === "browser");
|
||||
const defaultValues = hasBrowserDefault
|
||||
? filteredSteps.filter((s) => s.value === "browser").map((s) => s.value)
|
||||
: [
|
||||
NONE_STEP,
|
||||
];
|
||||
// Pre-select browser + telegram by default (telegram has the smoothest setup UX)
|
||||
const recommendedDefaults = [
|
||||
"browser",
|
||||
"telegram",
|
||||
];
|
||||
const defaultValues = filteredSteps.filter((s) => recommendedDefaults.includes(s.value)).map((s) => s.value);
|
||||
if (defaultValues.length === 0) {
|
||||
defaultValues.push(NONE_STEP);
|
||||
}
|
||||
|
||||
const selected = await p.multiselect({
|
||||
message: "Setup options (↑/↓ navigate, space to select, enter to confirm)",
|
||||
|
|
|
|||
|
|
@ -374,6 +374,7 @@ async function setupOpenclawConfig(
|
|||
enabled: true,
|
||||
botToken: telegramBotToken,
|
||||
dmPolicy: "pairing",
|
||||
groupPolicy: "open",
|
||||
groups: {
|
||||
"*": {
|
||||
requireMention: true,
|
||||
|
|
@ -386,7 +387,7 @@ async function setupOpenclawConfig(
|
|||
if (enabledSteps?.has("whatsapp")) {
|
||||
channels.whatsapp = {
|
||||
dmPolicy: "pairing",
|
||||
groupPolicy: "allowlist",
|
||||
groupPolicy: "open",
|
||||
sendReadReceipts: true,
|
||||
};
|
||||
}
|
||||
|
|
@ -399,14 +400,14 @@ async function setupOpenclawConfig(
|
|||
await uploadConfigFile(runner, config, "$HOME/.openclaw/openclaw.json");
|
||||
|
||||
// Configure browser via CLI (openclaw config set) — the supported way to set
|
||||
// browser options. Writing JSON directly may not be picked up by all versions.
|
||||
// browser options. Redirect stdout to suppress doctor warnings on each call.
|
||||
const browserResult = await asyncTryCatchIf(isOperationalError, () =>
|
||||
runner.runServer(
|
||||
"export PATH=$HOME/.npm-global/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH; " +
|
||||
"openclaw config set browser.executablePath /usr/bin/google-chrome-stable; " +
|
||||
"openclaw config set browser.noSandbox true; " +
|
||||
"openclaw config set browser.headless true; " +
|
||||
"openclaw config set browser.defaultProfile openclaw",
|
||||
"openclaw config set browser.executablePath /usr/bin/google-chrome-stable >/dev/null; " +
|
||||
"openclaw config set browser.noSandbox true >/dev/null; " +
|
||||
"openclaw config set browser.headless true >/dev/null; " +
|
||||
"openclaw config set browser.defaultProfile openclaw >/dev/null",
|
||||
),
|
||||
);
|
||||
if (!browserResult.ok) {
|
||||
|
|
@ -419,7 +420,7 @@ async function setupOpenclawConfig(
|
|||
const gatewayTokenResult = await asyncTryCatchIf(isOperationalError, () =>
|
||||
runner.runServer(
|
||||
"export PATH=$HOME/.npm-global/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH; " +
|
||||
`openclaw config set gateway.auth.token ${shellQuote(gatewayToken)}`,
|
||||
`openclaw config set gateway.auth.token ${shellQuote(gatewayToken)} >/dev/null`,
|
||||
),
|
||||
);
|
||||
if (!gatewayTokenResult.ok) {
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ const AGENT_EXTRA_STEPS: Record<string, OptionalStep[]> = {
|
|||
{
|
||||
value: "telegram",
|
||||
label: "Telegram",
|
||||
hint: "connect via bot token from @BotFather",
|
||||
hint: "recommended — connect via bot token from @BotFather",
|
||||
dataEnvVar: "TELEGRAM_BOT_TOKEN",
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -298,8 +298,12 @@ export async function runOrchestration(
|
|||
|
||||
if (enabledSteps?.has("telegram")) {
|
||||
logStep("Telegram pairing...");
|
||||
logInfo("DM your Telegram bot to get a pairing code, then enter it below.");
|
||||
logInfo("Waiting for pairing code...");
|
||||
logInfo("To pair your Telegram account:");
|
||||
logInfo(" 1. Open Telegram on your phone");
|
||||
logInfo(" 2. Search for the bot you created with @BotFather");
|
||||
logInfo(' 3. Send it any message (e.g. "hello")');
|
||||
logInfo(" 4. The bot will reply with a pairing code");
|
||||
logInfo(" 5. Enter the code below");
|
||||
process.stderr.write("\n");
|
||||
const pairingCode = (await prompt("Telegram pairing code: ")).trim();
|
||||
if (pairingCode) {
|
||||
|
|
@ -320,34 +324,16 @@ export async function runOrchestration(
|
|||
}
|
||||
|
||||
if (enabledSteps?.has("whatsapp")) {
|
||||
// Step 1: QR code scan to link the WhatsApp device
|
||||
logStep("Linking WhatsApp — scan the QR code with your phone...");
|
||||
logInfo("Open WhatsApp > Settings > Linked Devices > Link a Device");
|
||||
process.stderr.write("\n");
|
||||
const whatsappCmd = `source ~/.spawnrc 2>/dev/null; ${ocPath}; openclaw channels login --channel whatsapp`;
|
||||
prepareStdinForHandoff();
|
||||
await cloud.interactiveSession(whatsappCmd);
|
||||
|
||||
// Step 2: Pairing — approve your own number so the bot responds to you
|
||||
logStep("WhatsApp pairing...");
|
||||
logInfo("Send a message to your bot on WhatsApp to get a pairing code, then enter it below.");
|
||||
process.stderr.write("\n");
|
||||
const pairingCode = (await prompt("WhatsApp pairing code: ")).trim();
|
||||
if (pairingCode) {
|
||||
const escaped = shellQuote(pairingCode);
|
||||
const result = await asyncTryCatchIf(isOperationalError, () =>
|
||||
cloud.runner.runServer(
|
||||
`source ~/.spawnrc 2>/dev/null; ${ocPath}; openclaw pairing approve whatsapp ${escaped}`,
|
||||
),
|
||||
);
|
||||
if (result.ok) {
|
||||
logInfo("WhatsApp paired successfully");
|
||||
} else {
|
||||
logWarn("Pairing failed — you can pair later via: openclaw pairing approve whatsapp <CODE>");
|
||||
}
|
||||
} else {
|
||||
logInfo("No code entered — pair later via: openclaw pairing approve whatsapp <CODE>");
|
||||
}
|
||||
logInfo("WhatsApp linked! To pair a contact:");
|
||||
logInfo(" 1. Have someone message your WhatsApp number");
|
||||
logInfo(" 2. They'll get a pairing code from the bot");
|
||||
logInfo(" 3. Approve via: openclaw pairing approve whatsapp <CODE>");
|
||||
}
|
||||
|
||||
// 11d. Agent-specific pre-launch tip (e.g. channel setup ordering hint)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue