Add bot activity tracking system

This commit is contained in:
2025-09-25 01:28:56 +01:00
parent d6f8a5e697
commit ac4fe688d9
3 changed files with 306 additions and 2 deletions

View File

@@ -26,14 +26,16 @@ namespace TeleBot.Handlers
private readonly ILittleShopService _shopService;
private readonly IPrivacyService _privacyService;
private readonly IProductCarouselService _carouselService;
private readonly IBotActivityTracker _activityTracker;
private readonly IConfiguration _configuration;
private readonly ILogger<CallbackHandler> _logger;
public CallbackHandler(
ISessionManager sessionManager,
ILittleShopService shopService,
IPrivacyService privacyService,
IProductCarouselService carouselService,
IBotActivityTracker activityTracker,
IConfiguration configuration,
ILogger<CallbackHandler> logger)
{
@@ -41,6 +43,7 @@ namespace TeleBot.Handlers
_shopService = shopService;
_privacyService = privacyService;
_carouselService = carouselService;
_activityTracker = activityTracker;
_configuration = configuration;
_logger = logger;
}
@@ -232,6 +235,13 @@ namespace TeleBot.Handlers
private async Task HandleBrowse(ITelegramBotClient bot, Message message, UserSession session)
{
// Track browsing activity
await _activityTracker.TrackActivityAsync(
message.Chat,
ActivityTypes.Browse,
"Browsing categories"
);
var categories = await _shopService.GetCategoriesAsync();
await bot.EditMessageTextAsync(
@@ -249,6 +259,13 @@ namespace TeleBot.Handlers
var categories = await _shopService.GetCategoriesAsync();
var category = categories.FirstOrDefault(c => c.Id == categoryId);
var products = await _shopService.GetProductsAsync(categoryId, 1);
// Track category view
await _activityTracker.TrackActivityAsync(
message.Chat,
ActivityTypes.ViewProduct,
$"Viewing category: {category?.Name ?? "Unknown"}"
);
// Edit the original message to show category header (bigger, more prominent)
var headerText = $"**{category?.Name ?? "Unknown Category"} PRODUCTS**\n\nBrowse individual products below:";
@@ -334,7 +351,15 @@ namespace TeleBot.Handlers
await bot.AnswerCallbackQueryAsync("", "Product not found", showAlert: true);
return;
}
// Track product view
await _activityTracker.TrackActivityAsync(
message.Chat,
ActivityTypes.ViewProduct,
$"Viewing product: {product.Name}",
product
);
// Store current product in temp data for quantity selection
session.TempData["current_product"] = productId;
session.TempData["current_quantity"] = 1;
@@ -407,6 +432,16 @@ namespace TeleBot.Handlers
session.Cart.AddItem(productId, itemName, price, quantity, multiBuyId, selectedVariant);
// Track add to cart action
await _activityTracker.TrackActivityAsync(
callbackQuery.Message!.Chat,
ActivityTypes.AddToCart,
$"Added to cart: {itemName}",
product,
price * quantity,
quantity
);
await bot.AnswerCallbackQueryAsync(
callbackQuery.Id,
$"✅ Added {quantity}x {itemName} to cart",
@@ -419,6 +454,15 @@ namespace TeleBot.Handlers
private async Task HandleViewCart(ITelegramBotClient bot, Message message, UserSession session)
{
// Track cart view
await _activityTracker.TrackActivityAsync(
message.Chat,
ActivityTypes.ViewCart,
$"Viewing cart with {session.Cart.Items.Count} items",
null,
session.Cart.GetTotalAmount()
);
await bot.EditMessageTextAsync(
message.Chat.Id,
message.MessageId,
@@ -499,6 +543,16 @@ namespace TeleBot.Handlers
// Add to cart with base product
session.Cart.AddItem(productId, product.Name, product.Price, quantity, null, null);
// Track quick buy action
await _activityTracker.TrackActivityAsync(
callbackQuery.Message!.Chat,
ActivityTypes.AddToCart,
$"Quick buy: {product.Name}",
product,
product.Price * quantity,
quantity
);
await bot.AnswerCallbackQueryAsync(
callbackQuery.Id,
$"✅ Added {quantity}x {product.Name} to cart",
@@ -623,6 +677,15 @@ namespace TeleBot.Handlers
return;
}
// Track checkout initiation
await _activityTracker.TrackActivityAsync(
message.Chat,
ActivityTypes.Checkout,
$"Starting checkout with {session.Cart.Items.Count} items",
null,
session.Cart.GetTotalAmount()
);
// Initialize order flow
session.OrderFlow = new OrderFlowData
{
@@ -876,6 +939,13 @@ namespace TeleBot.Handlers
private async Task HandleViewOrders(ITelegramBotClient bot, Message message, UserSession session, User telegramUser)
{
// Track view orders action
await _activityTracker.TrackActivityAsync(
message.Chat,
ActivityTypes.ViewOrders,
"Viewing order history"
);
// Use new customer-based order lookup
var orders = await _shopService.GetCustomerOrdersAsync(
telegramUser.Id,

View File

@@ -0,0 +1,102 @@
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Telegram.Bot.Types;
using LittleShop.Client.Models;
namespace TeleBot.Services
{
public interface IBotActivityTracker
{
Task TrackActivityAsync(
Chat chat,
string activityType,
string description,
Product? product = null,
decimal? value = null,
int? quantity = null);
}
public class BotActivityTracker : IBotActivityTracker
{
private readonly HttpClient _httpClient;
private readonly IConfiguration _configuration;
private readonly ILogger<BotActivityTracker> _logger;
private readonly string _littleShopUrl;
public BotActivityTracker(
HttpClient httpClient,
IConfiguration configuration,
ILogger<BotActivityTracker> logger)
{
_httpClient = httpClient;
_configuration = configuration;
_logger = logger;
_littleShopUrl = configuration["LittleShop:BaseUrl"] ?? "http://littleshop-admin:8080";
}
public async Task TrackActivityAsync(
Chat chat,
string activityType,
string description,
Product? product = null,
decimal? value = null,
int? quantity = null)
{
try
{
var activity = new
{
SessionIdentifier = $"telegram_{chat.Id}",
UserDisplayName = chat.Username ?? $"{chat.FirstName} {chat.LastName}".Trim(),
ActivityType = activityType,
ActivityDescription = description,
ProductId = product?.Id,
ProductName = product?.Name,
CategoryName = product?.CategoryName,
Value = value,
Quantity = quantity,
Platform = "Telegram",
Location = "Unknown",
Timestamp = DateTime.UtcNow
};
var json = JsonSerializer.Serialize(activity);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(
$"{_littleShopUrl}/api/bot/activity",
content);
if (!response.IsSuccessStatusCode)
{
_logger.LogWarning("Failed to track activity: {StatusCode}", response.StatusCode);
}
}
catch (Exception ex)
{
// Don't let tracking errors break the main flow
_logger.LogError(ex, "Error tracking bot activity");
}
}
}
public class ActivityTypes
{
public const string Browse = "Browse";
public const string ViewProduct = "ViewProduct";
public const string AddToCart = "AddToCart";
public const string RemoveFromCart = "RemoveFromCart";
public const string ViewCart = "ViewCart";
public const string Checkout = "Checkout";
public const string SelectVariant = "SelectVariant";
public const string ViewOrders = "ViewOrders";
public const string Search = "Search";
public const string Help = "Help";
public const string Start = "Start";
}
}