SYMBOL INDEX (373 symbols across 39 files) FILE: app_server.go type AppServer (line 17) | type AppServer struct method Start (line 37) | func (s *AppServer) Start(port string) error { function NewAppServer (line 25) | func NewAppServer(xiaohongshuService *XiaohongshuService) *AppServer { FILE: browser/browser.go type browserConfig (line 12) | type browserConfig struct type Option (line 16) | type Option function WithBinPath (line 18) | func WithBinPath(binPath string) Option { function maskProxyCredentials (line 25) | func maskProxyCredentials(proxyURL string) string { function NewBrowser (line 38) | func NewBrowser(headless bool, options ...Option) *headless_browser.Brow... FILE: cmd/login/main.go function main (line 15) | func main() { function saveCookies (line 66) | func saveCookies(page *rod.Page) error { FILE: configs/browser.go function InitHeadless (line 9) | func InitHeadless(h bool) { function IsHeadless (line 14) | func IsHeadless() bool { function SetBinPath (line 18) | func SetBinPath(b string) { function GetBinPath (line 22) | func GetBinPath() string { FILE: configs/image.go constant ImagesDir (line 9) | ImagesDir = "xiaohongshu_images" function GetImagesPath (line 12) | func GetImagesPath() string { FILE: configs/username.go constant Username (line 4) | Username = "xiaohongshu-mcp" FILE: cookies/cookies.go type Cookier (line 10) | type Cookier interface type localCookie (line 16) | type localCookie struct method LoadCookies (line 31) | func (c *localCookie) LoadCookies() ([]byte, error) { method SaveCookies (line 42) | func (c *localCookie) SaveCookies(data []byte) error { method DeleteCookies (line 47) | func (c *localCookie) DeleteCookies() error { function NewLoadCookie (line 20) | func NewLoadCookie(path string) Cookier { function GetCookiesFilePath (line 58) | func GetCookiesFilePath() string { FILE: handlers_api.go function respondError (line 14) | func respondError(c *gin.Context, statusCode int, code, message string, ... function respondSuccess (line 28) | func respondSuccess(c *gin.Context, data any, message string) { method checkLoginStatusHandler (line 42) | func (s *AppServer) checkLoginStatusHandler(c *gin.Context) { method getLoginQrcodeHandler (line 56) | func (s *AppServer) getLoginQrcodeHandler(c *gin.Context) { method deleteCookiesHandler (line 68) | func (s *AppServer) deleteCookiesHandler(c *gin.Context) { method publishHandler (line 84) | func (s *AppServer) publishHandler(c *gin.Context) { method publishVideoHandler (line 104) | func (s *AppServer) publishVideoHandler(c *gin.Context) { method listFeedsHandler (line 124) | func (s *AppServer) listFeedsHandler(c *gin.Context) { method searchFeedsHandler (line 138) | func (s *AppServer) searchFeedsHandler(c *gin.Context) { method getFeedDetailHandler (line 176) | func (s *AppServer) getFeedDetailHandler(c *gin.Context) { method userProfileHandler (line 212) | func (s *AppServer) userProfileHandler(c *gin.Context) { method postCommentHandler (line 233) | func (s *AppServer) postCommentHandler(c *gin.Context) { method replyCommentHandler (line 254) | func (s *AppServer) replyCommentHandler(c *gin.Context) { function healthHandler (line 274) | func healthHandler(c *gin.Context) { method myProfileHandler (line 284) | func (s *AppServer) myProfileHandler(c *gin.Context) { FILE: main.go function main (line 11) | func main() { FILE: mcp_handlers.go function parseVisibility (line 19) | func parseVisibility(args map[string]interface{}) string { method handleCheckLoginStatus (line 31) | func (s *AppServer) handleCheckLoginStatus(ctx context.Context) *MCPTool... method handleGetLoginQrcode (line 63) | func (s *AppServer) handleGetLoginQrcode(ctx context.Context) *MCPToolRe... method handleDeleteCookies (line 102) | func (s *AppServer) handleDeleteCookies(ctx context.Context) *MCPToolRes... method handlePublishContent (line 124) | func (s *AppServer) handlePublishContent(ctx context.Context, args map[s... method handlePublishVideo (line 198) | func (s *AppServer) handlePublishVideo(ctx context.Context, args map[str... method handleListFeeds (line 270) | func (s *AppServer) handleListFeeds(ctx context.Context) *MCPToolResult { method handleSearchFeeds (line 305) | func (s *AppServer) handleSearchFeeds(ctx context.Context, args SearchFe... method handleGetFeedDetail (line 361) | func (s *AppServer) handleGetFeedDetail(ctx context.Context, args map[st... method handleUserProfile (line 479) | func (s *AppServer) handleUserProfile(ctx context.Context, args map[stri... method handleLikeFeed (line 539) | func (s *AppServer) handleLikeFeed(ctx context.Context, args map[string]... method handleFavoriteFeed (line 575) | func (s *AppServer) handleFavoriteFeed(ctx context.Context, args map[str... method handlePostComment (line 611) | func (s *AppServer) handlePostComment(ctx context.Context, args map[stri... method handleReplyComment (line 673) | func (s *AppServer) handleReplyComment(ctx context.Context, args map[str... FILE: mcp_server.go function boolPtr (line 14) | func boolPtr(b bool) *bool { return &b } type PublishContentArgs (line 19) | type PublishContentArgs struct type PublishVideoArgs (line 31) | type PublishVideoArgs struct type SearchFeedsArgs (line 42) | type SearchFeedsArgs struct type FilterOption (line 48) | type FilterOption struct type FeedDetailArgs (line 57) | type FeedDetailArgs struct type UserProfileArgs (line 68) | type UserProfileArgs struct type PostCommentArgs (line 74) | type PostCommentArgs struct type ReplyCommentArgs (line 81) | type ReplyCommentArgs struct type LikeFeedArgs (line 90) | type LikeFeedArgs struct type FavoriteFeedArgs (line 97) | type FavoriteFeedArgs struct function InitMCPServer (line 104) | func InitMCPServer(appServer *AppServer) *mcp.Server { function withPanicRecovery (line 122) | func withPanicRecovery[T any]( function registerTools (line 155) | func registerTools(server *mcp.Server, appServer *AppServer) { function convertToMCPResult (line 450) | func convertToMCPResult(result *MCPToolResult) *mcp.CallToolResult { function convertStringsToInterfaces (line 481) | func convertStringsToInterfaces(strs []string) []interface{} { FILE: middleware.go function corsMiddleware (line 11) | func corsMiddleware() gin.HandlerFunc { function errorHandlingMiddleware (line 27) | func errorHandlingMiddleware() gin.HandlerFunc { FILE: pkg/downloader/images.go type ImageDownloader (line 19) | type ImageDownloader struct method DownloadImage (line 41) | func (d *ImageDownloader) DownloadImage(imageURL string) (string, erro... method DownloadImages (line 107) | func (d *ImageDownloader) DownloadImages(imageURLs []string) ([]string... method isValidImageURL (line 128) | func (d *ImageDownloader) isValidImageURL(rawURL string) bool { method generateFileName (line 145) | func (d *ImageDownloader) generateFileName(imageURL, extension string)... function NewImageDownloader (line 25) | func NewImageDownloader(savePath string) *ImageDownloader { function IsImageURL (line 160) | func IsImageURL(path string) bool { FILE: pkg/downloader/images_test.go function TestIsImageURL (line 14) | func TestIsImageURL(t *testing.T) { function TestNewImageDownloader (line 37) | func TestNewImageDownloader(t *testing.T) { function TestImageDownloader_isValidImageURL (line 58) | func TestImageDownloader_isValidImageURL(t *testing.T) { function TestImageDownloader_generateFileName (line 82) | func TestImageDownloader_generateFileName(t *testing.T) { function TestDownloadImage_AntiHotlink (line 110) | func TestDownloadImage_AntiHotlink(t *testing.T) { function TestDownloadImage_AntiHotlink_External (line 155) | func TestDownloadImage_AntiHotlink_External(t *testing.T) { FILE: pkg/downloader/processor.go type ImageProcessor (line 10) | type ImageProcessor struct method ProcessImages (line 26) | func (p *ImageProcessor) ProcessImages(images []string) ([]string, err... function NewImageProcessor (line 15) | func NewImageProcessor() *ImageProcessor { FILE: pkg/xhsutil/title.go function CalcTitleLength (line 7) | func CalcTitleLength(s string) int { FILE: pkg/xhsutil/title_test.go function TestCalcTitleLength (line 9) | func TestCalcTitleLength(t *testing.T) { FILE: routes.go function setupRoutes (line 11) | func setupRoutes(appServer *AppServer) *gin.Engine { FILE: service.go type XiaohongshuService (line 22) | type XiaohongshuService struct method DeleteCookies (line 97) | func (s *XiaohongshuService) DeleteCookies(ctx context.Context) error { method CheckLoginStatus (line 104) | func (s *XiaohongshuService) CheckLoginStatus(ctx context.Context) (*L... method GetLoginQrcode (line 127) | func (s *XiaohongshuService) GetLoginQrcode(ctx context.Context) (*Log... method PublishContent (line 175) | func (s *XiaohongshuService) PublishContent(ctx context.Context, req *... method processImages (line 242) | func (s *XiaohongshuService) processImages(images []string) ([]string,... method publishContent (line 248) | func (s *XiaohongshuService) publishContent(ctx context.Context, conte... method PublishVideo (line 265) | func (s *XiaohongshuService) PublishVideo(ctx context.Context, req *Pu... method publishVideo (line 331) | func (s *XiaohongshuService) publishVideo(ctx context.Context, content... method ListFeeds (line 347) | func (s *XiaohongshuService) ListFeeds(ctx context.Context) (*FeedsLis... method SearchFeeds (line 372) | func (s *XiaohongshuService) SearchFeeds(ctx context.Context, keyword ... method GetFeedDetail (line 395) | func (s *XiaohongshuService) GetFeedDetail(ctx context.Context, feedID... method GetFeedDetailWithConfig (line 400) | func (s *XiaohongshuService) GetFeedDetailWithConfig(ctx context.Conte... method UserProfile (line 425) | func (s *XiaohongshuService) UserProfile(ctx context.Context, userID, ... method PostCommentToFeed (line 449) | func (s *XiaohongshuService) PostCommentToFeed(ctx context.Context, fe... method LikeFeed (line 466) | func (s *XiaohongshuService) LikeFeed(ctx context.Context, feedID, xse... method UnlikeFeed (line 481) | func (s *XiaohongshuService) UnlikeFeed(ctx context.Context, feedID, x... method FavoriteFeed (line 496) | func (s *XiaohongshuService) FavoriteFeed(ctx context.Context, feedID,... method UnfavoriteFeed (line 511) | func (s *XiaohongshuService) UnfavoriteFeed(ctx context.Context, feedI... method ReplyCommentToFeed (line 526) | func (s *XiaohongshuService) ReplyCommentToFeed(ctx context.Context, f... method GetMyProfile (line 579) | func (s *XiaohongshuService) GetMyProfile(ctx context.Context) (*UserP... function NewXiaohongshuService (line 25) | func NewXiaohongshuService() *XiaohongshuService { type PublishRequest (line 30) | type PublishRequest struct type LoginStatusResponse (line 42) | type LoginStatusResponse struct type LoginQrcodeResponse (line 48) | type LoginQrcodeResponse struct type PublishResponse (line 55) | type PublishResponse struct type PublishVideoRequest (line 64) | type PublishVideoRequest struct type PublishVideoResponse (line 75) | type PublishVideoResponse struct type FeedsListResponse (line 84) | type FeedsListResponse struct type UserProfileResponse (line 90) | type UserProfileResponse struct function newBrowser (line 548) | func newBrowser() *headless_browser.Browser { function saveCookies (line 552) | func saveCookies(page *rod.Page) error { function withBrowserPage (line 568) | func withBrowserPage(fn func(*rod.Page) error) error { FILE: skills/post-to-xhs/scripts/account_manager.py function _ensure_config_dir (line 35) | def _ensure_config_dir(): function _load_accounts (line 40) | def _load_accounts() -> dict: function _save_accounts (line 62) | def _save_accounts(data: dict): function get_profile_dir (line 69) | def get_profile_dir(account_name: Optional[str] = None) -> str: function get_default_account (line 99) | def get_default_account() -> str: function set_default_account (line 105) | def set_default_account(account_name: str) -> bool: function list_accounts (line 119) | def list_accounts() -> list[dict]: function add_account (line 138) | def add_account(name: str, alias: Optional[str] = None) -> bool: function remove_account (line 165) | def remove_account(name: str, delete_profile: bool = False) -> bool: function get_account_info (line 202) | def get_account_info(name: str) -> Optional[dict]: function account_exists (line 213) | def account_exists(name: str) -> bool: function main (line 223) | def main(): FILE: skills/post-to-xhs/scripts/cdp_publish.py class CDPError (line 106) | class CDPError(Exception): class XiaohongshuPublisher (line 110) | class XiaohongshuPublisher: method __init__ (line 113) | def __init__(self, host: str = CDP_HOST, port: int = CDP_PORT): method _get_targets (line 123) | def _get_targets(self) -> list[dict]: method _find_or_create_tab (line 140) | def _find_or_create_tab(self, target_url_prefix: str = "") -> str: method connect (line 164) | def connect(self, target_url_prefix: str = ""): method disconnect (line 174) | def disconnect(self): method _send (line 184) | def _send(self, method: str, params: dict | None = None) -> dict: method _evaluate (line 206) | def _evaluate(self, expression: str) -> Any: method _navigate (line 218) | def _navigate(self, url: str): method check_login (line 229) | def check_login(self) -> bool: method clear_cookies (line 254) | def clear_cookies(self, domain: str = ".xiaohongshu.com"): method open_login_page (line 274) | def open_login_page(self): method _click_image_text_tab (line 296) | def _click_image_text_tab(self): method _upload_images (line 324) | def _upload_images(self, image_paths: list[str]): method _fill_title (line 368) | def _fill_title(self, title: str): method _fill_content (line 394) | def _fill_content(self, content: str): method _click_publish (line 425) | def _click_publish(self): method _click_long_article_tab (line 469) | def _click_long_article_tab(self): method _click_new_creation (line 497) | def _click_new_creation(self): method _fill_long_title (line 528) | def _fill_long_title(self, title: str): method _click_auto_format (line 556) | def _click_auto_format(self): method _wait_for_templates (line 585) | def _wait_for_templates(self) -> bool: method get_template_names (line 602) | def get_template_names(self) -> list[str]: method select_template (line 618) | def select_template(self, name: str) -> bool: method _click_next_step (line 645) | def _click_next_step(self): method publish_long_article (line 674) | def publish_long_article( method click_next_and_prepare_publish (line 749) | def click_next_and_prepare_publish(self, content: str = ""): method publish (line 767) | def publish( function main (line 819) | def main(): FILE: skills/post-to-xhs/scripts/chrome_launcher.py function get_chrome_path (line 32) | def get_chrome_path() -> str: function get_user_data_dir (line 57) | def get_user_data_dir(account: Optional[str] = None) -> str: function is_port_open (line 78) | def is_port_open(port: int, host: str = "127.0.0.1") -> bool: function launch_chrome (line 89) | def launch_chrome(port: int = CDP_PORT, headless: bool = False, account:... function kill_chrome (line 152) | def kill_chrome(port: int = CDP_PORT): function restart_chrome (line 229) | def restart_chrome(port: int = CDP_PORT, headless: bool = False, account... function ensure_chrome (line 250) | def ensure_chrome(port: int = CDP_PORT, headless: bool = False, account:... function get_current_account (line 272) | def get_current_account() -> Optional[str]: FILE: skills/post-to-xhs/scripts/image_downloader.py class ImageDownloader (line 21) | class ImageDownloader: method __init__ (line 24) | def __init__(self, temp_dir: str | None = None): method _guess_extension (line 34) | def _guess_extension(self, url: str, content_type: str | None) -> str: method download (line 57) | def download(self, url: str, referer: str | None = None) -> str: method download_all (line 93) | def download_all(self, urls: list[str]) -> list[str]: method cleanup (line 108) | def cleanup(self): method __enter__ (line 122) | def __enter__(self): method __exit__ (line 125) | def __exit__(self, *_): FILE: skills/post-to-xhs/scripts/publish_pipeline.py function main (line 57) | def main(): FILE: types.go type ErrorResponse (line 8) | type ErrorResponse struct type SuccessResponse (line 15) | type SuccessResponse struct type MCPToolResult (line 24) | type MCPToolResult struct type MCPContent (line 30) | type MCPContent struct type CommentLoadConfig (line 38) | type CommentLoadConfig struct type FeedDetailRequest (line 50) | type FeedDetailRequest struct type SearchFeedsRequest (line 57) | type SearchFeedsRequest struct type FeedDetailResponse (line 63) | type FeedDetailResponse struct type PostCommentRequest (line 69) | type PostCommentRequest struct type PostCommentResponse (line 76) | type PostCommentResponse struct type ReplyCommentRequest (line 83) | type ReplyCommentRequest struct type ReplyCommentResponse (line 92) | type ReplyCommentResponse struct type UserProfileRequest (line 101) | type UserProfileRequest struct type ActionResult (line 107) | type ActionResult struct FILE: xiaohongshu/comment_feed.go type CommentFeedAction (line 14) | type CommentFeedAction struct method PostComment (line 24) | func (f *CommentFeedAction) PostComment(ctx context.Context, feedID, x... method ReplyToComment (line 83) | func (f *CommentFeedAction) ReplyToComment(ctx context.Context, feedID... function NewCommentFeedAction (line 19) | func NewCommentFeedAction(page *rod.Page) *CommentFeedAction { function findCommentElement (line 157) | func findCommentElement(page *rod.Page, commentID, userID string) (*rod.... FILE: xiaohongshu/feed_detail.go constant defaultMaxAttempts (line 22) | defaultMaxAttempts = 500 constant stagnantLimit (line 23) | stagnantLimit = 20 constant minScrollDelta (line 24) | minScrollDelta = 10 constant maxClickPerRound (line 25) | maxClickPerRound = 3 constant stagnantCheckThreshold (line 26) | stagnantCheckThreshold = 2 constant largeScrollTrigger (line 27) | largeScrollTrigger = 5 constant buttonClickInterval (line 28) | buttonClickInterval = 3 constant finalSprintPushCount (line 29) | finalSprintPushCount = 15 type delayConfig (line 33) | type delayConfig struct type CommentLoadConfig (line 49) | type CommentLoadConfig struct function DefaultCommentLoadConfig (line 56) | func DefaultCommentLoadConfig() CommentLoadConfig { type FeedDetailAction (line 65) | type FeedDetailAction struct method GetFeedDetail (line 75) | func (f *FeedDetailAction) GetFeedDetail(ctx context.Context, feedID, ... method GetFeedDetailWithConfig (line 79) | func (f *FeedDetailAction) GetFeedDetailWithConfig(ctx context.Context... method loadAllCommentsWithConfig (line 141) | func (f *FeedDetailAction) loadAllCommentsWithConfig(page *rod.Page, c... method extractFeedDetail (line 806) | func (f *FeedDetailAction) extractFeedDetail(page *rod.Page, feedID st... function NewFeedDetailAction (line 69) | func NewFeedDetailAction(page *rod.Page) *FeedDetailAction { type commentLoader (line 122) | type commentLoader struct method load (line 152) | func (cl *commentLoader) load() error { method calculateMaxAttempts (line 193) | func (cl *commentLoader) calculateMaxAttempts() int { method checkNoComments (line 200) | func (cl *commentLoader) checkNoComments() bool { method checkComplete (line 208) | func (cl *commentLoader) checkComplete() bool { method shouldClickButtons (line 220) | func (cl *commentLoader) shouldClickButtons() bool { method clickButtonsWithRetry (line 224) | func (cl *commentLoader) clickButtonsWithRetry() { method updateState (line 245) | func (cl *commentLoader) updateState(currentCount int) { method shouldStopAtTarget (line 262) | func (cl *commentLoader) shouldStopAtTarget(currentCount int) bool { method performScroll (line 278) | func (cl *commentLoader) performScroll() { method handleStagnation (line 304) | func (cl *commentLoader) handleStagnation() { method performFinalSprint (line 317) | func (cl *commentLoader) performFinalSprint() { type loadStats (line 129) | type loadStats struct type loadState (line 135) | type loadState struct function sleepRandom (line 329) | func sleepRandom(minMs, maxMs int) { function getScrollInterval (line 338) | func getScrollInterval(speed string) time.Duration { function clickShowMoreButtonsSmart (line 351) | func clickShowMoreButtonsSmart(page *rod.Page, maxRepliesThreshold int) ... function isElementClickable (line 389) | func isElementClickable(el *rod.Element) bool { function shouldSkipButton (line 399) | func shouldSkipButton(text string, threshold int, regex *regexp.Regexp) ... function clickElementWithHumanBehavior (line 414) | func clickElementWithHumanBehavior(page *rod.Page, el *rod.Element, text... function humanScroll (line 469) | func humanScroll(page *rod.Page, speed string, largeMode bool, pushCount... function getScrollRatio (line 519) | func getScrollRatio(speed string) float64 { function calculateScrollDelta (line 530) | func calculateScrollDelta(viewportHeight int, baseRatio float64) float64 { function scrollToCommentsArea (line 538) | func scrollToCommentsArea(page *rod.Page) { function smartScroll (line 553) | func smartScroll(page *rod.Page, delta float64) { function scrollToLastComment (line 572) | func scrollToLastComment(page *rod.Page) { function getScrollTop (line 585) | func getScrollTop(page *rod.Page) int { function getCommentCount (line 614) | func getCommentCount(page *rod.Page) int { function getTotalCommentCount (line 644) | func getTotalCommentCount(page *rod.Page) int { function checkNoCommentsArea (line 693) | func checkNoCommentsArea(page *rod.Page) bool { function checkEndContainer (line 712) | func checkEndContainer(page *rod.Page) bool { function checkPageAccessible (line 756) | func checkPageAccessible(page *rod.Page) error { function makeFeedDetailURL (line 865) | func makeFeedDetailURL(feedID, xsecToken string) string { FILE: xiaohongshu/feeds.go type FeedsListAction (line 13) | type FeedsListAction struct method GetFeedsList (line 27) | func (f *FeedsListAction) GetFeedsList(ctx context.Context) ([]Feed, e... function NewFeedsListAction (line 17) | func NewFeedsListAction(page *rod.Page) *FeedsListAction { FILE: xiaohongshu/feeds_test.go function TestGetFeedsList (line 13) | func TestGetFeedsList(t *testing.T) { FILE: xiaohongshu/like_favorite.go type ActionResult (line 16) | type ActionResult struct constant SelectorLikeButton (line 24) | SelectorLikeButton = ".interact-container .left .like-lottie" constant SelectorCollectButton (line 25) | SelectorCollectButton = ".interact-container .left .reds-icon.collect-icon" type interactActionType (line 29) | type interactActionType constant actionLike (line 32) | actionLike interactActionType = "点赞" constant actionFavorite (line 33) | actionFavorite interactActionType = "收藏" constant actionUnlike (line 34) | actionUnlike interactActionType = "取消点赞" constant actionUnfavorite (line 35) | actionUnfavorite interactActionType = "取消收藏" type interactAction (line 38) | type interactAction struct method preparePage (line 46) | func (a *interactAction) preparePage(ctx context.Context, actionType i... method performClick (line 58) | func (a *interactAction) performClick(page *rod.Page, selector string) { method getInteractState (line 216) | func (a *interactAction) getInteractState(page *rod.Page, feedID strin... function newInteractAction (line 42) | func newInteractAction(page *rod.Page) *interactAction { type LikeAction (line 64) | type LikeAction struct method Like (line 73) | func (a *LikeAction) Like(ctx context.Context, feedID, xsecToken strin... method Unlike (line 78) | func (a *LikeAction) Unlike(ctx context.Context, feedID, xsecToken str... method perform (line 82) | func (a *LikeAction) perform(ctx context.Context, feedID, xsecToken st... method toggleLike (line 108) | func (a *LikeAction) toggleLike(page *rod.Page, feedID string, targetL... function NewLikeAction (line 68) | func NewLikeAction(page *rod.Page) *LikeAction { type FavoriteAction (line 140) | type FavoriteAction struct method Favorite (line 149) | func (a *FavoriteAction) Favorite(ctx context.Context, feedID, xsecTok... method Unfavorite (line 154) | func (a *FavoriteAction) Unfavorite(ctx context.Context, feedID, xsecT... method perform (line 158) | func (a *FavoriteAction) perform(ctx context.Context, feedID, xsecToke... method toggleFavorite (line 184) | func (a *FavoriteAction) toggleFavorite(page *rod.Page, feedID string,... function NewFavoriteAction (line 144) | func NewFavoriteAction(page *rod.Page) *FavoriteAction { FILE: xiaohongshu/login.go type LoginAction (line 11) | type LoginAction struct method CheckLoginStatus (line 19) | func (a *LoginAction) CheckLoginStatus(ctx context.Context) (bool, err... method Login (line 37) | func (a *LoginAction) Login(ctx context.Context) error { method FetchQrcodeImage (line 59) | func (a *LoginAction) FetchQrcodeImage(ctx context.Context) (string, b... method WaitForLogin (line 85) | func (a *LoginAction) WaitForLogin(ctx context.Context) bool { function NewLogin (line 15) | func NewLogin(page *rod.Page) *LoginAction { FILE: xiaohongshu/navigate.go type NavigateAction (line 9) | type NavigateAction struct method ToExplorePage (line 17) | func (n *NavigateAction) ToExplorePage(ctx context.Context) error { method ToProfilePage (line 27) | func (n *NavigateAction) ToProfilePage(ctx context.Context) error { function NewNavigate (line 13) | func NewNavigate(page *rod.Page) *NavigateAction { FILE: xiaohongshu/publish.go type PublishImageContent (line 19) | type PublishImageContent struct type PublishAction (line 30) | type PublishAction struct method Publish (line 71) | func (p *PublishAction) Publish(ctx context.Context, content PublishIm... constant urlOfPublic (line 35) | urlOfPublic = `https://creator.xiaohongshu.com/publish/publish?source=of... function NewPublishImageAction (line 38) | func NewPublishImageAction(page *rod.Page) (*PublishAction, error) { function removePopCover (line 97) | func removePopCover(page *rod.Page) { function clickEmptyPosition (line 112) | func clickEmptyPosition(page *rod.Page) { function mustClickPublishTab (line 118) | func mustClickPublishTab(page *rod.Page, tabname string) error { function getTabElement (line 154) | func getTabElement(page *rod.Page, tabname string) (*rod.Element, bool, ... function isElementBlocked (line 186) | func isElementBlocked(elem *rod.Element) (bool, error) { function uploadImages (line 204) | func uploadImages(page *rod.Page, imagesPaths []string) error { function waitForUploadComplete (line 244) | func waitForUploadComplete(page *rod.Page, expectedCount int) error { function submitPublish (line 274) | func submitPublish(page *rod.Page, title, content string, tags []string,... function waitAndClickTitleInput (line 354) | func waitAndClickTitleInput(titleElem *rod.Element) error { function checkTitleMaxLength (line 365) | func checkTitleMaxLength(page *rod.Page) error { function checkContentMaxLength (line 385) | func checkContentMaxLength(page *rod.Page) error { function makeMaxLengthError (line 405) | func makeMaxLengthError(elemText string) error { function getContentElement (line 417) | func getContentElement(page *rod.Page) (*rod.Element, bool) { function inputTags (line 442) | func inputTags(contentElem *rod.Element, tags []string) error { function inputTag (line 479) | func inputTag(contentElem *rod.Element, tag string) error { function findTextboxByPlaceholder (line 517) | func findTextboxByPlaceholder(page *rod.Page) (*rod.Element, error) { function findPlaceholderElement (line 538) | func findPlaceholderElement(elements []*rod.Element, searchText string) ... function findTextboxParent (line 552) | func findTextboxParent(elem *rod.Element) *rod.Element { function isElementVisible (line 576) | func isElementVisible(elem *rod.Element) bool { function setVisibility (line 603) | func setVisibility(page *rod.Page, visibility string) error { function setSchedulePublish (line 648) | func setSchedulePublish(page *rod.Page, t time.Time) error { function clickScheduleSwitch (line 665) | func clickScheduleSwitch(page *rod.Page) error { function setDateTime (line 679) | func setDateTime(page *rod.Page, t time.Time) error { function setOriginal (line 699) | func setOriginal(page *rod.Page) error { function confirmOriginalDeclaration (line 761) | func confirmOriginalDeclaration(page *rod.Page) error { function bindProducts (line 846) | func bindProducts(page *rod.Page, products []string) error { function clickAddProductButton (line 900) | func clickAddProductButton(page *rod.Page) error { function waitForProductModal (line 958) | func waitForProductModal(page *rod.Page) (*rod.Element, error) { function searchAndSelectProduct (line 977) | func searchAndSelectProduct(page *rod.Page, modal *rod.Element, keyword ... function clickModalSaveButton (line 1059) | func clickModalSaveButton(page *rod.Page, modal *rod.Element) error { function waitForModalClose (line 1087) | func waitForModalClose(page *rod.Page) error { FILE: xiaohongshu/publish_test.go function TestPublish (line 13) | func TestPublish(t *testing.T) { FILE: xiaohongshu/publish_video.go type PublishVideoContent (line 17) | type PublishVideoContent struct function NewPublishVideoAction (line 28) | func NewPublishVideoAction(page *rod.Page) (*PublishAction, error) { method PublishVideo (line 56) | func (p *PublishAction) PublishVideo(ctx context.Context, content Publis... function uploadVideo (line 74) | func uploadVideo(page *rod.Page, videoPath string) error { function waitForPublishButtonClickable (line 104) | func waitForPublishButtonClickable(page *rod.Page) (*rod.Element, error) { function submitPublishVideo (line 135) | func submitPublishVideo(page *rod.Page, title, content string, tags []st... FILE: xiaohongshu/search.go type SearchResult (line 14) | type SearchResult struct type FilterOption (line 21) | type FilterOption struct type internalFilterOption (line 30) | type internalFilterOption struct function convertToInternalFilters (line 70) | func convertToInternalFilters(filter FilterOption) ([]internalFilterOpti... function findInternalOption (line 122) | func findInternalOption(filtersIndex int, text string) (internalFilterOp... function validateInternalFilterOption (line 138) | func validateInternalFilterOption(filter internalFilterOption) error { type SearchAction (line 158) | type SearchAction struct method Search (line 168) | func (s *SearchAction) Search(ctx context.Context, keyword string, fil... function NewSearchAction (line 162) | func NewSearchAction(page *rod.Page) *SearchAction { function makeSearchURL (line 242) | func makeSearchURL(keyword string) string { FILE: xiaohongshu/search_test.go function TestSearch (line 12) | func TestSearch(t *testing.T) { function TestSearchWithFilters (line 38) | func TestSearchWithFilters(t *testing.T) { function TestFilterValidation (line 70) | func TestFilterValidation(t *testing.T) { FILE: xiaohongshu/types.go type FeedResponse (line 6) | type FeedResponse struct type FeedData (line 11) | type FeedData struct type FeedsValue (line 16) | type FeedsValue struct type Feed (line 21) | type Feed struct type NoteCard (line 30) | type NoteCard struct type User (line 40) | type User struct type InteractInfo (line 48) | type InteractInfo struct type Cover (line 60) | type Cover struct type ImageInfo (line 71) | type ImageInfo struct type Video (line 77) | type Video struct type VideoCapability (line 82) | type VideoCapability struct type FeedDetailResponse (line 89) | type FeedDetailResponse struct type FeedDetail (line 95) | type FeedDetail struct type DetailImageInfo (line 109) | type DetailImageInfo struct type CommentList (line 118) | type CommentList struct type Comment (line 125) | type Comment struct type UserProfileResponse (line 140) | type UserProfileResponse struct type UserPageData (line 147) | type UserPageData struct type UserBasicInfo (line 155) | type UserBasicInfo struct type UserInteractions (line 166) | type UserInteractions struct FILE: xiaohongshu/user_profile.go type UserProfileAction (line 12) | type UserProfileAction struct method UserProfile (line 22) | func (u *UserProfileAction) UserProfile(ctx context.Context, userID, x... method extractUserProfileData (line 33) | func (u *UserProfileAction) extractUserProfileData(page *rod.Page) (*U... method GetMyProfileViaSidebar (line 107) | func (u *UserProfileAction) GetMyProfileViaSidebar(ctx context.Context... function NewUserProfileAction (line 16) | func NewUserProfileAction(page *rod.Page) *UserProfileAction { function makeUserProfileURL (line 103) | func makeUserProfileURL(userID, xsecToken string) string {