Add bot activity tracking system
This commit is contained in:
132
LittleShop/Controllers/BotController.cs
Normal file
132
LittleShop/Controllers/BotController.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using LittleShop.Data;
|
||||
using LittleShop.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace LittleShop.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/bot")]
|
||||
public class BotController : ControllerBase
|
||||
{
|
||||
private readonly LittleShopContext _context;
|
||||
private readonly ILogger<BotController> _logger;
|
||||
|
||||
public BotController(LittleShopContext context, ILogger<BotController> logger)
|
||||
{
|
||||
_context = context;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpPost("activity")]
|
||||
public async Task<IActionResult> TrackActivity([FromBody] BotActivityDto activity)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the default bot ID (TeleBot) - we can enhance this to support multiple bots later
|
||||
var bot = await _context.Bots.FirstOrDefaultAsync(b => b.Type == Enums.BotType.Telegram);
|
||||
if (bot == null)
|
||||
{
|
||||
// Create a default TeleBot entry if not exists
|
||||
bot = new Bot
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
BotKey = "telebot-default",
|
||||
Name = "TeleBot",
|
||||
Type = Enums.BotType.Telegram,
|
||||
Status = Enums.BotStatus.Active,
|
||||
IsActive = true,
|
||||
LastSeenAt = DateTime.UtcNow,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
PlatformUsername = "telebot",
|
||||
PlatformDisplayName = "TeleBot",
|
||||
Version = "1.0.0"
|
||||
};
|
||||
_context.Bots.Add(bot);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
var botActivity = new BotActivity
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
BotId = bot.Id,
|
||||
SessionIdentifier = activity.SessionIdentifier,
|
||||
UserDisplayName = activity.UserDisplayName,
|
||||
ActivityType = activity.ActivityType,
|
||||
ActivityDescription = activity.ActivityDescription,
|
||||
ProductId = activity.ProductId,
|
||||
ProductName = activity.ProductName ?? string.Empty,
|
||||
CategoryName = activity.CategoryName ?? string.Empty,
|
||||
Value = activity.Value,
|
||||
Quantity = activity.Quantity,
|
||||
Platform = activity.Platform,
|
||||
Location = activity.Location,
|
||||
Timestamp = activity.Timestamp ?? DateTime.UtcNow
|
||||
};
|
||||
|
||||
_context.BotActivities.Add(botActivity);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
_logger.LogInformation("Tracked bot activity: {Type} by {User} on {Platform}",
|
||||
activity.ActivityType, activity.UserDisplayName, activity.Platform);
|
||||
|
||||
return Ok(new { success = true, activityId = botActivity.Id });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error tracking bot activity");
|
||||
return StatusCode(500, new { success = false, error = "Failed to track activity" });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("activity/stats")]
|
||||
public async Task<IActionResult> GetActivityStats()
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var oneDayAgo = now.AddDays(-1);
|
||||
var oneHourAgo = now.AddHours(-1);
|
||||
var fiveMinutesAgo = now.AddMinutes(-5);
|
||||
|
||||
var stats = new
|
||||
{
|
||||
TotalActivities = await _context.BotActivities.CountAsync(),
|
||||
Last24Hours = await _context.BotActivities.CountAsync(a => a.Timestamp >= oneDayAgo),
|
||||
LastHour = await _context.BotActivities.CountAsync(a => a.Timestamp >= oneHourAgo),
|
||||
ActiveNow = await _context.BotActivities.CountAsync(a => a.Timestamp >= fiveMinutesAgo),
|
||||
UniqueUsersToday = await _context.BotActivities
|
||||
.Where(a => a.Timestamp >= oneDayAgo)
|
||||
.Select(a => a.SessionIdentifier)
|
||||
.Distinct()
|
||||
.CountAsync(),
|
||||
TopActivities = await _context.BotActivities
|
||||
.Where(a => a.Timestamp >= oneDayAgo)
|
||||
.GroupBy(a => a.ActivityType)
|
||||
.Select(g => new { Type = g.Key, Count = g.Count() })
|
||||
.OrderByDescending(x => x.Count)
|
||||
.Take(5)
|
||||
.ToListAsync()
|
||||
};
|
||||
|
||||
return Ok(stats);
|
||||
}
|
||||
}
|
||||
|
||||
public class BotActivityDto
|
||||
{
|
||||
public string SessionIdentifier { get; set; } = string.Empty;
|
||||
public string UserDisplayName { get; set; } = string.Empty;
|
||||
public string ActivityType { get; set; } = string.Empty;
|
||||
public string ActivityDescription { get; set; } = string.Empty;
|
||||
public Guid? ProductId { get; set; }
|
||||
public string? ProductName { get; set; }
|
||||
public string? CategoryName { get; set; }
|
||||
public decimal? Value { get; set; }
|
||||
public int? Quantity { get; set; }
|
||||
public string Platform { get; set; } = "Unknown";
|
||||
public string Location { get; set; } = "Unknown";
|
||||
public DateTime? Timestamp { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user