JS爬虫实战演练

在这个小红书私信通里面进行一个js的爬虫

文字发送

async function sendChatMessage(content) {
    const url = 'https://pro.xiaohongshu.com/api/edith/ads/pro/chat/chatline/msg';
    const params = new URLSearchParams({
        porch_user_id: '677e116404ee000000000001'
    });

    const messageData = {
		sender_porch_id: "677e116404ee000000000001",
		receiver_id: "612368ee000000000101cd0c",
        content: content,
        message_type: "TEXT",
		platform:3,
        uuid: uuid()
    };

    const headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-encoding': 'gzip, deflate, br, zstd',
        'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'authorization': 'AT-68c517457761645230526862lrx8ruxmrxwq0enw',  
        'content-type': 'application/json',
        'origin': 'https://pro.xiaohongshu.com',
        'referer': 'https://pro.xiaohongshu.com/im/multiCustomerService',
        'sec-ch-ua': '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0',
        'x-subsystem': 'ares'
    };

    try {
        console.log('发送数据:', messageData);
        
        const response = await fetch(`${url}?${params}`, {
            method: 'POST',
            headers: headers,
            credentials: 'include',
            body: JSON.stringify(messageData)
        });

        if (!response.ok) {
            const errorText = await response.text();
            console.error('错误详情:', errorText);
            throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
        }

        const result = await response.json();
        console.log('发送成功:', result);
        return result;
    } catch (error) {
        console.error('发送失败:', error);
        throw error;
    }
}

// 测试发送
async function testSend() {
    try {
        console.log('当前 cookie:', document.cookie);
        const result = await sendChatMessage("test message");
        console.log('发送结果:', result);
    } catch (error) {
        console.error('发送出错:', error);
    }
}
// 执行测试
testSend();

图片发送

//第一步进行token获取
async function getUploadTokenData() {
    // 构建URL和参数
    const baseUrl = 'https://pro.xiaohongshu.com/api/edith/ads/pro/chat/uploader/v3/token';
    const params = new URLSearchParams({
        biz_name: 'cs',
        scene: 'feeva_img',
        file_count: '1',
        version: '1',
        source: 'web'
    });

    try {
        const response = await fetch(`${baseUrl}?${params}`, {
            method: 'GET',
            headers: {
                'accept': 'application/json, text/plain, */*',
                'authorization': 'AT-68c517457761645230526862lrx8ruxmrxwq0enw',
                'x-b3-traceid': 'dba620e6f7ba1f67',
                'x-subsystem': 'ares',
                'referer': 'https://pro.xiaohongshu.com/im/multiCustomerService',
                'sec-fetch-dest': 'empty',
                'sec-fetch-mode': 'cors',
                'sec-fetch-site': 'same-origin',
                'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0'
            },
            credentials: 'include'  // 包含cookies
        });

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const data = await response.json();
        
        // 检查响应是否成功并返回data部分
        if (data.success && data.code === 0) {
            return {
                success: true,
                data: data.data
            };
        } else {
            return {
                success: false,
                error: data.msg || '获取数据失败'
            };
        }

    } catch (error) {
        console.error('Error fetching upload token:', error);
        return {
            success: false,
            error: error.message
        };
    }
}

// 使用示例
async function example() {
    try {
        const result = await getUploadTokenData();
        if (result.success) {
            console.log('Upload permits:', result.data.upload_temp_permits);
            console.log('Result:', result.data.result);
            
            // 获取具体的上传许可信息
            const permit = result.data.upload_temp_permits[0];
            console.log('File ID:', permit.file_ids[0]);
            console.log('Upload Token:', permit.token);
            console.log('Upload Address:', permit.upload_addr);
            console.log('Expire Time:', new Date(permit.expire_time));
        } else {
            console.error('Failed to get data:', result.error);
        }
    } catch (error) {
        console.error('Error:', error);
    }
}

// 执行示例
example();



//第二步put上传图片
async function uploadImageUrl(imageUrl) {
    // 1. 首先获取图片数据
    const imageResponse = await fetch(imageUrl);
    const imageBlob = await imageResponse.blob();

    // 2. 准备上传请求
    const uploadUrl = 'https://ros-upload.xiaohongshu.com/rimmatrix/V6nuam8zyZhLcjZdJfl1HEkhCXSx3GHlj2os4CEpSlVYbzo';

    try {
        const response = await fetch(uploadUrl, {
            method: 'PUT',
            headers: {
                'accept': '*/*',
                'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
                'authorization': 'q-sign-algorithm=sha1&q-ak=null&q-sign-time=1736479724;1736566124&q-key-time=1736479724;1736566124&q-header-list=content-length;host&q-url-param-list=&q-signature=18d7f7bce19414d500bf7bf33b2b027bc8fecc88',
                'content-type': 'image/jpeg',
                'origin': 'https://pro.xiaohongshu.com',
                'referer': 'https://pro.xiaohongshu.com/',
                'x-cos-security-token': 'iFbRMAXXIamH6mFfYAecIk6sRug:eyJkZWFkbGluZSI6MTczNjU3MDQ0OSwiYWxsb3dQcmVmaXhlcyI6WyJWNm51YW04enlaaExjalpkSmZsMUhFa2hDWFN4M0dIbGoyb3M0Q0VwU2xWWWJ6byJdfQ',
                'sec-ch-ua': '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
                'sec-ch-ua-mobile': '?0',
                'sec-ch-ua-platform': '"Windows"',
                'sec-fetch-dest': 'empty',
                'sec-fetch-mode': 'cors',
                'sec-fetch-site': 'same-site'
            },
            body: imageBlob
        });

        if (response.ok) {
            const previewUrl = response.headers.get('x-ros-preview-url');
            return {
                success: true,
                previewUrl: previewUrl,
                etag: response.headers.get('etag')
            };
        } else {
            throw new Error(`Upload failed with status: ${response.status}`);
        }
    } catch (error) {
        console.error('Error uploading image:', error);
        return {
            success: false,
            error: error.message
        };
    }
}

// 使用示例:
const imageUrl = 'https://filecenter.kyliao.com:89/KYL/1/wxid_2a1a5t10214712/2025-01-09/3a71fa92-dce7-475f-ae44-ed62c79f7b5d.png'; // 替换为您的图片URL
uploadImageUrl(imageUrl)
    .then(result => {
        if (result.success) {
            console.log('Upload successful!');
            console.log('Preview URL:', result.previewUrl);
            console.log('ETag:', result.etag);
        } else {
            console.error('Upload failed:', result.error);
        }
    })
    .catch(error => {
        console.error('Error:', error);
    });

(0,
                                        De.Ix)
										
										
//最后一步 msg发送
async function testSend() {
    try {
        // 先构造图片数据对象
        const imageData = {
            link: {
                cloudType: 4,
                bizName: "cs",
                scene: "feeva_img",
                fileId: "rimmatrix/RWuNee2PEHOq7_jYoFamLUouQZeS2uDXIbpwnuZr1F2CudM",
                preViewUrl: "https://ros-preview.xhscdn.com/rimmatrix/V6nuam8zyZhLcjZdJfl1HEkhCXSx3GHlj2os4CEpSlVYbzo?sign=ae5c1f2b90482122bd9262a2cfa12da6&t=1736485284"
            },
            size: {
                width: 337,
                height: 170
            }
        };

        console.log('当前 cookie:', document.cookie);
        
        // 发送消息时,需要修改 message_type 为 "IMAGE"
        const messageData = {
            sender_porch_id: "677e116404ee000000000001",
            receiver_id: "612368ee000000000101cd0c",
            content: JSON.stringify(imageData),  // 将图片数据转换为字符串
            message_type: "IMAGE",  // 改为 IMAGE 类型
            platform: 3,
            uuid: uuid()
        };

        const result = await sendChatMessage(messageData);
        console.log('发送结果:', result);
    } catch (error) {
        console.error('发送出错:', error);
    }
}

// 修改 sendChatMessage 函数,直接接收消息数据对象
async function sendChatMessage(messageData) {
    const url = 'https://pro.xiaohongshu.com/api/edith/ads/pro/chat/chatline/msg';
    const params = new URLSearchParams({
        porch_user_id: '677e116404ee000000000001'
    });

    const headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-encoding': 'gzip, deflate, br, zstd',
        'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'authorization': 'AT-68c517457761645230526862lrx8ruxmrxwq0enw',
        'content-type': 'application/json',
        'origin': 'https://pro.xiaohongshu.com',
        'referer': 'https://pro.xiaohongshu.com/im/multiCustomerService',
        'sec-ch-ua': '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0',
        'x-subsystem': 'ares'
    };

    try {
        console.log('发送数据:', messageData);
        
        const response = await fetch(`${url}?${params}`, {
            method: 'POST',
            headers: headers,
            credentials: 'include',
            body: JSON.stringify(messageData)
        });

        if (!response.ok) {
            const errorText = await response.text();
            console.error('错误详情:', errorText);
            throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
        }

        const result = await response.json();
        console.log('发送成功:', result);
        return result;
    } catch (error) {
        console.error('发送失败:', error);
        throw error;
    }
}
// 执行测试
testSend();

回撤功能

//先发送消息 然后获取id
async function sendPostRequest() {
    const url = 'https://pro.xiaohongshu.com/api/edith/ads/pro/chat/chatline/msg?porch_user_id=677e116404ee000000000001';

    const payload = {
        sender_porch_id: "677e116404ee000000000001",
        receiver_id: "612368ee000000000101cd0c",
        content: "ccccc",
        message_type: "TEXT",
        platform: 3,
        uuid: "1736478957090-43350413"
    };

    const headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-encoding': 'gzip, deflate, br, zstd',
        'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'authorization': 'AT-68c517457761645230526862lrx8ruxmrxwq0enw',
        'content-type': 'application/json',
        'origin': 'https://pro.xiaohongshu.com',
        'referer': 'https://pro.xiaohongshu.com/im/multiCustomerService',
        'sec-ch-ua': '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0',
        'x-subsystem': 'ares',
        'cookie': 'abRequestId=f2154e9b-797b-5124-baaa-c2afb64b6f79; a1=194491d8b8fa14itukoamsqt4nf4p629kv1nvnb1250000382687; webId=0a7ab39304a5a8d090bd6ddcc8848598; web_session=030037a04c168270c118ba0407204a3a7c64a9; gid=yj44jyfj08Tfyj44jyfYDhIDYi0y4397Tl06yyJMA94IiI284UKJjh888qYJKYW8SjS84q4j; customerClientId=621527812963092; customer-sso-sid=68c5174577616452305268601fca10ccf489f9fe; x-user-id-pro.xiaohongshu.com=63a188ad0000000026013607; access-token-pro.xiaohongshu.com=customer.ares.AT-68c517457761645230526862lrx8ruxwq0enw; access-token-pro.beta.xiaohongshu.com=customer.ares.AT-68c517457761645230526862lrx8ruxwq0enw; xsecappid=pro-base; acw_tc=0a0d0e0317364784102826015e342af72d01e74806b984ca4f111406df3b0f; websectiga=10f9a40ba454a07755a08f27ef8194c53637eba4551cf9751c009d9afb564467; sec_poison_id=611c6572-b0c6-43fc-a7e7-dd15e153861d'
    };

    try {
        const response = await fetch(url, {
            method: 'POST',
            headers: headers,
            body: JSON.stringify(payload)
        });

        if (!response.ok) {
            const errorText = await response.text();
            console.error('请求失败:', errorText);
            throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
        }

        const result = await response.json();
        console.log('请求成功:', result);

        // 提取 message_id
        const messageId = result.data?.message_id;
        if (messageId) {
            console.log('Message ID:', messageId);
        } else {
            console.log('Message ID not found in response');
        }

        return result;
    } catch (error) {
        console.error('请求出错:', error);
        throw error;
    }
}

// 调用函数发送请求
sendPostRequest();





async function sendDeleteRequest() {
    const url = 'https://pro.xiaohongshu.com/api/edith/ads/pro/chat/chatline/msg';
    const params = new URLSearchParams({
        porch_user_id: '677e116404ee000000000001',
        id: '612368ee000000000101cd0c.63a188ad0000000026013607.1e78093375f6b8a',
        customer_user_id: '612368ee000000000101cd0c'
    });

    const headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-encoding': 'gzip, deflate, br, zstd',
        'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'authorization': 'AT-68c517457761645230526862lrx8ruxmrxwq0enw',
        'origin': 'https://pro.xiaohongshu.com',
        'referer': 'https://pro.xiaohongshu.com/im/multiCustomerService',
        'sec-ch-ua': '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0',
        'x-subsystem': 'ares',
        'cookie': 'abRequestId=f2154e9b-797b-5124-baaa-c2afb64b6f79; a1=194491d8b8fa14itukoamsqt4nf4p629kv1nvnb1250000382687; webId=0a7ab39304a5a8d090bd6ddcc8848598; web_session=030037a04c168270c118ba0407204a3a7c64a9; gid=yj44jyfj08Tfyj44jyfYDhIDYi0y4397Tl06yyJMA94IiI284UKJjh888qYJKYW8SjS84q4j; customerClientId=621527812963092; customer-sso-sid=68c5174577616452305268601fca10ccf489f9fe; x-user-id-pro.xiaohongshu.com=63a188ad0000000026013607; access-token-pro.xiaohongshu.com=customer.ares.AT-68c517457761645230526862lrx8ruxmrxwq0enw; access-token-pro.beta.xiaohongshu.com=customer.ares.AT-68c517457761645230526862lrx8ruxmrxwq0enw; xsecappid=pro-base; acw_tc=0a0d0e0317364784102826015e342af72d01e74806b984ca4f111406df3b0f; websectiga=cf46039d1971c7b9a650d87269f31ac8fe3bf71d61ebf9d9a0a87efb414b816c; sec_poison_id=b36eccf0-9bce-4f66-8da8-20cd23f25541'
    };

    try {
        const response = await fetch(`${url}?${params}`, {
            method: 'DELETE',
            headers: headers
        });

        if (!response.ok) {
            const errorText = await response.text();
            console.error('请求失败:', errorText);
            throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
        }

        const result = await response.json();
        console.log('请求成功:', result);
        return result;
    } catch (error) {
        console.error('请求出错:', error);
        throw error;
    }
}

// 调用函数发送请求
sendDeleteRequest();

获取头像和昵称

async function getChatList() {
    const url = 'https://pro.xiaohongshu.com/api/edith/ads/pro/chat/chatline/chat';
    
    const params = new URLSearchParams({
        porch_user_id: '677e116404ee000000000001',
        limit: '80'
    });

    const headers = {
        'authority': 'pro.xiaohongshu.com',
        'accept': 'application/json, text/plain, */*',
        'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'authorization': 'AT-68c517457761645230526862lrx8ruxmrxwq0enw',
        'cookie': 'abRequestId=f2154e9b-797b-5124-baaa-c2afb64b6f79; a1=194491d8b8fa14itukoamsqt4nf4p629kv1nvnb1250000382687; webId=0a7ab39304a5a8d090bd6ddcc8848598; web_session=030037a04c168270c118ba0407204a3a7c64a9; gid=yj44jyfj08Tfyj44jyfYDhIDYi0y4397Tl06yyJMA94IiI284UKJjh888qYJKYW8SjS84q4j; customerClientId=621527812963092; customer-sso-sid=68c5174577616452305268601fca10ccf489f9fe; x-user-id-pro.xiaohongshu.com=63a188ad0000000026013607; access-token-pro.xiaohongshu.com=customer.ares.AT-68c517457761645230526862lrx8ruxmrxwq0enw; access-token-pro.beta.xiaohongshu.com=customer.ares.AT-68c517457761645230526862lrx8ruxmrxwq0enw; xsecappid=pro-base; acw_tc=0a4252f017364116529762089e968dff6b8b6e47ea444b0b76026fa2d1e664; websectiga=9730ffafd96f2d09dc024760e253af6ab1feb0002827740b95a255ddf6847fc8; sec_poison_id=f5e5bad7-0c91-4002-8189-51147435d119',
        'referer': 'https://pro.xiaohongshu.com/im/liberal',
        'sec-ch-ua': '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0',
        'x-subsystem': 'ares'
    };

    try {
        const response = await fetch(`${url}?${params.toString()}`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const data = await response.json();
        
        if (data.success && data.data && data.data.chat_list) {
            // 格式化聊天列表数据
            const formattedChats = data.data.chat_list.map(chat => {
                const timestamp = chat.sixin_chat.last_msg_ts;
                const date = new Date(timestamp);
                
                return {
                    // 用户基本信息
                    userInfo: {
                        userId: chat.sixin_chat.user_id,
                        nickname: chat.sixin_chat.nickname,
                        avatarUrl: chat.sixin_chat.avatar,
                        avatarLink: `头像链接: ${chat.sixin_chat.avatar}` // 新增头像链接显示
                    },
                    // 最后一条消息信息
                    lastMessage: {
                        content: chat.sixin_chat.last_msg_content,
                        timestamp: timestamp,
                        formattedTime: date.toLocaleString(),
                        storeId: chat.sixin_chat.last_store_id
                    },
                    // 会话信息
                    sessionInfo: {
                        sessionId: chat.session.session_id,
                        status: chat.session.state,
                        replied: chat.session.is_replied,
                        grantorUserId: chat.session.grantor_user_id
                    },
                    // 聊天状态
                    chatStatus: {
                        isActive: chat.long_chat_view.active,
                        isFavorite: chat.long_chat_view.favorite,
                        lastActiveTime: new Date(chat.long_chat_view.last_msg_ts).toLocaleString(),
                        isBlacklisted: chat.in_blacklist
                    }
                };
            });

            // 打印格式化后的数据
            console.log('\n=== 聊天列表摘要 ===');
            formattedChats.forEach((chat, index) => {
                console.log(`\n【聊天 ${index + 1}】`);
                console.log(`用户: ${chat.userInfo.nickname}`);
                console.log(`ID: ${chat.userInfo.userId}`);
                console.log(chat.userInfo.avatarLink);  // 显示头像链接
                console.log(`最新消息: ${chat.lastMessage.content}`);
                console.log(`发送时间: ${chat.lastMessage.formattedTime}`);
                console.log(`会话状态: ${chat.sessionInfo.status}`);
                console.log(`已回复: ${chat.sessionInfo.replied ? '是' : '否'}`);
                console.log(`活跃状态: ${chat.chatStatus.isActive ? '活跃' : '不活跃'}`);
                console.log('------------------------');
            });

            // 保存完整数据到文件
            if (typeof require !== 'undefined') {
                const fs = require('fs');
                fs.writeFileSync(
                    'formatted_chat_list.json', 
                    JSON.stringify(formattedChats, null, 2)
                );
                console.log('\n详细数据已保存到 formatted_chat_list.json');
            }

            return formattedChats;
        }
        
        return null;
        
    } catch (error) {
        console.error('获取聊天列表失败:', error.message);
        return null;
    }
}

// main函数保持不变
async function main() {
    try {
        console.log('正在获取聊天列表...');
        const chatList = await getChatList();
        
        if (chatList) {
            console.log(`\n成功获取 ${chatList.length} 个聊天会话`);
            
            // 统计信息
            const stats = {
                activeChats: chatList.filter(chat => chat.chatStatus.isActive).length,
                repliedChats: chatList.filter(chat => chat.sessionInfo.replied).length,
                favoriteChats: chatList.filter(chat => chat.chatStatus.isFavorite).length
            };
            
            console.log('\n=== 统计信息 ===');
            console.log(`活跃会话: ${stats.activeChats}`);
            console.log(`已回复会话: ${stats.repliedChats}`);
            console.log(`收藏会话: ${stats.favoriteChats}`);
            
            return chatList;
        }
    } catch (error) {
        console.error('执行出错:', error);
    }
}

// 运行代码
main().catch(console.error);

完整Class封裝結合代碼

class XiaohongshuAPI {
    constructor() {
        this.baseUrl = 'https://pro.xiaohongshu.com/api';
        this.porchUserId = '677e116404ee000000000001';
        this.receiverId = '612368ee000000000101cd0c';
        this.headers = {
            'accept': 'application/json, text/plain, */*',
            'accept-encoding': 'gzip, deflate, br, zstd',
            'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
            'authorization': 'AT-68c517457761645230526862lrx8ruxmrxwq0enw',
            'content-type': 'application/json',
            'origin': 'https://pro.xiaohongshu.com',
            'referer': 'https://pro.xiaohongshu.com/im/multiCustomerService',
            'sec-ch-ua': '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"Windows"',
            'sec-fetch-dest': 'empty',
            'sec-fetch-mode': 'cors',
            'sec-fetch-site': 'same-origin',
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0',
            'x-b3-traceid': 'c46a27c6cb6be409',
            'x-subsystem': 'ares',
            'cookie': document.cookie // 确保在浏览器环境中使用
        };
    }

    // 工具方法: 生成 UUID(需要实现或使用现有库)
    generateUUID() {
        // 简单的UUID生成方法(不保证唯一性,推荐使用库如 'uuid')
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }

    // 查看用户登录状态
    async fetchUserInfo() {
        const url = `${this.baseUrl}/eros/user/info`;

        try {
            const response = await fetch(url, {
                method: 'GET',
                headers: this.headers,
                credentials: 'include'
            });

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const result = await response.json();

            // 检查是否有 data 字段
            if (result.data) {
                console.log('用户信息:', result.data);
                return result.data;
            } else {
                console.log('响应中未找到 data 字段');
                return null;
            }
        } catch (error) {
            console.error('获取用户信息时出错:', error);
            return null;
        }
    }

    // 发送消息
    async sendChatMessage(messageData) {
        const url = `${this.baseUrl}/edith/ads/pro/chat/chatline/msg`;
        const params = new URLSearchParams({
            porch_user_id: this.porchUserId
        });

        try {
            console.log('发送消息数据:', messageData);

            const response = await fetch(`${url}?${params}`, {
                method: 'POST',
                headers: this.headers,
                credentials: 'include',
                body: JSON.stringify(messageData)
            });

            if (!response.ok) {
                const errorText = await response.text();
                console.error('POST 请求失败:', errorText);
                throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
            }

            const result = await response.json();
            console.log('发送成功:', result);

            const messageId = result.data?.message_id;
            if (messageId) {
                console.log('消息 ID:', messageId);
                return messageId;
            } else {
                console.log('响应中未找到消息 ID');
                return null;
            }
        } catch (error) {
            console.error('发送消息时出错:', error);
            return null;
        }
    }

    // 撤回消息
    async sendDeleteRequest(messageId) {
        const deleteUrl = `${this.baseUrl}/edith/ads/pro/chat/chatline/msg`;
        const params = new URLSearchParams({
            porch_user_id: this.porchUserId,
            id: messageId,
            customer_user_id: this.receiverId
        });

        try {
            const response = await fetch(`${deleteUrl}?${params}`, {
                method: 'DELETE',
                headers: this.headers
            });

            if (!response.ok) {
                const errorText = await response.text();
                console.error('DELETE 请求失败:', errorText);
                throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
            }

            const deleteResult = await response.json();
            console.log('DELETE 请求成功:', deleteResult);
            return deleteResult;
        } catch (error) {
            console.error('撤回消息时出错:', error);
            return null;
        }
    }

    // 撤回模块: 发送消息并撤回
    async sendPostAndDeleteRequest(content = "ccccc") {
        try {
            // Step 1: 发送消息
            const messageId = await this.sendChatMessage({
                sender_porch_id: this.porchUserId,
                receiver_id: this.receiverId,
                content: content,
                message_type: "TEXT",
                platform: 3,
                uuid: this.generateUUID()
            });

            if (messageId) {
                // Step 2: 撤回消息
                await this.sendDeleteRequest(messageId);
            }
        } catch (error) {
            console.error('发送或撤回消息时出错:', error);
        }
    }

    // 获取聊天列表
    async getChatList() {
        const url = `${this.baseUrl}/edith/ads/pro/chat/chatline/chat`;
        const params = new URLSearchParams({
            porch_user_id: this.porchUserId,
            limit: '80'
        });

        try {
            const response = await fetch(`${url}?${params.toString()}`, {
                method: 'GET',
                headers: this.headers
            });

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const data = await response.json();
            if (data.success && data.data && data.data.chat_list) {
                const formattedChats = data.data.chat_list.map(chat => {
                    const timestamp = chat.sixin_chat.last_msg_ts;
                    const date = new Date(timestamp);

                    return {
                        userInfo: {
                            userId: chat.sixin_chat.user_id,
                            nickname: chat.sixin_chat.nickname,
                            avatarUrl: chat.sixin_chat.avatar,
                            avatarLink: `头像链接: ${chat.sixin_chat.avatar}`
                        },
                        lastMessage: {
                            content: chat.sixin_chat.last_msg_content,
                            timestamp: timestamp,
                            formattedTime: date.toLocaleString(),
                            storeId: chat.sixin_chat.last_store_id
                        },
                        sessionInfo: {
                            sessionId: chat.session.session_id,
                            status: chat.session.state,
                            replied: chat.session.is_replied,
                            grantorUserId: chat.session.grantor_user_id
                        },
                        chatStatus: {
                            isActive: chat.long_chat_view.active,
                            isFavorite: chat.long_chat_view.favorite,
                            lastActiveTime: new Date(chat.long_chat_view.last_msg_ts).toLocaleString(),
                            isBlacklisted: chat.in_blacklist
                        }
                    };
                });

                console.log('\n=== 聊天列表摘要 ===');
                formattedChats.forEach((chat, index) => {
                    console.log(`\n【聊天 ${index + 1}】`);
                    console.log(`用户: ${chat.userInfo.nickname}`);
                    console.log(`ID: ${chat.userInfo.userId}`);
                    console.log(chat.userInfo.avatarLink);
                    console.log(`最新消息: ${chat.lastMessage.content}`);
                    console.log(`发送时间: ${chat.lastMessage.formattedTime}`);
                    console.log(`会话状态: ${chat.sessionInfo.status}`);
                    console.log(`已回复: ${chat.sessionInfo.replied ? '是' : '否'}`);
                    console.log(`活跃状态: ${chat.chatStatus.isActive ? '活跃' : '不活跃'}`);
                    console.log('------------------------');
                });

                // 保存完整数据到文件
                if (typeof require !== 'undefined') {
                    const fs = require('fs');
                    fs.writeFileSync(
                        'formatted_chat_list.json',
                        JSON.stringify(formattedChats, null, 2)
                    );
                    console.log('\n详细数据已保存到 formatted_chat_list.json');
                }

                return formattedChats;
            }

            console.log('响应数据不符合预期');
            return null;
        } catch (error) {
            console.error('获取聊天列表失败:', error.message);
            return null;
        }
    }

    // 获取上传令牌数据
    async getUploadTokenData() {
        const url = `${this.baseUrl}/edith/ads/pro/chat/uploader/v3/token`;
        const params = new URLSearchParams({
            biz_name: 'cs',
            scene: 'feeva_img',
            file_count: '1',
            version: '1',
            source: 'web'
        });

        try {
            const response = await fetch(`${url}?${params}`, {
                method: 'GET',
                headers: {
                    'accept': 'application/json, text/plain, */*',
                    'authorization': 'AT-68c517457761645230526862lrx8ruxmrxwq0enw',
                    'x-b3-traceid': 'dba620e6f7ba1f67',
                    'x-subsystem': 'ares',
                    'referer': 'https://pro.xiaohongshu.com/im/multiCustomerService',
                    'sec-fetch-dest': 'empty',
                    'sec-fetch-mode': 'cors',
                    'sec-fetch-site': 'same-origin',
                    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0'
                },
                credentials: 'include'
            });

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const data = await response.json();
            if (data.success && data.code === 0) {
                return data.data.upload_temp_permits[0];
            } else {
                throw new Error(data.msg || '获取上传令牌数据失败');
            }
        } catch (error) {
            console.error('获取上传令牌时出错:', error);
            throw error;
        }
    }

    // 上传图片
    async uploadImage(imageUrl, permit) {
        try {
            const imageResponse = await fetch(imageUrl);
            const imageBlob = await imageResponse.blob();

            console.log('上传令牌:', permit.token);
            console.log('上传地址:', permit.upload_addr);
            console.log('文件ID:', permit.file_ids[0]);

            const uploadUrl = `https://ros-upload.xiaohongshu.com/${permit.file_ids[0]}`;

            const response = await fetch(uploadUrl, {
                method: 'PUT',
                headers: {
                    'accept': '*/*',
                    'content-type': 'image/jpeg',
                    'authorization': permit.token,
                    'origin': 'https://pro.xiaohongshu.com',
                    'referer': 'https://pro.xiaohongshu.com/',
                    'x-cos-security-token': permit.token,
                    'sec-ch-ua': '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
                    'sec-ch-ua-mobile': '?0',
                    'sec-ch-ua-platform': '"Windows"',
                    'sec-fetch-dest': 'empty',
                    'sec-fetch-mode': 'cors',
                    'sec-fetch-site': 'same-site'
                },
                body: imageBlob
            });

            if (response.ok) {
                const previewUrl = response.headers.get('x-ros-preview-url');
                console.log('图片上传成功,预览URL:', previewUrl);
                return {
                    success: true,
                    fileId: permit.file_ids[0],
                    previewUrl: previewUrl
                };
            } else {
                throw new Error(`图片上传失败,状态码: ${response.status}`);
            }
        } catch (error) {
            console.error('上传图片时出错:', error);
            throw error;
        }
    }

    // 执行完整流程: 获取上传令牌 -> 上传图片 -> 发送图片消息
    async executeWorkflow(imageUrl) {
        try {
            // Step 1: 获取上传令牌
            const permit = await this.getUploadTokenData();
            console.log('获取到的上传许可:', permit);

            // Step 2: 上传图片
            const uploadResult = await this.uploadImage(imageUrl, permit);
            if (!uploadResult.success) {
                throw new Error('图片上传失败');
            }

            // Step 3: 发送图片消息
            const imageData = {
                link: {
                    cloudType: 4,
                    bizName: "cs",
                    scene: "feeva_img",
                    fileId: uploadResult.fileId,
                    preViewUrl: uploadResult.previewUrl
                },
                size: {
                    width: 337,
                    height: 170
                }
            };

            const messageData = {
                sender_porch_id: this.porchUserId,
                receiver_id: this.receiverId,
                content: JSON.stringify(imageData),
                message_type: "IMAGE",
                platform: 3,
                uuid: this.generateUUID()
            };

            const sendResult = await this.sendChatMessage(messageData);
            console.log('图片消息发送结果:', sendResult);
        } catch (error) {
            console.error('执行完整流程时出错:', error);
        }
    }

    // 获取未回复的聊天数据
    async getChatData() {
        const url = `${this.baseUrl}/edith/ads/pro/chat/chatline/chat`;
        const params = new URLSearchParams({
            porch_user_id: this.porchUserId,
            limit: '80',
            is_active: 'true'
        });

        try {
            const response = await fetch(`${url}?${params.toString()}`, {
                method: 'GET',
                headers: this.headers
            });

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const data = await response.json();
            const unrepliedChats = data.data.chat_list.filter(chat =>
                chat.session.is_replied === false
            );

            // 打印未回复的消息
            console.log('\n=== 未回复的消息 ===');
            unrepliedChats.forEach((chat, index) => {
                console.log(`\n--- 消息 ${index + 1} ---`);
                console.log('用户:', chat.sixin_chat.nickname);
                console.log('用户ID:', chat.sixin_chat.user_id);
                console.log('最后消息:', chat.sixin_chat.last_msg_content);
                console.log('发送时间:', new Date(chat.sixin_chat.last_msg_ts).toLocaleString());
                console.log('会话ID:', chat.session.session_id);
                console.log('会话状态:', chat.session.state);
            });

            // 如果在Node.js环境中,保存到文件
            if (typeof require !== 'undefined') {
                const fs = require('fs');
                fs.writeFileSync(
                    'full_response.json',
                    JSON.stringify(data, null, 2)
                );
                console.log('\n数据已保存到 full_response.json');
            }

            return data;
        } catch (error) {
            console.error('获取数据失败:', error.message);
            return null;
        }
    }
}

// 使用示例
const api = new XiaohongshuAPI();

// 查看用户登录状态
api.fetchUserInfo();

// 发送并撤回消息
api.sendPostAndDeleteRequest(id,contactIMID);

// 获取聊天列表
api.getChatList();

// 执行上传并发送图片的完整流程
const imageUrl = 'https://filecenter.kyliao.com:89/KYL/1/wxid_2a1a5t10214712/2025-01-09/3a71fa92-dce7-475f-ae44-ed62c79f7b5d.png'; // 替换为您的图片URL
api.executeWorkflow(imageUrl);

// 测试发送文本消息
// 测试发送文本消息
api.sendChatMessage({
    sender_porch_id: api.porchUserId,
    receiver_id: api.receiverId,
    content: "test message",
    message_type: "TEXT", // 确保包含 message_type
    platform: 3,
    uuid: api.generateUUID()
});

// 获取未回复的聊天数据
api.getChatData();


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/951833.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Center Loss 和 ArcFace Loss 笔记

一、Center Loss 1. 定义 Center Loss 旨在最小化类内特征的离散程度,通过约束样本特征与其类别中心之间的距离,提高类内特征的聚合性。 2. 公式 对于样本 xi​ 和其类别yi​,Center Loss 的公式为: xi​: 当前样本的特征向量&…

【Maui】动态菜单实现(绑定数据视图)

前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI,可从单个共享代码库开发可在 Android、iOS、macOS 和 Windows 上运行的应用。 .NET MAUI 是一款开放源代码应用,是 X…

【json】

JSON JSON是一种轻量级的,按照指定的格式去组织和封装数据的数据交互格式。 本质上是一个带有特定格式的字符串(py打印json时认定为str类型) 在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互,类似于计算机普通话 python与json关系及相互转换…

51单片机——中断(重点)

学习51单片机的重点及难点主要有中断、定时器、串口等内容,这部分内容一定要认真掌握,这部分没有学好就不能说学会了51单片机 1、中断系统 1.1 概念 中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的,中断功能的存在&#…

易支付二次元网站源码及部署教程

易支付二次元网站源码及部署教程 引言 在当今数字化时代,二次元文化逐渐成为年轻人生活中不可或缺的一部分。为了满足这一庞大用户群体的需求,搭建一个二次元主题网站显得尤为重要。本文将为您详细介绍易支付二次元网站源码的特点及其部署教程&#xf…

开源生成式物理引擎Genesis,可模拟世界万物

这是生成大模型时代 —— 它们能生成文本、图像、音频、视频、3D 对象…… 而如果将所有这些组合到一起,我们可能会得到一个世界! 现在,不管是 LeCun 正在探索的世界模型,还是李飞飞想要攻克的空间智能,又或是其他研究…

【fly-iot飞凡物联】(19):开源飞凡物联项目重启,使用go重写后端代码,感兴趣的小伙伴可以一起参加,使用apache协议开源,招募感兴趣的小伙伴!!

目录 前言fly-iot飞凡物联,感兴趣的小伙伴可以一起参加,使用apache协议开源使用go重写后端代码 前言 fly-iot飞凡物联专栏: https://blog.csdn.net/freewebsys/category_12219758.html fly-iot飞凡物联,感兴趣的小伙伴可以一起参…

用于与多个数据库聊天的智能 SQL 代理问答和 RAG 系统(3) —— 基于 LangChain 框架的文档检索与问答功能以及RAG Tool的使用

介绍基于 LangChain 框架的文档检索与问答功能,目标是通过查询存储的向量数据库(VectorDB),为用户的问题检索相关内容,并生成自然语言的答案。以下是代码逻辑的详细解析: 代码结构与功能 初始化环境与加载…

消息中间件类型介绍

消息中间件是一种在分布式系统中用于实现消息传递的软件架构模式。它能够在不同的系统或应用之间异步地传输数据,实现系统的解耦、提高系统的可扩展性和可靠性。以下是几种常见的消息中间件类型及其介绍: 1.RabbitMQ 特点: • 基于AMQP&#…

uniapp使用scss mixin抽离css常用的公共样式

1、编写通用scss样式文件 // 通用 Flex Mixin mixin flex($direction: row, $justify: flex-start, $align: stretch, $wrap: nowrap) {display: flex;flex-direction: $direction;justify-content: $justify;align-items: $align;flex-wrap: $wrap; }// 水平居中 mixin flex-…

Matlab Steger算法提取条纹中心线(亚像素位置)

文章目录 一、简介二、实现代码三、实现效果参考文献一、简介 Steger 算法是一种常用的图像边缘检测算法,可以用于提取图像中的中心线或边缘信息。它的理论假设是:条纹的亮度是按照高斯分布呈现的,即中心亮两侧渐暗。 其计算过程如下所述: 1、首先,我们需要计算每个点Hess…

PySide6 Qt for Python Qt Quick参考网址

Qt QML BOOK: 《Qt for Python》 -Building an Application https://www.qt.io/product/qt6/qml-book/ch19-python-build-app#signals-and-slots Qt for Python:与C版本的差异即BUG处理(常见的DLL文件确实的问题等) Qt for Pyt…

【大数据】Apache Superset:可视化开源架构

Apache Superset是什么 Apache Superset 是一个开源的现代化数据可视化和数据探索平台,主要用于帮助用户以交互式的方式分析和展示数据。有不少丰富的可视化组件,可以将数据从多种数据源(如 SQL 数据库、数据仓库、NoSQL 数据库等&#xff0…

ELK实战(最详细)

一、什么是ELK ELK是三个产品的简称:ElasticSearch(简称ES) 、Logstash 、Kibana 。其中: ElasticSearch:是一个开源分布式搜索引擎Logstash :是一个数据收集引擎,支持日志搜集、分析、过滤,支持大量数据…

汽车物资拍卖系统架构与功能分析

2015工作至今,10年资深全栈工程师,CTO,擅长带团队、攻克各种技术难题、研发各类软件产品,我的代码态度:代码虐我千百遍,我待代码如初恋,我的工作态度:极致,责任&#xff…

利用 Python 爬虫从义乌购根据关键词获取商品列表

在当今数字化商业时代,数据是企业获取竞争优势的关键。对于从事国际贸易的商家而言,能够及时、准确地获取商品信息至关重要。义乌购作为知名的国际贸易批发平台,汇集了海量的商品资源。通过 Python 爬虫技术,我们可以高效地从义乌…

HDFS编程 - 使用HDFS Java API进行文件操作

文章目录 前言一、创建hdfs-demo项目1. 在idea上创建maven项目2. 导入hadoop相关依赖 二、常用 HDFS Java API1. 简介2. 获取文件系统实例3. 创建目录4. 创建文件4.1 创建文件并写入数据4.2 创建新空白文件 5. 查看文件内容6. 查看目录下的文件或目录信息6.1 查看指定目录下的文…

直流无刷电机控制(FOC):电流模式

目录 概述 1 系统框架结构 1.1 硬件模块介绍 1.2 硬件实物图 1.3 引脚接口定义 2 代码实现 2.1 软件架构 2.2 电流检测函数 3 电流环功能实现 3.1 代码实现 3.2 测试代码实现 4 测试 概述 本文主要介绍基于DengFOC的库函数,实现直流无刷电机控制&#x…

51单片机——串口通信(重点)

1、通信 通信的方式可以分为多种,按照数据传送方式可分为串行通信和并行通信; 按照通信的数据同步方式,可分为异步通信和同步通信; 按照数据的传输方向又可分为单工、半双工和全双工通信 1.1 通信速率 衡量通信性能的一个非常…

如何在 Linux、MacOS 以及 Windows 中打开控制面板

控制面板不仅仅是一系列图标和菜单的集合;它是通往优化个人计算体验的大门。通过它,用户可以轻松调整从外观到性能的各种参数,确保他们的电脑能够完美地适应自己的需求。无论是想要提升系统安全性、管理硬件设备,还是简单地改变桌…