当前位置: 首页 > article >正文

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();



http://www.kler.cn/a/488434.html

相关文章:

  • 基于单片机的无线智能窗帘控制器的设计
  • springboot整合拦截器
  • 手机的ip地址是根据电话卡归属地定吗
  • 基于vue的商城小程序的毕业设计与实现(源码及报告)
  • 从零开始:使用VSCode搭建Python数据科学开发环境
  • n 维数组(张量)关于轴 axis 的理解
  • js观察者模式
  • nginx反向代理和负载均衡的区别
  • 【LeetCode】303. 区域和检索 - 数组不可变
  • linux 设置mysql 外网访问
  • 微信原生小程序自定义封装组件(以导航navbar为例)
  • 1.3作业
  • 机器学习的基本原理和算法
  • 缓存-Redis-API-Redisson-可重试
  • OpenCV轮廓相关操作API (C++)
  • 探索 Docker Desktop:简化开发与部署的利器
  • 4.3.1 树、二叉树基本概念
  • 阿里云直播互动Web
  • R.swift库的详细用法
  • JavaScript系列(18)--异步编程模式
  • 【UI自动化测试】selenium操作补充
  • 【Docker】docker compose 安装 Redis Stack
  • Linux 文件的特殊权限—ACL权限控制
  • JavaScript Chrome 中的运行
  • Android 12.0 mtk平板camera2横屏预览旋转90度横屏保存录像旋转90度功能实现
  • Python对象的序列化和反序列化工具:Joblib与Pickle