Switch MAX bridge to PyMax only
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
@@ -6,6 +7,7 @@ using QMax.Api.Configuration;
|
||||
using QMax.Api.Contracts;
|
||||
using QMax.Api.Data;
|
||||
using QMax.Api.Data.Entities;
|
||||
using QMax.Api.Infrastructure.Hubs;
|
||||
using QMax.Api.Infrastructure.Max;
|
||||
using QMax.Api.Services;
|
||||
|
||||
@@ -18,6 +20,7 @@ public sealed class MaxController(
|
||||
IMaxBridgeClient maxBridge,
|
||||
MaxBridgeSyncService syncService,
|
||||
QMaxDbContext db,
|
||||
IHubContext<QMaxHub> hubContext,
|
||||
IOptions<QMaxOptions> options) : ControllerBase
|
||||
{
|
||||
private readonly QMaxOptions _options = options.Value;
|
||||
@@ -82,6 +85,7 @@ public sealed class MaxController(
|
||||
state.LastError = status.LastError;
|
||||
state.UpdatedAt = DateTimeOffset.UtcNow;
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
await hubContext.Clients.All.SendAsync("MaxStatusChanged", ToDto(status), cancellationToken);
|
||||
}
|
||||
|
||||
private static MaxBridgeStatusDto ToDto(MaxBridgeStatus status)
|
||||
|
||||
@@ -15,7 +15,7 @@ public sealed class MockMaxBridgeClient : IMaxBridgeClient
|
||||
"max",
|
||||
"MAX",
|
||||
false,
|
||||
"Mock mode is active. Switch QMax:MaxMode to Playwright for real web.max.ru.",
|
||||
"Mock mode is active. Switch QMax:MaxMode to Worker and use qmax-pymax-worker for real MAX traffic.",
|
||||
DateTimeOffset.UtcNow)
|
||||
])
|
||||
];
|
||||
@@ -110,6 +110,6 @@ public sealed class MockMaxBridgeClient : IMaxBridgeClient
|
||||
|
||||
private static string MockChatUrl(string externalChatId)
|
||||
{
|
||||
return $"https://web.max.ru/mock/{Uri.EscapeDataString(externalChatId)}";
|
||||
return $"pymax://mock/{Uri.EscapeDataString(externalChatId)}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public sealed class WorkerMaxBridgeClient(
|
||||
public async Task<IReadOnlyList<MaxChatUpdate>> FetchUpdatesAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return await SendAsync<IReadOnlyList<MaxChatUpdate>>(HttpMethod.Get, "/updates", null, cancellationToken)
|
||||
?? Array.Empty<MaxChatUpdate>();
|
||||
?? throw new InvalidOperationException("MAX worker returned an empty updates response.");
|
||||
}
|
||||
|
||||
public async Task<MaxChatUpdate?> FetchChatHistoryAsync(string externalChatId, string? chatUrl, CancellationToken cancellationToken)
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using QMax.Api.Configuration;
|
||||
using QMax.Api.Contracts;
|
||||
using QMax.Api.Data;
|
||||
using QMax.Api.Data.Entities;
|
||||
using QMax.Api.Infrastructure.Hubs;
|
||||
@@ -29,10 +32,41 @@ public sealed class MaxBridgeSyncService(
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogWarning(ex, "MAX sync failed.");
|
||||
await PublishCurrentMaxStatusAsync(cancellationToken);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PublishCurrentMaxStatusAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var status = await maxBridgeClient.GetStatusAsync(cancellationToken);
|
||||
await using var scope = scopeFactory.CreateAsyncScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<QMaxDbContext>();
|
||||
var options = scope.ServiceProvider.GetRequiredService<IOptions<QMaxOptions>>().Value;
|
||||
var state = await db.MaxAccountStates.FirstOrDefaultAsync(x => x.Id == 1, cancellationToken);
|
||||
if (state is null)
|
||||
{
|
||||
state = new MaxAccountState { Id = 1 };
|
||||
db.MaxAccountStates.Add(state);
|
||||
}
|
||||
|
||||
state.PhoneNumber = options.MaxPhoneNumber;
|
||||
state.Status = status.Status;
|
||||
state.IsAuthorized = status.IsAuthorized;
|
||||
state.LastUrl = status.Url;
|
||||
state.LastError = status.LastError;
|
||||
state.UpdatedAt = DateTimeOffset.UtcNow;
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
await hubContext.Clients.All.SendAsync("MaxStatusChanged", ToDto(status), cancellationToken);
|
||||
}
|
||||
catch (Exception statusError)
|
||||
{
|
||||
logger.LogDebug(statusError, "Unable to publish current MAX status after sync failure.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<int> SyncChatHistoryAsync(string externalChatId, string? chatUrl, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(externalChatId))
|
||||
@@ -1387,6 +1421,11 @@ public sealed class MaxBridgeSyncService(
|
||||
};
|
||||
}
|
||||
|
||||
private static MaxBridgeStatusDto ToDto(MaxBridgeStatus status)
|
||||
{
|
||||
return new MaxBridgeStatusDto(status.Mode, status.IsAuthorized, status.LoginStage, status.Status, status.Url, status.Title, status.LastError, status.UpdatedAt);
|
||||
}
|
||||
|
||||
private sealed record LastKnownMessageSnapshot(
|
||||
MessageDirection Direction,
|
||||
string? Text,
|
||||
|
||||
Reference in New Issue
Block a user