send.js
1 /** 2 * BOSS直聘 send message — via UI automation on chat page. 3 * 4 * BOSS chat uses MQTT (not HTTP) for messaging, so we must go through the UI 5 * rather than making direct API calls. 6 */ 7 import { cli, Strategy } from '@jackwener/opencli/registry'; 8 import { requirePage, navigateToChat, findFriendByUid, clickCandidateInList, typeAndSendMessage, } from './utils.js'; 9 import { EmptyResultError, SelectorError } from '@jackwener/opencli/errors'; 10 cli({ 11 site: 'boss', 12 name: 'send', 13 description: 'BOSS直聘发送聊天消息', 14 domain: 'www.zhipin.com', 15 strategy: Strategy.COOKIE, 16 navigateBefore: false, 17 browser: true, 18 args: [ 19 { name: 'uid', positional: true, required: true, help: 'Encrypted UID of the candidate (from chatlist)' }, 20 { name: 'text', required: true, positional: true, help: 'Message text to send' }, 21 ], 22 columns: ['status', 'detail'], 23 func: async (page, kwargs) => { 24 requirePage(page); 25 await navigateToChat(page, 3); 26 const friend = await findFriendByUid(page, kwargs.uid, { maxPages: 5 }); 27 if (!friend) 28 throw new EmptyResultError('boss candidate search', '请确认 uid 是否正确'); 29 const numericUid = friend.uid; 30 const friendName = friend.name || '候选人'; 31 const clicked = await clickCandidateInList(page, numericUid); 32 if (!clicked) { 33 throw new SelectorError('聊天列表中的用户', '请确认聊天列表中有此人'); 34 } 35 await page.wait({ time: 2 }); 36 const sent = await typeAndSendMessage(page, kwargs.text); 37 if (!sent) { 38 throw new SelectorError('消息输入框', '聊天页面 UI 可能已改变'); 39 } 40 await page.wait({ time: 1 }); 41 return [{ status: '✅ 发送成功', detail: `已向 ${friendName} 发送: ${kwargs.text}` }]; 42 }, 43 });