diff --git a/src/OpenClaw.Shared/ChannelsSnapshot.cs b/src/OpenClaw.Shared/ChannelsSnapshot.cs
index 721aaa3c5..a598f69ad 100644
--- a/src/OpenClaw.Shared/ChannelsSnapshot.cs
+++ b/src/OpenClaw.Shared/ChannelsSnapshot.cs
@@ -234,7 +234,7 @@ public sealed class IMessageChannelStatus
// ─── Web login (QR linking) ──────────────────────────────────────────────────
-/// Result of web.login.start — a QR or status for a channel.
+/// Result of web.login.start - a QR or status for a channel.
public sealed class WebLoginStartResult
{
public string? Message { get; init; }
@@ -248,7 +248,7 @@ public sealed class WebLoginStartResult
public string? RawResponse { get; init; }
}
-/// Result of web.login.wait — long-poll outcome.
+/// Result of web.login.wait - long-poll outcome.
public sealed class WebLoginWaitResult
{
public string? Message { get; init; }
diff --git a/src/OpenClaw.Shared/OpenClawGatewayClient.cs b/src/OpenClaw.Shared/OpenClawGatewayClient.cs
index 2903700f4..5a6c8cd21 100644
--- a/src/OpenClaw.Shared/OpenClawGatewayClient.cs
+++ b/src/OpenClaw.Shared/OpenClawGatewayClient.cs
@@ -1219,12 +1219,13 @@ public async Task LogoutChannelAsync(string channelName, int timeoutMs = 1
"web.login.start",
new { force, timeoutMs },
timeoutMs + 5000);
+ var result = ParseWebLoginResponse(response);
return new WebLoginStartResult
{
- Message = response.ValueKind == JsonValueKind.Object && response.TryGetProperty("message", out var m) && m.ValueKind == JsonValueKind.String ? m.GetString() : null,
- QrDataUrl = response.ValueKind == JsonValueKind.Object && response.TryGetProperty("qrDataUrl", out var q) && q.ValueKind == JsonValueKind.String ? q.GetString() : null,
- Connected = response.ValueKind == JsonValueKind.Object && response.TryGetProperty("connected", out var c) && c.ValueKind == JsonValueKind.True,
- RawResponse = response.ValueKind != JsonValueKind.Undefined ? response.GetRawText() : null,
+ Message = result.Message,
+ QrDataUrl = result.QrDataUrl,
+ Connected = result.Connected,
+ RawResponse = result.RawResponse,
};
}
catch (Exception ex)
@@ -1251,12 +1252,13 @@ public async Task LogoutChannelAsync(string channelName, int timeoutMs = 1
"web.login.wait",
new { currentQrDataUrl, timeoutMs },
timeoutMs + 5000);
+ var result = ParseWebLoginResponse(response);
return new WebLoginWaitResult
{
- Message = response.ValueKind == JsonValueKind.Object && response.TryGetProperty("message", out var m) && m.ValueKind == JsonValueKind.String ? m.GetString() : null,
- QrDataUrl = response.ValueKind == JsonValueKind.Object && response.TryGetProperty("qrDataUrl", out var q) && q.ValueKind == JsonValueKind.String ? q.GetString() : null,
- Connected = response.ValueKind == JsonValueKind.Object && response.TryGetProperty("connected", out var c) && c.ValueKind == JsonValueKind.True,
- RawResponse = response.ValueKind != JsonValueKind.Undefined ? response.GetRawText() : null,
+ Message = result.Message,
+ QrDataUrl = result.QrDataUrl,
+ Connected = result.Connected,
+ RawResponse = result.RawResponse,
};
}
catch (Exception ex)
@@ -1270,6 +1272,17 @@ public async Task LogoutChannelAsync(string channelName, int timeoutMs = 1
}
}
+ private static WebLoginResponse ParseWebLoginResponse(JsonElement response)
+ {
+ return new WebLoginResponse(
+ response.ValueKind == JsonValueKind.Object && response.TryGetProperty("message", out var m) && m.ValueKind == JsonValueKind.String ? m.GetString() : null,
+ response.ValueKind == JsonValueKind.Object && response.TryGetProperty("qrDataUrl", out var q) && q.ValueKind == JsonValueKind.String ? q.GetString() : null,
+ response.ValueKind == JsonValueKind.Object && response.TryGetProperty("connected", out var c) && c.ValueKind == JsonValueKind.True,
+ response.ValueKind != JsonValueKind.Undefined ? response.GetRawText() : null);
+ }
+
+ private readonly record struct WebLoginResponse(string? Message, string? QrDataUrl, bool Connected, string? RawResponse);
+
private async Task SendConnectMessageAsync(string? nonce = null)
{
var requestId = Guid.NewGuid().ToString();