feat: add delete cookies functionality for login reset (#275)
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
|||||||
type Cookier interface {
|
type Cookier interface {
|
||||||
LoadCookies() ([]byte, error)
|
LoadCookies() ([]byte, error)
|
||||||
SaveCookies(data []byte) error
|
SaveCookies(data []byte) error
|
||||||
|
DeleteCookies() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type localCookie struct {
|
type localCookie struct {
|
||||||
@@ -42,6 +43,15 @@ func (c *localCookie) SaveCookies(data []byte) error {
|
|||||||
return os.WriteFile(c.path, data, 0644)
|
return os.WriteFile(c.path, data, 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteCookies 删除 cookies 文件。
|
||||||
|
func (c *localCookie) DeleteCookies() error {
|
||||||
|
if _, err := os.Stat(c.path); os.IsNotExist(err) {
|
||||||
|
// 文件不存在,返回 nil(认为已经删除)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return os.Remove(c.path)
|
||||||
|
}
|
||||||
|
|
||||||
// GetCookiesFilePath 获取 cookies 文件路径。
|
// GetCookiesFilePath 获取 cookies 文件路径。
|
||||||
// 为了向后兼容,如果旧路径 /tmp/cookies.json 存在,则继续使用;
|
// 为了向后兼容,如果旧路径 /tmp/cookies.json 存在,则继续使用;
|
||||||
// 否则使用当前目录下的 cookies.json
|
// 否则使用当前目录下的 cookies.json
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/xpzouying/xiaohongshu-mcp/cookies"
|
||||||
"github.com/xpzouying/xiaohongshu-mcp/xiaohongshu"
|
"github.com/xpzouying/xiaohongshu-mcp/xiaohongshu"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -63,6 +64,22 @@ func (s *AppServer) getLoginQrcodeHandler(c *gin.Context) {
|
|||||||
respondSuccess(c, result, "获取登录二维码成功")
|
respondSuccess(c, result, "获取登录二维码成功")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deleteCookiesHandler 删除 cookies,重置登录状态
|
||||||
|
func (s *AppServer) deleteCookiesHandler(c *gin.Context) {
|
||||||
|
err := s.xiaohongshuService.DeleteCookies(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
respondError(c, http.StatusInternalServerError, "DELETE_COOKIES_FAILED",
|
||||||
|
"删除 cookies 失败", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cookiePath := cookies.GetCookiesFilePath()
|
||||||
|
respondSuccess(c, map[string]interface{}{
|
||||||
|
"cookie_path": cookiePath,
|
||||||
|
"message": "Cookies 已成功删除,登录状态已重置。下次操作时需要重新登录。",
|
||||||
|
}, "删除 cookies 成功")
|
||||||
|
}
|
||||||
|
|
||||||
// publishHandler 发布内容
|
// publishHandler 发布内容
|
||||||
func (s *AppServer) publishHandler(c *gin.Context) {
|
func (s *AppServer) publishHandler(c *gin.Context) {
|
||||||
var req PublishRequest
|
var req PublishRequest
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/xpzouying/xiaohongshu-mcp/cookies"
|
||||||
"github.com/xpzouying/xiaohongshu-mcp/xiaohongshu"
|
"github.com/xpzouying/xiaohongshu-mcp/xiaohongshu"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -27,7 +28,14 @@ func (s *AppServer) handleCheckLoginStatus(ctx context.Context) *MCPToolResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resultText := fmt.Sprintf("登录状态检查成功: %+v", status)
|
// 根据 IsLoggedIn 判断并返回友好的提示
|
||||||
|
var resultText string
|
||||||
|
if status.IsLoggedIn {
|
||||||
|
resultText = fmt.Sprintf("✅ 已登录\n用户名: %s\n\n你可以使用其他功能了。", status.Username)
|
||||||
|
} else {
|
||||||
|
resultText = fmt.Sprintf("❌ 未登录\n\n请使用 get_login_qrcode 工具获取二维码进行登录。")
|
||||||
|
}
|
||||||
|
|
||||||
return &MCPToolResult{
|
return &MCPToolResult{
|
||||||
Content: []MCPContent{{
|
Content: []MCPContent{{
|
||||||
Type: "text",
|
Type: "text",
|
||||||
@@ -76,6 +84,28 @@ func (s *AppServer) handleGetLoginQrcode(ctx context.Context) *MCPToolResult {
|
|||||||
return &MCPToolResult{Content: contents}
|
return &MCPToolResult{Content: contents}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleDeleteCookies 处理删除 cookies 请求,用于登录重置
|
||||||
|
func (s *AppServer) handleDeleteCookies(ctx context.Context) *MCPToolResult {
|
||||||
|
logrus.Info("MCP: 删除 cookies,重置登录状态")
|
||||||
|
|
||||||
|
err := s.xiaohongshuService.DeleteCookies(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return &MCPToolResult{
|
||||||
|
Content: []MCPContent{{Type: "text", Text: "删除 cookies 失败: " + err.Error()}},
|
||||||
|
IsError: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cookiePath := cookies.GetCookiesFilePath()
|
||||||
|
resultText := fmt.Sprintf("Cookies 已成功删除,登录状态已重置。\n\n删除的文件路径: %s\n\n下次操作时,需要重新登录。", cookiePath)
|
||||||
|
return &MCPToolResult{
|
||||||
|
Content: []MCPContent{{
|
||||||
|
Type: "text",
|
||||||
|
Text: resultText,
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// handlePublishContent 处理发布内容
|
// handlePublishContent 处理发布内容
|
||||||
func (s *AppServer) handlePublishContent(ctx context.Context, args map[string]interface{}) *MCPToolResult {
|
func (s *AppServer) handlePublishContent(ctx context.Context, args map[string]interface{}) *MCPToolResult {
|
||||||
logrus.Info("MCP: 发布内容")
|
logrus.Info("MCP: 发布内容")
|
||||||
|
|||||||
@@ -153,7 +153,19 @@ func registerTools(server *mcp.Server, appServer *AppServer) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 工具 3: 发布内容
|
// 工具 3: 删除 cookies(登录重置)
|
||||||
|
mcp.AddTool(server,
|
||||||
|
&mcp.Tool{
|
||||||
|
Name: "delete_cookies",
|
||||||
|
Description: "删除 cookies 文件,重置登录状态。删除后需要重新登录。",
|
||||||
|
},
|
||||||
|
withPanicRecovery("delete_cookies", func(ctx context.Context, req *mcp.CallToolRequest, _ any) (*mcp.CallToolResult, any, error) {
|
||||||
|
result := appServer.handleDeleteCookies(ctx)
|
||||||
|
return convertToMCPResult(result), nil, nil
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
// 工具 4: 发布内容
|
||||||
mcp.AddTool(server,
|
mcp.AddTool(server,
|
||||||
&mcp.Tool{
|
&mcp.Tool{
|
||||||
Name: "publish_content",
|
Name: "publish_content",
|
||||||
@@ -172,7 +184,7 @@ func registerTools(server *mcp.Server, appServer *AppServer) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 工具 4: 获取Feed列表
|
// 工具 5: 获取Feed列表
|
||||||
mcp.AddTool(server,
|
mcp.AddTool(server,
|
||||||
&mcp.Tool{
|
&mcp.Tool{
|
||||||
Name: "list_feeds",
|
Name: "list_feeds",
|
||||||
@@ -184,7 +196,7 @@ func registerTools(server *mcp.Server, appServer *AppServer) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 工具 5: 搜索内容
|
// 工具 6: 搜索内容
|
||||||
mcp.AddTool(server,
|
mcp.AddTool(server,
|
||||||
&mcp.Tool{
|
&mcp.Tool{
|
||||||
Name: "search_feeds",
|
Name: "search_feeds",
|
||||||
@@ -196,7 +208,7 @@ func registerTools(server *mcp.Server, appServer *AppServer) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 工具 6: 获取Feed详情
|
// 工具 7: 获取Feed详情
|
||||||
mcp.AddTool(server,
|
mcp.AddTool(server,
|
||||||
&mcp.Tool{
|
&mcp.Tool{
|
||||||
Name: "get_feed_detail",
|
Name: "get_feed_detail",
|
||||||
@@ -212,7 +224,7 @@ func registerTools(server *mcp.Server, appServer *AppServer) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 工具 7: 获取用户主页
|
// 工具 8: 获取用户主页
|
||||||
mcp.AddTool(server,
|
mcp.AddTool(server,
|
||||||
&mcp.Tool{
|
&mcp.Tool{
|
||||||
Name: "user_profile",
|
Name: "user_profile",
|
||||||
@@ -228,7 +240,7 @@ func registerTools(server *mcp.Server, appServer *AppServer) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 工具 8: 发表评论
|
// 工具 9: 发表评论
|
||||||
mcp.AddTool(server,
|
mcp.AddTool(server,
|
||||||
&mcp.Tool{
|
&mcp.Tool{
|
||||||
Name: "post_comment_to_feed",
|
Name: "post_comment_to_feed",
|
||||||
@@ -245,7 +257,7 @@ func registerTools(server *mcp.Server, appServer *AppServer) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 工具 9: 发布视频(仅本地文件)
|
// 工具 10: 发布视频(仅本地文件)
|
||||||
mcp.AddTool(server,
|
mcp.AddTool(server,
|
||||||
&mcp.Tool{
|
&mcp.Tool{
|
||||||
Name: "publish_with_video",
|
Name: "publish_with_video",
|
||||||
@@ -263,7 +275,7 @@ func registerTools(server *mcp.Server, appServer *AppServer) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 工具 10: 点赞笔记
|
// 工具 11: 点赞笔记
|
||||||
mcp.AddTool(server,
|
mcp.AddTool(server,
|
||||||
&mcp.Tool{
|
&mcp.Tool{
|
||||||
Name: "like_feed",
|
Name: "like_feed",
|
||||||
@@ -280,7 +292,7 @@ func registerTools(server *mcp.Server, appServer *AppServer) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 工具 11: 收藏笔记
|
// 工具 12: 收藏笔记
|
||||||
mcp.AddTool(server,
|
mcp.AddTool(server,
|
||||||
&mcp.Tool{
|
&mcp.Tool{
|
||||||
Name: "favorite_feed",
|
Name: "favorite_feed",
|
||||||
@@ -297,7 +309,7 @@ func registerTools(server *mcp.Server, appServer *AppServer) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
logrus.Infof("Registered %d MCP tools", 11)
|
logrus.Infof("Registered %d MCP tools", 12)
|
||||||
}
|
}
|
||||||
|
|
||||||
// convertToMCPResult 将自定义的 MCPToolResult 转换为官方 SDK 的格式
|
// convertToMCPResult 将自定义的 MCPToolResult 转换为官方 SDK 的格式
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ func setupRoutes(appServer *AppServer) *gin.Engine {
|
|||||||
{
|
{
|
||||||
api.GET("/login/status", appServer.checkLoginStatusHandler)
|
api.GET("/login/status", appServer.checkLoginStatusHandler)
|
||||||
api.GET("/login/qrcode", appServer.getLoginQrcodeHandler)
|
api.GET("/login/qrcode", appServer.getLoginQrcodeHandler)
|
||||||
|
api.DELETE("/login/cookies", appServer.deleteCookiesHandler)
|
||||||
api.POST("/publish", appServer.publishHandler)
|
api.POST("/publish", appServer.publishHandler)
|
||||||
api.POST("/publish_video", appServer.publishVideoHandler)
|
api.POST("/publish_video", appServer.publishVideoHandler)
|
||||||
api.GET("/feeds/list", appServer.listFeedsHandler)
|
api.GET("/feeds/list", appServer.listFeedsHandler)
|
||||||
|
|||||||
@@ -86,6 +86,13 @@ type UserProfileResponse struct {
|
|||||||
Feeds []xiaohongshu.Feed `json:"feeds"`
|
Feeds []xiaohongshu.Feed `json:"feeds"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteCookies 删除 cookies 文件,用于登录重置
|
||||||
|
func (s *XiaohongshuService) DeleteCookies(ctx context.Context) error {
|
||||||
|
cookiePath := cookies.GetCookiesFilePath()
|
||||||
|
cookieLoader := cookies.NewLoadCookie(cookiePath)
|
||||||
|
return cookieLoader.DeleteCookies()
|
||||||
|
}
|
||||||
|
|
||||||
// CheckLoginStatus 检查登录状态
|
// CheckLoginStatus 检查登录状态
|
||||||
func (s *XiaohongshuService) CheckLoginStatus(ctx context.Context) (*LoginStatusResponse, error) {
|
func (s *XiaohongshuService) CheckLoginStatus(ctx context.Context) (*LoginStatusResponse, error) {
|
||||||
b := newBrowser()
|
b := newBrowser()
|
||||||
|
|||||||
Reference in New Issue
Block a user