fix: show google meet twilio call diagnostics

This commit is contained in:
Peter Steinberger
2026-05-01 12:52:24 +01:00
parent 8e5c2efb8d
commit c6a12a6fd2
5 changed files with 57 additions and 1 deletions

View File

@@ -20,6 +20,7 @@ Docs: https://docs.openclaw.ai
### Fixes
- Google Meet/Twilio: show delegated voice call ID, DTMF, and intro-greeting state in `googlemeet doctor`, and avoid claiming DTMF was sent when no Meet PIN sequence was configured. Refs #72478. Thanks @DougButdorf.
- Voice Call/Twilio: send notify-mode initial TwiML directly in the outbound create-call request while keeping conversation and pre-connect DTMF calls webhook-driven, so one-shot notify calls do not depend on a first-answer webhook fetch. Supersedes #72758. Thanks @tyshepps.
- Discord/Slack: defer status-reaction cleanup until run finalization so queued, thinking, tool, and terminal reactions no longer flicker during normal progress updates. (#75582)
- Discord/voice: leave Discord voice off for text-only configs unless `channels.discord.voice` is explicitly configured, avoiding default `GuildVoiceStates` traffic and idle gateway CPU pressure for bots that do not use `/vc`. Fixes #73753; refs #74044. Thanks @sanchezm86 and @SecureCloudProjO.

View File

@@ -1435,6 +1435,8 @@ before entering the PIN.
If the phone call is created but the Meet roster never shows the dial-in
participant:
- Run `openclaw googlemeet doctor <session-id>` to confirm the delegated Twilio
call ID, whether DTMF was queued, and whether the intro greeting was requested.
- Run `openclaw voicecall status --call-id <id>` and confirm the call is still
active.
- Run `openclaw voicecall tail` and check that Twilio webhooks are arriving at

View File

@@ -727,6 +727,48 @@ describe("google-meet CLI", () => {
}
});
it("prints Twilio session doctor output", async () => {
const stdout = captureStdout();
try {
await setupCli({
runtime: {
status: () => ({
found: true,
session: {
id: "meet_1",
url: "https://meet.google.com/abc-defg-hij",
state: "active",
transport: "twilio",
mode: "realtime",
participantIdentity: "Twilio phone participant",
createdAt: "2026-04-25T00:00:00.000Z",
updatedAt: "2026-04-25T00:00:01.000Z",
realtime: { enabled: true, provider: "openai", toolPolicy: "safe-read-only" },
twilio: {
dialInNumber: "+15551234567",
pinProvided: true,
dtmfSequence: "ww123456#",
voiceCallId: "call-1",
dtmfSent: true,
introSent: true,
},
notes: [],
},
}),
},
}).parseAsync(["googlemeet", "doctor", "meet_1"], { from: "user" });
expect(stdout.output()).toContain("session: meet_1");
expect(stdout.output()).toContain("transport: twilio");
expect(stdout.output()).toContain("twilio dial-in: +15551234567");
expect(stdout.output()).toContain("voice call id: call-1");
expect(stdout.output()).toContain("dtmf sent: yes");
expect(stdout.output()).toContain("intro sent: yes");
expect(stdout.output()).not.toContain("audio input active:");
} finally {
stdout.restore();
}
});
it("verifies OAuth refresh without printing secrets", async () => {
const fetchMock = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) =>
jsonResponse({

View File

@@ -256,6 +256,15 @@ function writeDoctorStatus(status: ReturnType<GoogleMeetRuntime["status"]>): voi
writeStdoutLine("state: %s", session.state);
writeStdoutLine("transport: %s", session.transport);
writeStdoutLine("mode: %s", session.mode);
if (session.twilio) {
writeStdoutLine("twilio dial-in: %s", session.twilio.dialInNumber);
writeStdoutLine("voice call id: %s", formatOptional(session.twilio.voiceCallId));
writeStdoutLine("dtmf sent: %s", formatBoolean(session.twilio.dtmfSent));
writeStdoutLine("intro sent: %s", formatBoolean(session.twilio.introSent));
}
if (!session.chrome) {
continue;
}
writeStdoutLine("node: %s", session.chrome?.nodeId ?? "local/none");
writeStdoutLine("audio bridge: %s", session.chrome?.audioBridge?.type ?? "none");
writeStdoutLine(

View File

@@ -435,7 +435,9 @@ export class GoogleMeetRuntime {
}
session.notes.push(
this.params.config.voiceCall.enabled
? "Twilio transport delegated the call to the voice-call plugin and sent configured DTMF."
? dtmfSequence
? "Twilio transport delegated the call to the voice-call plugin and queued configured DTMF."
: "Twilio transport delegated the call to the voice-call plugin without configured DTMF."
: "Twilio transport is an explicit dial plan; voice-call delegation is disabled.",
);
}