/ clis / boss / send.js
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  });