chatmsg.js
1 import { cli, Strategy } from '@jackwener/opencli/registry'; 2 import { requirePage, navigateToChat, bossFetch, findFriendByUid } from './utils.js'; 3 cli({ 4 site: 'boss', 5 name: 'chatmsg', 6 description: 'BOSS直聘查看与候选人的聊天消息', 7 domain: 'www.zhipin.com', 8 strategy: Strategy.COOKIE, 9 navigateBefore: false, 10 browser: true, 11 args: [ 12 { name: 'uid', required: true, positional: true, help: 'Encrypted UID (from chatlist)' }, 13 { name: 'page', type: 'int', default: 1, help: 'Page number' }, 14 ], 15 columns: ['from', 'type', 'text', 'time'], 16 func: async (page, kwargs) => { 17 requirePage(page); 18 await navigateToChat(page); 19 const friend = await findFriendByUid(page, kwargs.uid); 20 if (!friend) 21 throw new Error('未找到该候选人'); 22 const gid = friend.uid; 23 const securityId = encodeURIComponent(friend.securityId); 24 const msgUrl = `https://www.zhipin.com/wapi/zpchat/boss/historyMsg?gid=${gid}&securityId=${securityId}&page=${kwargs.page}&c=20&src=0`; 25 const msgData = await bossFetch(page, msgUrl); 26 const TYPE_MAP = { 27 1: '文本', 2: '图片', 3: '招呼', 4: '简历', 5: '系统', 28 6: '名片', 7: '语音', 8: '视频', 9: '表情', 29 }; 30 const messages = msgData.zpData?.messages || msgData.zpData?.historyMsgList || []; 31 return messages.map((m) => { 32 const fromObj = m.from || {}; 33 const isSelf = typeof fromObj === 'object' ? fromObj.uid !== friend.uid : false; 34 return { 35 from: isSelf ? '我' : (typeof fromObj === 'object' ? fromObj.name : friend.name), 36 type: TYPE_MAP[m.type] || '其他(' + m.type + ')', 37 text: m.text || m.body?.text || '', 38 time: m.time ? new Date(m.time).toLocaleString('zh-CN') : '', 39 }; 40 }); 41 }, 42 });