Files
xiaohongshu-mcp/handlers.go
zy aee7b321d3 feat: 添加获取小红书首页 Feeds 列表的 HTTP 和 MCP 接口
- 在 service.go 中添加 ListFeeds 业务逻辑,复用 xiaohongshu 包功能
- 添加 HTTP 接口 GET /api/v1/feeds/list
- 添加 MCP tool: list_feeds,支持通过 MCP 协议获取 Feeds
- 返回结构化的 Feeds 数据,包含列表和数量统计
- 更新 .gitignore 忽略构建产物和测试脚本
- 更新项目配置,添加 chmod 权限

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-12 01:22:19 +08:00

142 lines
3.6 KiB
Go

package main
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
// LoginWaitRequest 等待登录请求
type LoginWaitRequest struct {
Timeout int `json:"timeout"`
}
// ErrorResponse 错误响应
type ErrorResponse struct {
Error string `json:"error"`
Code string `json:"code"`
Details any `json:"details,omitempty"`
}
// SuccessResponse 成功响应
type SuccessResponse struct {
Success bool `json:"success"`
Data any `json:"data"`
Message string `json:"message,omitempty"`
}
// respondError 返回错误响应
func respondError(c *gin.Context, statusCode int, code, message string, details any) {
response := ErrorResponse{
Error: message,
Code: code,
Details: details,
}
logrus.Errorf("%s %s %s %d", c.Request.Method, c.Request.URL.Path,
c.GetString("account"), statusCode)
c.JSON(statusCode, response)
}
// respondSuccess 返回成功响应
func respondSuccess(c *gin.Context, data any, message string) {
response := SuccessResponse{
Success: true,
Data: data,
Message: message,
}
logrus.Infof("%s %s %s %d", c.Request.Method, c.Request.URL.Path,
c.GetString("account"), http.StatusOK)
c.JSON(http.StatusOK, response)
}
// XiaohongshuService 全局服务实例
var xiaohongshuService = NewXiaohongshuService()
// checkLoginStatusHandler 检查登录状态
func checkLoginStatusHandler(c *gin.Context) {
status, err := xiaohongshuService.CheckLoginStatus(c.Request.Context())
if err != nil {
respondError(c, http.StatusInternalServerError, "STATUS_CHECK_FAILED",
"检查登录状态失败", err.Error())
return
}
c.Set("account", "ai-report")
respondSuccess(c, status, "检查登录状态成功")
}
// publishHandler 发布内容
func publishHandler(c *gin.Context) {
var req PublishRequest
if err := c.ShouldBindJSON(&req); err != nil {
respondError(c, http.StatusBadRequest, "INVALID_REQUEST",
"请求参数错误", err.Error())
return
}
// 执行发布
result, err := xiaohongshuService.PublishContent(c.Request.Context(), &req)
if err != nil {
respondError(c, http.StatusInternalServerError, "PUBLISH_FAILED",
"发布失败", err.Error())
return
}
respondSuccess(c, result, "发布成功")
}
// listFeedsHandler 获取Feeds列表
func listFeedsHandler(c *gin.Context) {
// 获取 Feeds 列表
result, err := xiaohongshuService.ListFeeds(c.Request.Context())
if err != nil {
respondError(c, http.StatusInternalServerError, "LIST_FEEDS_FAILED",
"获取Feeds列表失败", err.Error())
return
}
c.Set("account", "ai-report")
respondSuccess(c, result, "获取Feeds列表成功")
}
// healthHandler 健康检查
func healthHandler(c *gin.Context) {
respondSuccess(c, map[string]any{
"status": "healthy",
"service": "xiaohongshu-mcp",
"account": "ai-report",
"timestamp": "now",
}, "服务正常")
}
// corsMiddleware CORS 中间件
func corsMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
return
}
c.Next()
}
}
// errorHandlingMiddleware 错误处理中间件
func errorHandlingMiddleware() gin.HandlerFunc {
return gin.CustomRecovery(func(c *gin.Context, recovered interface{}) {
logrus.Errorf("服务器内部错误: %v, path: %s", recovered, c.Request.URL.Path)
respondError(c, http.StatusInternalServerError, "INTERNAL_ERROR",
"服务器内部错误", recovered)
})
}