JS爬虫实战演练

news2025/1/15 13:33:50

在这个小红书私信通里面进行一个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.coloradmin.cn/o/2277027.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自动连接校园网wifi脚本实践(自动网页认证)

目录 起因执行步骤分析校园网登录逻辑如何判断当前是否处于未登录状态? 书写代码打包设置开机自动启动 起因 我们一般通过远程控制的方式访问实验室电脑,但是最近实验室老是断电,但重启后也不会自动连接校园网账户认证,远程工具&…

WPS计算机二级•表格函数计算

听说这里是目录哦 函数基础知识 相对绝对混合引用🌪️相对引用绝对引用混合引用 常用求和函数 SUM函数🌦️语法说明 函数快速求 平均数最值⚡平均数最值 实用统计函数 实现高效统计🌀COUNTCOUNTIF 实用文本函数 高效整理数据🌈RIG…

自动化测试工具Ranorex Studio(八十九)-解决方案浏览器

解决方案浏览器 除了为项目添加条目外,’Solution Explorer’允许你编辑解决方案的其他辅助选项。 例如,增加文件夹从而将项目中的录制模块和代码模块分离开来。 图:在solution browser中为项目添加文件夹 另外,你可以删除不用的…

2025 年 UI 大屏设计新风向

在科技日新月异的 2025 年,UI 大屏设计领域正经历着深刻的变革。随着技术的不断进步和用户需求的日益多样化,新的设计风向逐渐显现。了解并掌握这些趋势,对于设计师打造出更具吸引力和实用性的 UI 大屏作品至关重要。 一、沉浸式体验设计 如…

绘制三角形、正六边形、五角星、六角星

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>绘制图形</title><style>body {displ…

LLM实现视频切片合成 前沿知识调研

1.相关产品 产品链接腾讯智影https://zenvideo.qq.com/可灵https://klingai.kuaishou.com/即梦https://jimeng.jianying.com/ai-tool/home/Runwayhttps://aitools.dedao.cn/ai/runwayml-com/Descripthttps://www.descript.com/?utm_sourceai-bot.cn/Opus Cliphttps://www.opu…

Node.js - HTTP

1. HTTP请求 HTTP&#xff08;Hypertext Transfer Protocol&#xff0c;超文本传输协议&#xff09;是客户端和服务器之间通信的基础协议。HTTP 请求是由客户端&#xff08;通常是浏览器、手机应用或其他网络工具&#xff09;发送给服务器的消息&#xff0c;用来请求资源或执行…

鸿蒙中自定义slider实现字体大小变化

ui&#xff1a; import { display, mediaquery, router } from kit.ArkUI import CommonConstants from ./CommonConstants; import PreferencesUtil from ./PreferencesUtil; import StyleConstants from ./StyleConstants;// 字体大小 Entry Component struct FontSize {Sta…

Springboot + vue 小区物业管理系统

&#x1f942;(❁◡❁)您的点赞&#x1f44d;➕评论&#x1f4dd;➕收藏⭐是作者创作的最大动力&#x1f91e; &#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论 &#x1f525;&#x1f525;&…

uni-app编写微信小程序使用uni-popup搭配uni-popup-dialog组件在ios自动弹出键盘。

uni-popup-dialog 对话框 将 uni-popup 的type属性改为 dialog&#xff0c;并引入对应组件即可使用对话框 &#xff0c;该组件不支持单独使用 示例 <button click"open">打开弹窗</button> <uni-popup ref"popup" type"dialog"…

RabbitMQ中有哪几种交换机类型?

大家好&#xff0c;我是锋哥。今天分享关于【RabbitMQ中有哪几种交换机类型&#xff1f;】面试题。希望对大家有帮助&#xff1b; RabbitMQ中有哪几种交换机类型&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在RabbitMQ中&#xff0c;交换机&#xf…

Uniapp中实现加载更多、下拉刷新、返回顶部功能

一、加载更多&#xff1a; 在到达底部时&#xff0c;将新请求过来的数据追加到原来的数组即可&#xff1a; import {onReachBottom } from "dcloudio/uni-app";const pets ref([]); // 显示数据function network() {uni.request({url: "https://api.thecatap…

Kotlin 循环语句详解

文章目录 循环类别for-in 循环区间整数区间示例1&#xff1a;正向遍历示例2&#xff1a;反向遍历 示例1&#xff1a;遍历数组示例2&#xff1a;遍历区间示例3&#xff1a;遍历字符串示例4&#xff1a;带索引遍历 while 循环示例&#xff1a;计算阶乘 do-while 循环示例&#xf…

【零基础租赁实惠GPU推荐及大语言模型部署教程01】

租赁GPU推荐及大语言模型部署简易教程 1 官网地址2 注册账号及登录3 租用GPU3.1 充值&#xff08;不限制充值最低金额&#xff0c;1元亦可&#xff09;3.2 容器实例&#xff08;实际就是你租用的GPU电脑&#xff09;3.3 选择镜像&#xff08;选择基础环境&#xff1a;框架版本和…

Centos 宝塔安装

yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh 安装成功界面 宝塔说明文档 https://www.bt.cn/admin/servers#wcu 或者可以注册宝塔账号 1 快速部署 安装docker 之后 2 需要在usr/bin下下载do…

新版AndroidStudio通过系统快捷创建带BottomNavigationView的项目踩坑记录

选择上面这个玩意创建的项目 坑点1 &#xff1a;配置的写法和不一样了 镜像的写法&#xff1a; 新的settings.gradle.kts中配置镜像的代码&#xff1a; pluginManagement {repositories {mavenCentral()google {content {includeGroupByRegex("com\\.android.*")…

Java中网络编程的学习

目录 网络编程概述 网络模型 网络通信三要素: IP 端口号 通信协议 IP地址&#xff08;Internet Protocol Address&#xff09; 端口号 网络通信协议 TCP 三次握手 四次挥手 UDP TCP编程 客户端Socket的工作过程包含以下四个基本的步骤&#xff1a; 服务器程序…

浅谈云计算03 | 云计算的技术支撑(云使能技术)

云计算的技术支撑 一、定义与内涵1.1 定义与内涵 二、云计算使能技术架构2.1 宽带网络和 Internet 架构2.2 数据中心技术2.3 虚拟化技术2.4 Web 技术2.5 多租户技术2.6 服务技术 一、定义与内涵 1.1 定义与内涵 云计算技术包含一些基础的关键技术&#xff0c;这里称为使能技术…

腾讯云AI代码助手编程挑战赛-智能聊天助手

作品简介 本作品开发于腾讯云 AI 代码助手编程挑战赛&#xff0c;旨在体验腾讯云 AI 代码助手在项目开发中的助力。通过这一开发过程&#xff0c;体验到了 AI 辅助编程的高效性。 技术架构 前端: 使用 VUE3、TypeScript、TDesign 和 ElementUI 实现。 后端: 基于 Python 开发…

pip install hnswlib安装不成功

参考这个文章解决了问题&#xff1a;ERROR: Could not build wheels for hnswlib, which is required to install pyproject.toml-based projects 以下是我安装的时候&#xff0c;报错&#xff1a; Building wheel for hnswlib (pyproject.toml) ... errorerror: subprocess-e…