64dbc45265
- 新增 xhs_get_comment_notifications / xhs_reply_notification MCP工具 - 通知获取前先读取首页未读小红点数字,无未读则直接返回空,避免重复处理 - 新增 REST 端点 GET /notifications/comments 和 POST /notifications/reply - 前端小红书页面新增「通知」按钮和 NotificationPanel slide-over 组件 - 通知面板支持查看评论通知列表和行内回复
141 lines
4.0 KiB
TypeScript
141 lines
4.0 KiB
TypeScript
import { apiFetch } from './client';
|
|
import type {
|
|
LoginStatus,
|
|
QRCodeResult,
|
|
Feed,
|
|
FeedDetail,
|
|
Comment,
|
|
UserProfile,
|
|
SearchFilters,
|
|
HealthResponse,
|
|
ApiResponse,
|
|
PublishResult,
|
|
CommentResult,
|
|
CommentNotification,
|
|
} from './types';
|
|
|
|
// Health (no auth required)
|
|
export const getHealth = () =>
|
|
apiFetch<HealthResponse>('/health');
|
|
|
|
// Login
|
|
export const getLoginStatus = () =>
|
|
apiFetch<ApiResponse<LoginStatus>>('/api/xhs/login/status');
|
|
|
|
export const getLoginQRCode = () =>
|
|
apiFetch<ApiResponse<QRCodeResult>>('/api/xhs/login/qrcode');
|
|
|
|
export const deleteCookies = () =>
|
|
apiFetch<ApiResponse<{ message: string }>>('/api/xhs/login/cookies', { method: 'DELETE' });
|
|
|
|
// Lightweight cookie check (no browser opened)
|
|
export const checkLoginCookie = () =>
|
|
apiFetch<ApiResponse<{ hasCookies: boolean }>>('/api/xhs/login/cookie-check');
|
|
|
|
// Feeds
|
|
export const listFeeds = () =>
|
|
apiFetch<ApiResponse<Feed[]>>('/api/xhs/feeds');
|
|
|
|
export const searchFeeds = (keyword: string, filters?: SearchFilters) =>
|
|
apiFetch<ApiResponse<Feed[]>>('/api/xhs/search', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ keyword, filters }),
|
|
});
|
|
|
|
export const getFeedDetail = (feedId: string, xsecToken: string) =>
|
|
apiFetch<ApiResponse<FeedDetail>>('/api/xhs/feeds/detail', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ feed_id: feedId, xsec_token: xsecToken }),
|
|
});
|
|
|
|
export const getSubComments = (
|
|
feedId: string,
|
|
xsecToken: string,
|
|
commentId: string,
|
|
maxCount = 20,
|
|
) =>
|
|
apiFetch<ApiResponse<Comment[]>>('/api/xhs/feeds/sub-comments', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ feed_id: feedId, xsec_token: xsecToken, comment_id: commentId, max_count: maxCount }),
|
|
});
|
|
|
|
// User
|
|
export const getUserProfile = (userId: string, xsecToken: string) =>
|
|
apiFetch<ApiResponse<UserProfile>>('/api/xhs/user/profile', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ user_id: userId, xsec_token: xsecToken }),
|
|
});
|
|
|
|
// Publish
|
|
export const publishImage = (data: {
|
|
title: string;
|
|
content: string;
|
|
images: string[];
|
|
tags?: string[];
|
|
schedule_at?: string;
|
|
is_original?: boolean;
|
|
visibility?: 'public' | 'private' | 'friends';
|
|
}) =>
|
|
apiFetch<ApiResponse<PublishResult>>('/api/xhs/publish/image', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
});
|
|
|
|
export const publishVideo = (data: {
|
|
title: string;
|
|
content: string;
|
|
video: string;
|
|
tags?: string[];
|
|
schedule_at?: string;
|
|
visibility?: 'public' | 'private' | 'friends';
|
|
}) =>
|
|
apiFetch<ApiResponse<PublishResult>>('/api/xhs/publish/video', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
});
|
|
|
|
// Interactions
|
|
export const postComment = (feedId: string, xsecToken: string, content: string) =>
|
|
apiFetch<ApiResponse<CommentResult>>('/api/xhs/comment', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ feed_id: feedId, xsec_token: xsecToken, content }),
|
|
});
|
|
|
|
export const replyComment = (data: {
|
|
feed_id: string;
|
|
xsec_token: string;
|
|
content: string;
|
|
comment_id?: string;
|
|
user_id?: string;
|
|
}) =>
|
|
apiFetch<ApiResponse<CommentResult>>('/api/xhs/comment/reply', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
});
|
|
|
|
// Notifications
|
|
export const getCommentNotifications = (maxCount = 20) =>
|
|
apiFetch<ApiResponse<CommentNotification[]>>(`/api/xhs/notifications/comments?max_count=${maxCount}`);
|
|
|
|
export const replyNotification = (data: {
|
|
user_id: string;
|
|
comment_content: string;
|
|
reply_content: string;
|
|
}) =>
|
|
apiFetch<ApiResponse<CommentResult>>('/api/xhs/notifications/reply', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
});
|
|
|
|
export const toggleLike = (feedId: string, xsecToken: string) =>
|
|
apiFetch<ApiResponse<{ success: boolean; liked: boolean }>>('/api/xhs/like', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ feed_id: feedId, xsec_token: xsecToken }),
|
|
});
|
|
|
|
export const toggleFavorite = (feedId: string, xsecToken: string) =>
|
|
apiFetch<ApiResponse<{ success: boolean; favorited: boolean }>>('/api/xhs/favorite', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ feed_id: feedId, xsec_token: xsecToken }),
|
|
});
|