@reconcrap/boss-recommend-mcp 1.1.9 → 1.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reconcrap/boss-recommend-mcp",
3
- "version": "1.1.9",
3
+ "version": "1.1.10",
4
4
  "description": "Unified MCP pipeline for recommend-page filtering and screening on Boss Zhipin",
5
5
  "keywords": [
6
6
  "boss",
@@ -1116,7 +1116,7 @@ const jsClickFavoriteFallback = `(() => {
1116
1116
  return { ok: true };
1117
1117
  })()`;
1118
1118
 
1119
- const jsGetGreetState = `(() => {
1119
+ const jsGetGreetStateRecommend = `(() => {
1120
1120
  const normalize = (value) => String(value || '').replace(/\s+/g, ' ').trim();
1121
1121
  const isVisible = (doc, el) => {
1122
1122
  if (!el) return false;
@@ -1161,7 +1161,7 @@ const jsGetGreetState = `(() => {
1161
1161
  return { ok: false, error: 'GREET_BUTTON_NOT_FOUND' };
1162
1162
  })()`;
1163
1163
 
1164
- const jsClickGreetFallback = `(() => {
1164
+ const jsClickGreetFallbackRecommend = `(() => {
1165
1165
  const topButton = Array.from(document.querySelectorAll('.resume-footer.item-operate button, .resume-footer-wrap button, button.btn-v2.btn-sure-v2'))
1166
1166
  .find((item) => item && item.offsetParent !== null && /沟通|打招呼|聊一聊/.test(String(item.textContent || '').replace(/\\s+/g, ' ')));
1167
1167
  if (topButton) {
@@ -1179,6 +1179,70 @@ const jsClickGreetFallback = `(() => {
1179
1179
  return { ok: true };
1180
1180
  })()`;
1181
1181
 
1182
+ const jsGetGreetStateFeatured = `(() => {
1183
+ const normalize = (value) => String(value || '').replace(/\s+/g, ' ').trim();
1184
+ const isVisible = (doc, el) => {
1185
+ if (!el) return false;
1186
+ const view = doc.defaultView || window;
1187
+ const style = view.getComputedStyle(el);
1188
+ if (style.display === 'none' || style.visibility === 'hidden' || Number(style.opacity || '1') < 0.02) {
1189
+ return false;
1190
+ }
1191
+ const rect = el.getBoundingClientRect();
1192
+ return rect.width > 2 && rect.height > 2;
1193
+ };
1194
+ const resolveGreet = (doc, offsetX, offsetY, scope) => {
1195
+ if (!doc) return null;
1196
+ const candidates = [
1197
+ ...Array.from(doc.querySelectorAll('button.btn-v2.position-rights.btn-sure-v2')),
1198
+ ...Array.from(doc.querySelectorAll('button.btn-v2.btn-sure-v2.position-rights')),
1199
+ ...Array.from(doc.querySelectorAll('.resume-footer.item-operate button.btn-v2, .resume-footer-wrap button.btn-v2')),
1200
+ ...Array.from(doc.querySelectorAll('.resume-footer.item-operate button, .resume-footer-wrap button'))
1201
+ ];
1202
+ const button = candidates.find((item) => isVisible(doc, item) && /立即沟通|沟通|打招呼|聊一聊/.test(normalize(item.textContent))) || null;
1203
+ if (!button) return null;
1204
+ const rect = button.getBoundingClientRect();
1205
+ return {
1206
+ ok: true,
1207
+ disabled: Boolean(button.disabled),
1208
+ x: offsetX + rect.left + rect.width / 2,
1209
+ y: offsetY + rect.top + rect.height / 2,
1210
+ scope
1211
+ };
1212
+ };
1213
+ const topResult = resolveGreet(document, 0, 0, 'top');
1214
+ if (topResult) return topResult;
1215
+
1216
+ const frame = document.querySelector('iframe[name="recommendFrame"]')
1217
+ || document.querySelector('iframe[src*="/web/frame/recommend/"]')
1218
+ || document.querySelector('iframe');
1219
+ if (!frame || !frame.contentDocument) {
1220
+ return { ok: false, error: 'NO_RECOMMEND_IFRAME' };
1221
+ }
1222
+ const frameRect = frame.getBoundingClientRect();
1223
+ const frameResult = resolveGreet(frame.contentDocument, frameRect.left, frameRect.top, 'frame');
1224
+ if (frameResult) return frameResult;
1225
+ return { ok: false, error: 'GREET_BUTTON_NOT_FOUND' };
1226
+ })()`;
1227
+
1228
+ const jsClickGreetFallbackFeatured = `(() => {
1229
+ const topButton = Array.from(document.querySelectorAll('button.btn-v2.position-rights.btn-sure-v2, button.btn-v2.btn-sure-v2.position-rights, .resume-footer.item-operate button, .resume-footer-wrap button'))
1230
+ .find((item) => item && item.offsetParent !== null && /立即沟通|沟通|打招呼|聊一聊/.test(String(item.textContent || '').replace(/\\s+/g, ' ')));
1231
+ if (topButton) {
1232
+ topButton.click();
1233
+ return { ok: true, scope: 'top' };
1234
+ }
1235
+ const frame = document.querySelector('iframe[name="recommendFrame"]')
1236
+ || document.querySelector('iframe[src*="/web/frame/recommend/"]')
1237
+ || document.querySelector('iframe');
1238
+ if (!frame || !frame.contentDocument) return { ok: false, error: 'NO_RECOMMEND_IFRAME' };
1239
+ const doc = frame.contentDocument;
1240
+ const button = doc.querySelector('button.btn-v2.position-rights.btn-sure-v2, button.btn-v2.btn-sure-v2.position-rights');
1241
+ if (!button || button.offsetParent === null) return { ok: false, error: 'GREET_BUTTON_NOT_FOUND' };
1242
+ button.click();
1243
+ return { ok: true };
1244
+ })()`;
1245
+
1182
1246
  const jsGetKnowButtonState = `(() => {
1183
1247
  const normalize = (value) => String(value || '').replace(/\s+/g, '').trim();
1184
1248
  const pickVisibleKnowButton = (doc) => {
@@ -2433,7 +2497,11 @@ class RecommendScreenCli {
2433
2497
  }
2434
2498
 
2435
2499
  async greetCandidate() {
2436
- const greet = await this.evaluate(jsGetGreetState);
2500
+ const greetStateScript = this.args.pageScope === "featured" ? jsGetGreetStateFeatured : jsGetGreetStateRecommend;
2501
+ const greetClickFallbackScript = this.args.pageScope === "featured"
2502
+ ? jsClickGreetFallbackFeatured
2503
+ : jsClickGreetFallbackRecommend;
2504
+ const greet = await this.evaluate(greetStateScript);
2437
2505
  if (!greet?.ok || greet.disabled) {
2438
2506
  throw this.buildError("GREET_BUTTON_FAILED", greet?.error || "打招呼按钮不可用");
2439
2507
  }
@@ -2441,7 +2509,7 @@ class RecommendScreenCli {
2441
2509
  try {
2442
2510
  await this.simulateHumanClick(greet.x, greet.y);
2443
2511
  } catch {
2444
- const fallback = await this.evaluate(jsClickGreetFallback);
2512
+ const fallback = await this.evaluate(greetClickFallbackScript);
2445
2513
  if (!fallback?.ok) {
2446
2514
  throw this.buildError("GREET_BUTTON_FAILED", fallback?.error || "打招呼点击失败");
2447
2515
  }