myProfileHandler (#239)

Co-authored-by: Buf Generate <buf-generate@bondee.com>
This commit is contained in:
Carlo
2025-10-16 21:17:28 +08:00
committed by GitHub
parent 23f85616b4
commit 844ff8c102
5 changed files with 92 additions and 0 deletions

View File

@@ -227,3 +227,17 @@ func healthHandler(c *gin.Context) {
"timestamp": "now",
}, "服务正常")
}
// myProfileHandler 我的信息
func (s *AppServer) myProfileHandler(c *gin.Context) {
// 获取当前登录用户信息
result, err := s.xiaohongshuService.GetMyProfile(c.Request.Context())
if err != nil {
respondError(c, http.StatusInternalServerError, "GET_MY_PROFILE_FAILED",
"获取我的主页失败", err.Error())
return
}
c.Set("account", "ai-report")
respondSuccess(c, map[string]any{"data": result}, "获取我的主页成功")
}

View File

@@ -48,6 +48,7 @@ func setupRoutes(appServer *AppServer) *gin.Engine {
api.POST("/feeds/detail", appServer.getFeedDetailHandler)
api.POST("/user/profile", appServer.userProfileHandler)
api.POST("/feeds/comment", appServer.postCommentHandler)
api.GET("/user/me", appServer.myProfileHandler)
}
return router

View File

@@ -461,3 +461,38 @@ func saveCookies(page *rod.Page) error {
cookieLoader := cookies.NewLoadCookie(cookies.GetCookiesFilePath())
return cookieLoader.SaveCookies(data)
}
// withBrowserPage 执行需要浏览器页面的操作的通用函数
func withBrowserPage(fn func(*rod.Page) error) error {
b := newBrowser()
defer b.Close()
page := b.NewPage()
defer page.Close()
return fn(page)
}
// GetMyProfile 获取当前登录用户的个人信息
func (s *XiaohongshuService) GetMyProfile(ctx context.Context) (*UserProfileResponse, error) {
var result *xiaohongshu.UserProfileResponse
var err error
err = withBrowserPage(func(page *rod.Page) error {
action := xiaohongshu.NewUserProfileAction(page)
result, err = action.GetMyProfileViaSidebar(ctx)
return err
})
if err != nil {
return nil, err
}
response := &UserProfileResponse{
UserBasicInfo: result.UserBasicInfo,
Interactions: result.Interactions,
Feeds: result.Feeds,
}
return response, nil
}

View File

@@ -23,3 +23,23 @@ func (n *NavigateAction) ToExplorePage(ctx context.Context) error {
return nil
}
func (n *NavigateAction) ToProfilePage(ctx context.Context) error {
page := n.page.Context(ctx)
// First navigate to explore page
if err := n.ToExplorePage(ctx); err != nil {
return err
}
page.MustWaitStable()
// Find and click the "我" channel link in sidebar
profileLink := page.MustElement(`div.main-container li.user.side-bar-component a.link-wrapper span.channel`)
profileLink.MustClick()
// Wait for navigation to complete
page.MustWaitLoad()
return nil
}

View File

@@ -26,6 +26,11 @@ func (u *UserProfileAction) UserProfile(ctx context.Context, userID, xsecToken s
page.MustNavigate(searchURL)
page.MustWaitStable()
return u.extractUserProfileData(page)
}
// extractUserProfileData 从页面中提取用户资料数据的通用方法
func (u *UserProfileAction) extractUserProfileData(page *rod.Page) (*UserProfileResponse, error) {
page.MustWait(`() => window.__INITIAL_STATE__ !== undefined`)
// 获取 window.__INITIAL_STATE__ 并转换为 JSON 字符串
@@ -69,3 +74,20 @@ func (u *UserProfileAction) UserProfile(ctx context.Context, userID, xsecToken s
func makeUserProfileURL(userID, xsecToken string) string {
return fmt.Sprintf("https://www.xiaohongshu.com/user/profile/%s?xsec_token=%s&xsec_source=pc_note", userID, xsecToken)
}
func (u *UserProfileAction) GetMyProfileViaSidebar(ctx context.Context) (*UserProfileResponse, error) {
page := u.page.Context(ctx)
// 创建导航动作
navigate := NewNavigate(page)
// 通过侧边栏导航到个人主页
if err := navigate.ToProfilePage(ctx); err != nil {
return nil, fmt.Errorf("failed to navigate to profile page via sidebar: %w", err)
}
// 等待页面加载完成并获取 __INITIAL_STATE__
page.MustWaitStable()
return u.extractUserProfileData(page)
}