feat: Bot management improvements with wallet configuration and duplicate detection

This commit is contained in:
2025-10-10 12:34:00 +01:00
parent 91000035f5
commit 7008a95df3
9 changed files with 408 additions and 13 deletions

View File

@@ -52,11 +52,37 @@ namespace TeleBot.Services
{
// Check if bot key exists in configuration
_botKey = _configuration["BotManager:ApiKey"];
if (string.IsNullOrEmpty(_botKey))
{
// Register new bot
await RegisterBotAsync();
// Try to find existing bot registration by Telegram username first
var botUsername = await GetTelegramBotUsernameAsync();
if (!string.IsNullOrEmpty(botUsername))
{
var existingBot = await FindExistingBotByPlatformAsync(botUsername);
if (existingBot != null)
{
_logger.LogInformation("Found existing bot registration for @{Username} (ID: {BotId}). Using existing bot.",
botUsername, existingBot.Id);
_botKey = existingBot.BotKey;
_botId = existingBot.Id;
// Update platform info in case it changed
await UpdatePlatformInfoAsync();
}
else
{
_logger.LogInformation("No existing bot found for @{Username}. Registering new bot.", botUsername);
await RegisterBotAsync();
}
}
else
{
_logger.LogWarning("Could not determine bot username. Registering new bot.");
await RegisterBotAsync();
}
}
else
{
@@ -125,18 +151,21 @@ namespace TeleBot.Services
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"{apiUrl}/api/bots/register", content);
if (response.IsSuccessStatusCode)
{
var responseJson = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<BotRegistrationResponse>(responseJson);
_botKey = result?.BotKey;
_botId = result?.BotId;
_logger.LogInformation("Bot registered successfully. Bot ID: {BotId}", _botId);
_logger.LogWarning("IMPORTANT: Save this bot key securely: {BotKey}", _botKey);
// Update platform info immediately after registration
await UpdatePlatformInfoAsync();
// Save bot key to configuration or secure storage
// In production, this should be saved securely
}
@@ -423,6 +452,118 @@ namespace TeleBot.Services
_settingsSyncTimer?.Dispose();
}
private async Task<string?> GetTelegramBotUsernameAsync()
{
try
{
var botToken = _configuration["Telegram:BotToken"];
if (string.IsNullOrEmpty(botToken) || botToken == "YOUR_BOT_TOKEN_HERE")
{
_logger.LogWarning("Bot token not configured in appsettings.json");
return null;
}
// Call Telegram API to get bot info
var response = await _httpClient.GetAsync($"https://api.telegram.org/bot{botToken}/getMe");
if (response.IsSuccessStatusCode)
{
var responseJson = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<TelegramGetMeResponse>(responseJson);
return result?.Result?.Username;
}
else
{
_logger.LogWarning("Failed to get bot info from Telegram: {StatusCode}", response.StatusCode);
return null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting Telegram bot username");
return null;
}
}
private async Task<BotDto?> FindExistingBotByPlatformAsync(string platformUsername)
{
try
{
var apiUrl = _configuration["LittleShop:ApiUrl"];
const int telegramBotType = 0; // BotType.Telegram enum value
var response = await _httpClient.GetAsync($"{apiUrl}/api/bots/by-platform/{telegramBotType}/{platformUsername}");
if (response.IsSuccessStatusCode)
{
var responseJson = await response.Content.ReadAsStringAsync();
var bot = JsonSerializer.Deserialize<BotDto>(responseJson);
return bot;
}
else if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return null; // Bot not found - this is expected for first registration
}
else
{
_logger.LogWarning("Failed to check for existing bot: {StatusCode}", response.StatusCode);
return null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error finding existing bot by platform username");
return null;
}
}
private async Task UpdatePlatformInfoAsync()
{
try
{
var apiUrl = _configuration["LittleShop:ApiUrl"];
var botToken = _configuration["Telegram:BotToken"];
if (string.IsNullOrEmpty(botToken) || string.IsNullOrEmpty(_botKey))
return;
// Get bot info from Telegram
var telegramResponse = await _httpClient.GetAsync($"https://api.telegram.org/bot{botToken}/getMe");
if (!telegramResponse.IsSuccessStatusCode)
return;
var telegramJson = await telegramResponse.Content.ReadAsStringAsync();
var telegramResult = JsonSerializer.Deserialize<TelegramGetMeResponse>(telegramJson);
if (telegramResult?.Result == null)
return;
// Update platform info in LittleShop
var updateData = new
{
PlatformUsername = telegramResult.Result.Username,
PlatformDisplayName = telegramResult.Result.FirstName ?? telegramResult.Result.Username,
PlatformId = telegramResult.Result.Id.ToString()
};
var json = JsonSerializer.Serialize(updateData);
var content = new StringContent(json, Encoding.UTF8, "application/json");
_httpClient.DefaultRequestHeaders.Clear();
_httpClient.DefaultRequestHeaders.Add("X-Bot-Key", _botKey);
var response = await _httpClient.PutAsync($"{apiUrl}/api/bots/platform-info", content);
if (response.IsSuccessStatusCode)
{
_logger.LogInformation("Updated platform info for @{Username}", telegramResult.Result.Username);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to update platform info");
}
}
// DTOs for API responses
private class BotRegistrationResponse
{
@@ -435,11 +576,29 @@ namespace TeleBot.Services
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public string BotKey { get; set; } = string.Empty;
}
private class SessionDto
{
public Guid Id { get; set; }
}
private class TelegramGetMeResponse
{
public bool Ok { get; set; }
public TelegramBotInfo? Result { get; set; }
}
private class TelegramBotInfo
{
public long Id { get; set; }
public bool IsBot { get; set; }
public string FirstName { get; set; } = string.Empty;
public string Username { get; set; } = string.Empty;
public bool? CanJoinGroups { get; set; }
public bool? CanReadAllGroupMessages { get; set; }
public bool? SupportsInlineQueries { get; set; }
}
}
}