From fe4c627432f7805ff5c9c7a0ea2adeda19e4c8fe Mon Sep 17 00:00:00 2001 From: Xinhua Gu Date: Fri, 27 Feb 2026 21:36:31 +0100 Subject: [PATCH] fix(voice-call): speak inbound greeting for twilio answered calls --- extensions/voice-call/src/manager.test.ts | 39 ++++++++++++----------- extensions/voice-call/src/manager.ts | 6 ---- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/extensions/voice-call/src/manager.test.ts b/extensions/voice-call/src/manager.test.ts index 06bb380c916..d8f9d27a8b7 100644 --- a/extensions/voice-call/src/manager.test.ts +++ b/extensions/voice-call/src/manager.test.ts @@ -111,28 +111,31 @@ describe("CallManager", () => { expect(manager.getCallByProviderCallId("request-uuid")).toBeUndefined(); }); - it("speaks initial message on answered for notify mode (non-Twilio)", async () => { - const { manager, provider } = createManagerHarness(); + it.each(["plivo", "twilio"] as const)( + "speaks initial message on answered for notify mode (%s)", + async (providerName) => { + const { manager, provider } = createManagerHarness({}, new FakeProvider(providerName)); - const { callId, success } = await manager.initiateCall("+15550000002", undefined, { - message: "Hello there", - mode: "notify", - }); - expect(success).toBe(true); + const { callId, success } = await manager.initiateCall("+15550000002", undefined, { + message: "Hello there", + mode: "notify", + }); + expect(success).toBe(true); - manager.processEvent({ - id: "evt-2", - type: "call.answered", - callId, - providerCallId: "call-uuid", - timestamp: Date.now(), - }); + manager.processEvent({ + id: `evt-2-${providerName}`, + type: "call.answered", + callId, + providerCallId: "call-uuid", + timestamp: Date.now(), + }); - await new Promise((resolve) => setTimeout(resolve, 0)); + await new Promise((resolve) => setTimeout(resolve, 0)); - expect(provider.playTtsCalls).toHaveLength(1); - expect(provider.playTtsCalls[0]?.text).toBe("Hello there"); - }); + expect(provider.playTtsCalls).toHaveLength(1); + expect(provider.playTtsCalls[0]?.text).toBe("Hello there"); + }, + ); it("rejects inbound calls with missing caller ID when allowlist enabled", () => { const { manager, provider } = createManagerHarness({ diff --git a/extensions/voice-call/src/manager.ts b/extensions/voice-call/src/manager.ts index 927899f325c..e93e77f2199 100644 --- a/extensions/voice-call/src/manager.ts +++ b/extensions/voice-call/src/manager.ts @@ -166,12 +166,6 @@ export class CallManager { return; } - // Twilio has provider-specific state for speaking ( fallback) and can - // fail for inbound calls; keep existing Twilio behavior unchanged. - if (this.provider.name === "twilio") { - return; - } - void this.speakInitialMessage(call.providerCallId); }