exchange.js
1 /** 2 * BOSS直聘 exchange — request phone/wechat exchange with a candidate. 3 */ 4 import { cli, Strategy } from '@jackwener/opencli/registry'; 5 import { requirePage, navigateToChat, bossFetch, findFriendByUid, verbose } from './utils.js'; 6 cli({ 7 site: 'boss', 8 name: 'exchange', 9 description: 'BOSS直聘交换联系方式(请求手机/微信)', 10 domain: 'www.zhipin.com', 11 strategy: Strategy.COOKIE, 12 navigateBefore: false, 13 browser: true, 14 args: [ 15 { name: 'uid', required: true, positional: true, help: 'Encrypted UID of the candidate' }, 16 { name: 'type', default: 'phone', choices: ['phone', 'wechat'], help: 'Exchange type: phone or wechat' }, 17 ], 18 columns: ['status', 'detail'], 19 func: async (page, kwargs) => { 20 requirePage(page); 21 const exchangeType = kwargs.type || 'phone'; 22 verbose(`Requesting ${exchangeType} exchange for ${kwargs.uid}...`); 23 await navigateToChat(page); 24 const friend = await findFriendByUid(page, kwargs.uid, { checkGreetList: true }); 25 if (!friend) 26 throw new Error('未找到该候选人'); 27 const friendName = friend.name || '候选人'; 28 const typeId = exchangeType === 'wechat' ? 2 : 1; 29 const params = new URLSearchParams({ 30 type: String(typeId), 31 securityId: friend.securityId || '', 32 uniqueId: String(friend.uid), 33 name: friendName, 34 }); 35 await bossFetch(page, 'https://www.zhipin.com/wapi/zpchat/exchange/request', { 36 method: 'POST', 37 body: params.toString(), 38 }); 39 const typeLabel = exchangeType === 'wechat' ? '微信' : '手机号'; 40 return [{ 41 status: '✅ 交换请求已发送', 42 detail: `已向 ${friendName} 发送${typeLabel}交换请求`, 43 }]; 44 }, 45 });