136 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
package handler
 | 
						|
 | 
						|
import (
 | 
						|
	"net/http"
 | 
						|
	"strconv"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/gin-gonic/gin"
 | 
						|
 | 
						|
	"github.com/Tencent/WeKnora/internal/errors"
 | 
						|
	"github.com/Tencent/WeKnora/internal/logger"
 | 
						|
	"github.com/Tencent/WeKnora/internal/types/interfaces"
 | 
						|
)
 | 
						|
 | 
						|
// MessageHandler handles HTTP requests related to messages within chat sessions
 | 
						|
// It provides endpoints for loading and managing message history
 | 
						|
type MessageHandler struct {
 | 
						|
	MessageService interfaces.MessageService // Service that implements message business logic
 | 
						|
}
 | 
						|
 | 
						|
// NewMessageHandler creates a new message handler instance with the required service
 | 
						|
// Parameters:
 | 
						|
//   - messageService: Service that implements message business logic
 | 
						|
//
 | 
						|
// Returns a pointer to a new MessageHandler
 | 
						|
func NewMessageHandler(messageService interfaces.MessageService) *MessageHandler {
 | 
						|
	return &MessageHandler{
 | 
						|
		MessageService: messageService,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// LoadMessages handles requests to load message history
 | 
						|
// It supports both loading recent messages and loading messages before a specific timestamp
 | 
						|
// This endpoint is used for scrolling through conversation history
 | 
						|
func (h *MessageHandler) LoadMessages(c *gin.Context) {
 | 
						|
	ctx := c.Request.Context()
 | 
						|
 | 
						|
	logger.Info(ctx, "Start loading messages")
 | 
						|
 | 
						|
	// Get path parameters and query parameters
 | 
						|
	sessionID := c.Param("session_id")
 | 
						|
	limit := c.DefaultQuery("limit", "20")
 | 
						|
	beforeTimeStr := c.DefaultQuery("before_time", "")
 | 
						|
 | 
						|
	logger.Infof(ctx, "Loading messages params, session ID: %s, limit: %s, before time: %s",
 | 
						|
		sessionID, limit, beforeTimeStr)
 | 
						|
 | 
						|
	// Parse limit parameter with fallback to default
 | 
						|
	limitInt, err := strconv.Atoi(limit)
 | 
						|
	if err != nil {
 | 
						|
		logger.Warnf(ctx, "Invalid limit value, using default value 20, input: %s", limit)
 | 
						|
		limitInt = 20
 | 
						|
	}
 | 
						|
 | 
						|
	// If no beforeTime is provided, retrieve the most recent messages
 | 
						|
	if beforeTimeStr == "" {
 | 
						|
		logger.Infof(ctx, "Getting recent messages for session, session ID: %s, limit: %d", sessionID, limitInt)
 | 
						|
		messages, err := h.MessageService.GetRecentMessagesBySession(ctx, sessionID, limitInt)
 | 
						|
		if err != nil {
 | 
						|
			logger.ErrorWithFields(ctx, err, nil)
 | 
						|
			c.Error(errors.NewInternalServerError(err.Error()))
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		logger.Infof(
 | 
						|
			ctx,
 | 
						|
			"Successfully retrieved recent messages, session ID: %s, message count: %d",
 | 
						|
			sessionID, len(messages),
 | 
						|
		)
 | 
						|
		c.JSON(http.StatusOK, gin.H{
 | 
						|
			"success": true,
 | 
						|
			"data":    messages,
 | 
						|
		})
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// If beforeTime is provided, parse the timestamp
 | 
						|
	beforeTime, err := time.Parse(time.RFC3339Nano, beforeTimeStr)
 | 
						|
	if err != nil {
 | 
						|
		logger.Errorf(
 | 
						|
			ctx,
 | 
						|
			"Invalid time format, please use RFC3339Nano format, err: %v, beforeTimeStr: %s",
 | 
						|
			err, beforeTimeStr,
 | 
						|
		)
 | 
						|
		c.Error(errors.NewBadRequestError("Invalid time format, please use RFC3339Nano format"))
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// Retrieve messages before the specified timestamp
 | 
						|
	logger.Infof(ctx, "Getting messages before specific time, session ID: %s, before time: %s, limit: %d",
 | 
						|
		sessionID, beforeTime.Format(time.RFC3339Nano), limitInt)
 | 
						|
	messages, err := h.MessageService.GetMessagesBySessionBeforeTime(ctx, sessionID, beforeTime, limitInt)
 | 
						|
	if err != nil {
 | 
						|
		logger.ErrorWithFields(ctx, err, nil)
 | 
						|
		c.Error(errors.NewInternalServerError(err.Error()))
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	logger.Infof(
 | 
						|
		ctx,
 | 
						|
		"Successfully retrieved messages before time, session ID: %s, message count: %d",
 | 
						|
		sessionID, len(messages),
 | 
						|
	)
 | 
						|
	c.JSON(http.StatusOK, gin.H{
 | 
						|
		"success": true,
 | 
						|
		"data":    messages,
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
// DeleteMessage handles requests to delete a message from a session
 | 
						|
// It requires both session ID and message ID to identify the specific message to delete
 | 
						|
func (h *MessageHandler) DeleteMessage(c *gin.Context) {
 | 
						|
	ctx := c.Request.Context()
 | 
						|
 | 
						|
	logger.Info(ctx, "Start deleting message")
 | 
						|
 | 
						|
	// Get path parameters for session and message identification
 | 
						|
	sessionID := c.Param("session_id")
 | 
						|
	messageID := c.Param("id")
 | 
						|
 | 
						|
	logger.Infof(ctx, "Deleting message, session ID: %s, message ID: %s", sessionID, messageID)
 | 
						|
 | 
						|
	// Delete the message using the message service
 | 
						|
	if err := h.MessageService.DeleteMessage(ctx, sessionID, messageID); err != nil {
 | 
						|
		logger.ErrorWithFields(ctx, err, nil)
 | 
						|
		c.Error(errors.NewInternalServerError(err.Error()))
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	logger.Infof(ctx, "Message deleted successfully, session ID: %s, message ID: %s", sessionID, messageID)
 | 
						|
	c.JSON(http.StatusOK, gin.H{
 | 
						|
		"success": true,
 | 
						|
		"message": "Message deleted successfully",
 | 
						|
	})
 | 
						|
}
 |