chore: logger cleanup and test fixes
parent
fdfb1df0de
commit
d7cc94333a
|
|
@ -243,6 +243,8 @@ export async function getReplyFromConfig(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const finalArgv = argv;
|
const finalArgv = argv;
|
||||||
|
const isClaudeInvocation =
|
||||||
|
finalArgv.length > 0 && path.basename(finalArgv[0]) === CLAUDE_BIN;
|
||||||
logVerbose(`Running command auto-reply: ${finalArgv.join(" ")}`);
|
logVerbose(`Running command auto-reply: ${finalArgv.join(" ")}`);
|
||||||
const started = Date.now();
|
const started = Date.now();
|
||||||
try {
|
try {
|
||||||
|
|
@ -255,7 +257,7 @@ export async function getReplyFromConfig(
|
||||||
if (stderr?.trim()) {
|
if (stderr?.trim()) {
|
||||||
logVerbose(`Command auto-reply stderr: ${stderr.trim()}`);
|
logVerbose(`Command auto-reply stderr: ${stderr.trim()}`);
|
||||||
}
|
}
|
||||||
if (reply.claudeOutputFormat === "json" && trimmed) {
|
if (trimmed && (reply.claudeOutputFormat === "json" || isClaudeInvocation)) {
|
||||||
// Claude JSON mode: extract the human text for both logging and reply while keeping metadata.
|
// Claude JSON mode: extract the human text for both logging and reply while keeping metadata.
|
||||||
const parsed = parseClaudeJson(trimmed);
|
const parsed = parseClaudeJson(trimmed);
|
||||||
if (parsed?.parsed && isVerbose()) {
|
if (parsed?.parsed && isVerbose()) {
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,34 @@ describe("config and templating", () => {
|
||||||
|
|
||||||
expect(result).toBe("hello world");
|
expect(result).toBe("hello world");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("parses Claude JSON output even without explicit claudeOutputFormat when using claude bin", async () => {
|
||||||
|
const runSpy = vi.spyOn(index, "runCommandWithTimeout").mockResolvedValue({
|
||||||
|
stdout: '{"result":"Sure! What\'s up?"}\n',
|
||||||
|
stderr: "",
|
||||||
|
code: 0,
|
||||||
|
signal: null,
|
||||||
|
killed: false,
|
||||||
|
});
|
||||||
|
const cfg = {
|
||||||
|
inbound: {
|
||||||
|
reply: {
|
||||||
|
mode: "command" as const,
|
||||||
|
command: ["claude", "{{Body}}"],
|
||||||
|
// No claudeOutputFormat set on purpose
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await index.getReplyFromConfig(
|
||||||
|
{ Body: "hi", From: "+1", To: "+2" },
|
||||||
|
undefined,
|
||||||
|
cfg,
|
||||||
|
runSpy,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe("Sure! What's up?");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("twilio interactions", () => {
|
describe("twilio interactions", () => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { EventEmitter } from "node:events";
|
import { EventEmitter } from "node:events";
|
||||||
|
import fsSync from "node:fs";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import type { MockBaileysSocket } from "../test/mocks/baileys.js";
|
import type { MockBaileysSocket } from "../test/mocks/baileys.js";
|
||||||
import { createMockBaileys } from "../test/mocks/baileys.js";
|
import { createMockBaileys } from "../test/mocks/baileys.js";
|
||||||
|
|
@ -30,6 +31,7 @@ import {
|
||||||
createWaSocket,
|
createWaSocket,
|
||||||
loginWeb,
|
loginWeb,
|
||||||
monitorWebInbox,
|
monitorWebInbox,
|
||||||
|
logWebSelfId,
|
||||||
sendMessageWeb,
|
sendMessageWeb,
|
||||||
waitForWaConnection,
|
waitForWaConnection,
|
||||||
} from "./provider-web.js";
|
} from "./provider-web.js";
|
||||||
|
|
@ -162,4 +164,28 @@ describe("provider-web", () => {
|
||||||
|
|
||||||
await listener.close();
|
await listener.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("logWebSelfId prints cached E.164 when creds exist", () => {
|
||||||
|
const existsSpy = vi
|
||||||
|
.spyOn(fsSync, "existsSync")
|
||||||
|
.mockReturnValue(true as never);
|
||||||
|
const readSpy = vi
|
||||||
|
.spyOn(fsSync, "readFileSync")
|
||||||
|
.mockReturnValue(
|
||||||
|
JSON.stringify({ me: { id: "12345@s.whatsapp.net" } }),
|
||||||
|
);
|
||||||
|
const runtime = {
|
||||||
|
log: vi.fn(),
|
||||||
|
error: vi.fn(),
|
||||||
|
exit: vi.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
logWebSelfId(runtime as never);
|
||||||
|
|
||||||
|
expect(runtime.log).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining("+12345"),
|
||||||
|
);
|
||||||
|
existsSpy.mockRestore();
|
||||||
|
readSpy.mockRestore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -341,10 +341,10 @@ function readWebSelfId() {
|
||||||
// Read the cached WhatsApp Web identity (jid + E.164) from disk if present.
|
// Read the cached WhatsApp Web identity (jid + E.164) from disk if present.
|
||||||
const credsPath = path.join(WA_WEB_AUTH_DIR, "creds.json");
|
const credsPath = path.join(WA_WEB_AUTH_DIR, "creds.json");
|
||||||
try {
|
try {
|
||||||
if (!fs.existsSync(credsPath)) {
|
if (!fsSync.existsSync(credsPath)) {
|
||||||
return { e164: null, jid: null };
|
return { e164: null, jid: null };
|
||||||
}
|
}
|
||||||
const raw = fs.readFileSync(credsPath, "utf-8");
|
const raw = fsSync.readFileSync(credsPath, "utf-8");
|
||||||
const parsed = JSON.parse(raw) as { me?: { id?: string } } | undefined;
|
const parsed = JSON.parse(raw) as { me?: { id?: string } } | undefined;
|
||||||
const jid = parsed?.me?.id ?? null;
|
const jid = parsed?.me?.id ?? null;
|
||||||
const e164 = jid ? jidToE164(jid) : null;
|
const e164 = jid ? jidToE164(jid) : null;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { success, isVerbose, warn } from "../globals.js";
|
import { isVerbose, success, warn } from "../globals.js";
|
||||||
|
import { logError, logInfo } from "../logger.js";
|
||||||
import { readEnv } from "../env.js";
|
import { readEnv } from "../env.js";
|
||||||
import { normalizeE164 } from "../utils.js";
|
import { normalizeE164 } from "../utils.js";
|
||||||
import type { RuntimeEnv } from "../runtime.js";
|
import { defaultRuntime, type RuntimeEnv } from "../runtime.js";
|
||||||
import { createClient } from "./client.js";
|
import { createClient } from "./client.js";
|
||||||
import type { TwilioSenderListClient, TwilioRequester } from "./types.js";
|
import type { TwilioSenderListClient, TwilioRequester } from "./types.js";
|
||||||
|
|
||||||
|
|
@ -43,6 +44,7 @@ export async function setMessagingServiceWebhook(
|
||||||
client: TwilioSenderListClient,
|
client: TwilioSenderListClient,
|
||||||
url: string,
|
url: string,
|
||||||
method: "POST" | "GET",
|
method: "POST" | "GET",
|
||||||
|
runtime: RuntimeEnv = defaultRuntime,
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const msid = await findMessagingServiceSid(client);
|
const msid = await findMessagingServiceSid(client);
|
||||||
if (!msid) return false;
|
if (!msid) return false;
|
||||||
|
|
@ -53,10 +55,9 @@ export async function setMessagingServiceWebhook(
|
||||||
});
|
});
|
||||||
const fetched = await client.messaging.v1.services(msid).fetch();
|
const fetched = await client.messaging.v1.services(msid).fetch();
|
||||||
const stored = fetched?.inboundRequestUrl;
|
const stored = fetched?.inboundRequestUrl;
|
||||||
console.log(
|
logInfo(
|
||||||
success(
|
`✅ Messaging Service webhook set to ${stored ?? url} (service ${msid})`,
|
||||||
`✅ Messaging Service webhook set to ${stored ?? url} (service ${msid})`,
|
runtime,
|
||||||
),
|
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch {
|
} catch {
|
||||||
|
|
@ -96,18 +97,19 @@ export async function updateWebhook(
|
||||||
const storedUrl =
|
const storedUrl =
|
||||||
fetched?.webhook?.callback_url || fetched?.webhook?.fallback_url;
|
fetched?.webhook?.callback_url || fetched?.webhook?.fallback_url;
|
||||||
if (storedUrl) {
|
if (storedUrl) {
|
||||||
console.log(success(`✅ Twilio sender webhook set to ${storedUrl}`));
|
logInfo(`✅ Twilio sender webhook set to ${storedUrl}`, runtime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isVerbose())
|
if (isVerbose())
|
||||||
console.error(
|
logError(
|
||||||
"Sender updated but webhook callback_url missing; will try fallbacks",
|
"Sender updated but webhook callback_url missing; will try fallbacks",
|
||||||
|
runtime,
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (isVerbose())
|
if (isVerbose())
|
||||||
console.error(
|
logError(
|
||||||
"channelsSenders request update failed, will try client helpers",
|
`channelsSenders request update failed, will try client helpers: ${String(err)}`,
|
||||||
err,
|
runtime,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,18 +129,19 @@ export async function updateWebhook(
|
||||||
const storedUrl =
|
const storedUrl =
|
||||||
fetched?.webhook?.callback_url || fetched?.webhook?.fallback_url;
|
fetched?.webhook?.callback_url || fetched?.webhook?.fallback_url;
|
||||||
if (storedUrl) {
|
if (storedUrl) {
|
||||||
console.log(success(`✅ Twilio sender webhook set to ${storedUrl}`));
|
logInfo(`✅ Twilio sender webhook set to ${storedUrl}`, runtime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isVerbose())
|
if (isVerbose())
|
||||||
console.error(
|
logError(
|
||||||
"Form update succeeded but callback_url missing; will try helper fallback",
|
"Form update succeeded but callback_url missing; will try helper fallback",
|
||||||
|
runtime,
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (isVerbose())
|
if (isVerbose())
|
||||||
console.error(
|
logError(
|
||||||
"Form channelsSenders update failed, will try helper fallback",
|
`Form channelsSenders update failed, will try helper fallback: ${String(err)}`,
|
||||||
err,
|
runtime,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,18 +157,17 @@ export async function updateWebhook(
|
||||||
.fetch();
|
.fetch();
|
||||||
const storedUrl =
|
const storedUrl =
|
||||||
fetched?.webhook?.callback_url || fetched?.webhook?.fallback_url;
|
fetched?.webhook?.callback_url || fetched?.webhook?.fallback_url;
|
||||||
console.log(
|
logInfo(
|
||||||
success(
|
`✅ Twilio sender webhook set to ${storedUrl ?? url} (helper API)`,
|
||||||
`✅ Twilio sender webhook set to ${storedUrl ?? url} (helper API)`,
|
runtime,
|
||||||
),
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (isVerbose())
|
if (isVerbose())
|
||||||
console.error(
|
logError(
|
||||||
"channelsSenders helper update failed, will try phone number fallback",
|
`channelsSenders helper update failed, will try phone number fallback: ${String(err)}`,
|
||||||
err,
|
runtime,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,14 +179,14 @@ export async function updateWebhook(
|
||||||
smsUrl: url,
|
smsUrl: url,
|
||||||
smsMethod: method,
|
smsMethod: method,
|
||||||
});
|
});
|
||||||
console.log(success(`✅ Phone webhook set to ${url} (number ${phoneSid})`));
|
logInfo(`✅ Phone webhook set to ${url} (number ${phoneSid})`, runtime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (isVerbose())
|
if (isVerbose())
|
||||||
console.error(
|
logError(
|
||||||
"Incoming phone number webhook update failed; no more fallbacks",
|
`Incoming phone number webhook update failed; no more fallbacks: ${String(err)}`,
|
||||||
err,
|
runtime,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue