job-pro 0.9.3 → 0.9.5
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/dist/alibaba.js +30 -0
- package/dist/antgroup.js +30 -0
- package/dist/apply.js +19 -0
- package/dist/baidu.js +30 -0
- package/dist/bilibili.js +30 -0
- package/dist/byd.js +30 -0
- package/dist/bytedance.js +30 -0
- package/dist/cainiao.js +30 -0
- package/dist/cambricon.js +1 -0
- package/dist/cicc.js +30 -0
- package/dist/deepseek.js +1 -0
- package/dist/didi.js +30 -0
- package/dist/galaxyuniversal.js +1 -0
- package/dist/geely.js +1 -0
- package/dist/hikvision.js +30 -0
- package/dist/horizonrobotics.js +1 -0
- package/dist/huawei.js +30 -0
- package/dist/iflytek.js +38 -0
- package/dist/index.js +31 -6
- package/dist/jd.js +30 -0
- package/dist/kuaishou.js +30 -0
- package/dist/liauto.js +30 -0
- package/dist/megvii.js +1 -0
- package/dist/meituan.js +30 -0
- package/dist/mihoyo.js +30 -0
- package/dist/moka.js +58 -0
- package/dist/moonshot.js +1 -0
- package/dist/netease.js +30 -0
- package/dist/oppo.js +30 -0
- package/dist/pdd.js +30 -0
- package/dist/pingan.js +30 -0
- package/dist/sensetime.js +1 -0
- package/dist/sf.js +30 -0
- package/dist/stepfun.js +1 -0
- package/dist/tencent.js +30 -0
- package/dist/trip.js +30 -0
- package/dist/unitree.js +30 -0
- package/dist/vivo.js +38 -0
- package/dist/webank.js +30 -0
- package/dist/wecruit.js +49 -0
- package/dist/weibo.js +30 -0
- package/dist/xiaohongshu.js +30 -0
- package/package.json +1 -1
package/dist/alibaba.js
CHANGED
|
@@ -476,3 +476,33 @@ export async function matchResume(text, opts = {}) {
|
|
|
476
476
|
"The only authority on selection is HR.",
|
|
477
477
|
};
|
|
478
478
|
}
|
|
479
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_alibaba } from "./apply.js";
|
|
480
|
+
export async function fetchApplicationSchema(postId) {
|
|
481
|
+
const id = (postId ?? "").trim();
|
|
482
|
+
if (!id)
|
|
483
|
+
return { ok: false, source: "campus-talent.alibaba.com", message: "post_id is required" };
|
|
484
|
+
let title = "";
|
|
485
|
+
let applyUrl = "https://campus-talent.alibaba.com";
|
|
486
|
+
try {
|
|
487
|
+
const detail = (await fetchPositionDetail(id));
|
|
488
|
+
if (detail?.ok === false) {
|
|
489
|
+
return { ok: false, source: "campus-talent.alibaba.com", message: detail.message ?? "post not found" };
|
|
490
|
+
}
|
|
491
|
+
title = detail?.title ?? "";
|
|
492
|
+
if (detail?.apply_url)
|
|
493
|
+
applyUrl = detail.apply_url;
|
|
494
|
+
}
|
|
495
|
+
catch { }
|
|
496
|
+
return {
|
|
497
|
+
ok: true,
|
|
498
|
+
schema: _buildBespokeApplySchema_alibaba({
|
|
499
|
+
source: "campus-talent.alibaba.com",
|
|
500
|
+
postId: id,
|
|
501
|
+
jobTitle: title,
|
|
502
|
+
applyUrl,
|
|
503
|
+
submitEndpoint: "https://campus-talent.alibaba.com/campus/applyPosition.json",
|
|
504
|
+
submitKind: "multipart-session",
|
|
505
|
+
submitNotes: "Alibaba — POST /campus/applyPosition.json with session cookie. Alipay OAuth gates the session. Endpoint inferred; needs validation.",
|
|
506
|
+
}),
|
|
507
|
+
};
|
|
508
|
+
}
|
package/dist/antgroup.js
CHANGED
|
@@ -360,3 +360,33 @@ export async function matchResume(text, opts = {}) {
|
|
|
360
360
|
};
|
|
361
361
|
}
|
|
362
362
|
export { extractResumeSignals, scoreOverlap };
|
|
363
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_antgroup } from "./apply.js";
|
|
364
|
+
export async function fetchApplicationSchema(postId) {
|
|
365
|
+
const id = (postId ?? "").trim();
|
|
366
|
+
if (!id)
|
|
367
|
+
return { ok: false, source: "hrcareersweb.antgroup.com", message: "post_id is required" };
|
|
368
|
+
let title = "";
|
|
369
|
+
let applyUrl = "https://hrcareersweb.antgroup.com";
|
|
370
|
+
try {
|
|
371
|
+
const detail = (await fetchPositionDetail(id));
|
|
372
|
+
if (detail?.ok === false) {
|
|
373
|
+
return { ok: false, source: "hrcareersweb.antgroup.com", message: detail.message ?? "post not found" };
|
|
374
|
+
}
|
|
375
|
+
title = detail?.title ?? "";
|
|
376
|
+
if (detail?.apply_url)
|
|
377
|
+
applyUrl = detail.apply_url;
|
|
378
|
+
}
|
|
379
|
+
catch { }
|
|
380
|
+
return {
|
|
381
|
+
ok: true,
|
|
382
|
+
schema: _buildBespokeApplySchema_antgroup({
|
|
383
|
+
source: "hrcareersweb.antgroup.com",
|
|
384
|
+
postId: id,
|
|
385
|
+
jobTitle: title,
|
|
386
|
+
applyUrl,
|
|
387
|
+
submitEndpoint: "https://hrcareersweb.antgroup.com/api/social/position/apply",
|
|
388
|
+
submitKind: "multipart-session",
|
|
389
|
+
submitNotes: "Ant Group — POST /api/social/position/apply (also campus variant). Alipay OAuth session required. Endpoint inferred from parallel read-side path; needs validation.",
|
|
390
|
+
}),
|
|
391
|
+
};
|
|
392
|
+
}
|
package/dist/apply.js
CHANGED
|
@@ -201,6 +201,25 @@ export function formatStaged(s) {
|
|
|
201
201
|
function truncate(s, n) {
|
|
202
202
|
return s.length > n ? s.slice(0, n - 1) + "…" : s;
|
|
203
203
|
}
|
|
204
|
+
export function buildBespokeApplySchema(cfg) {
|
|
205
|
+
const standard = [
|
|
206
|
+
{ label: "Name", required: true, fields: [{ name: "name", type: "input_text" }] },
|
|
207
|
+
{ label: "Email", required: true, fields: [{ name: "email", type: "input_text" }] },
|
|
208
|
+
{ label: "Phone", required: true, fields: [{ name: "phone", type: "input_text" }] },
|
|
209
|
+
{ label: "Resume", required: true, fields: [{ name: "resume", type: "input_file" }] },
|
|
210
|
+
];
|
|
211
|
+
return {
|
|
212
|
+
source: cfg.source,
|
|
213
|
+
post_id: cfg.postId,
|
|
214
|
+
job_title: cfg.jobTitle,
|
|
215
|
+
apply_url: cfg.applyUrl,
|
|
216
|
+
submit_endpoint: cfg.submitEndpoint,
|
|
217
|
+
submit_method: cfg.submitEndpoint ? "POST" : undefined,
|
|
218
|
+
submit_kind: cfg.submitKind ?? "multipart-session",
|
|
219
|
+
submit_notes: cfg.submitNotes,
|
|
220
|
+
questions: [...standard, ...(cfg.extraQuestions ?? [])],
|
|
221
|
+
};
|
|
222
|
+
}
|
|
204
223
|
export async function submitApplication(staged, target, options = {}) {
|
|
205
224
|
if (!staged.submit_endpoint) {
|
|
206
225
|
return {
|
package/dist/baidu.js
CHANGED
|
@@ -419,3 +419,33 @@ export async function matchResume(text, opts = {}) {
|
|
|
419
419
|
"The only authority on selection is HR.",
|
|
420
420
|
};
|
|
421
421
|
}
|
|
422
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_baidu } from "./apply.js";
|
|
423
|
+
export async function fetchApplicationSchema(postId) {
|
|
424
|
+
const id = (postId ?? "").trim();
|
|
425
|
+
if (!id)
|
|
426
|
+
return { ok: false, source: "talent.baidu.com", message: "post_id is required" };
|
|
427
|
+
let title = "";
|
|
428
|
+
let applyUrl = "https://talent.baidu.com";
|
|
429
|
+
try {
|
|
430
|
+
const detail = (await fetchPositionDetail(id));
|
|
431
|
+
if (detail?.ok === false) {
|
|
432
|
+
return { ok: false, source: "talent.baidu.com", message: detail.message ?? "post not found" };
|
|
433
|
+
}
|
|
434
|
+
title = detail?.title ?? "";
|
|
435
|
+
if (detail?.apply_url)
|
|
436
|
+
applyUrl = detail.apply_url;
|
|
437
|
+
}
|
|
438
|
+
catch { }
|
|
439
|
+
return {
|
|
440
|
+
ok: true,
|
|
441
|
+
schema: _buildBespokeApplySchema_baidu({
|
|
442
|
+
source: "talent.baidu.com",
|
|
443
|
+
postId: id,
|
|
444
|
+
jobTitle: title,
|
|
445
|
+
applyUrl,
|
|
446
|
+
submitEndpoint: "https://talent.baidu.com/external/baidu/applyJob.json",
|
|
447
|
+
submitKind: "multipart-session",
|
|
448
|
+
submitNotes: "Baidu — POST /external/baidu/applyJob.json with session cookie. Endpoint inferred; needs validation.",
|
|
449
|
+
}),
|
|
450
|
+
};
|
|
451
|
+
}
|
package/dist/bilibili.js
CHANGED
|
@@ -422,3 +422,33 @@ export async function findNoticesByQuestion(_question, _opts = {}) {
|
|
|
422
422
|
message: "Bilibili: no public notices endpoint",
|
|
423
423
|
};
|
|
424
424
|
}
|
|
425
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_bilibili } from "./apply.js";
|
|
426
|
+
export async function fetchApplicationSchema(postId) {
|
|
427
|
+
const id = (postId ?? "").trim();
|
|
428
|
+
if (!id)
|
|
429
|
+
return { ok: false, source: "jobs.bilibili.com", message: "post_id is required" };
|
|
430
|
+
let title = "";
|
|
431
|
+
let applyUrl = "https://jobs.bilibili.com";
|
|
432
|
+
try {
|
|
433
|
+
const detail = (await fetchPositionDetail(id));
|
|
434
|
+
if (detail?.ok === false) {
|
|
435
|
+
return { ok: false, source: "jobs.bilibili.com", message: detail.message ?? "post not found" };
|
|
436
|
+
}
|
|
437
|
+
title = detail?.title ?? "";
|
|
438
|
+
if (detail?.apply_url)
|
|
439
|
+
applyUrl = detail.apply_url;
|
|
440
|
+
}
|
|
441
|
+
catch { }
|
|
442
|
+
return {
|
|
443
|
+
ok: true,
|
|
444
|
+
schema: _buildBespokeApplySchema_bilibili({
|
|
445
|
+
source: "jobs.bilibili.com",
|
|
446
|
+
postId: id,
|
|
447
|
+
jobTitle: title,
|
|
448
|
+
applyUrl,
|
|
449
|
+
submitEndpoint: "https://jobs.bilibili.com/api/post/apply",
|
|
450
|
+
submitKind: "multipart-session",
|
|
451
|
+
submitNotes: "Bilibili — POST /api/post/apply with session cookie. Endpoint inferred; needs validation.",
|
|
452
|
+
}),
|
|
453
|
+
};
|
|
454
|
+
}
|
package/dist/byd.js
CHANGED
|
@@ -379,3 +379,33 @@ export async function matchResume(text, opts = {}) {
|
|
|
379
379
|
};
|
|
380
380
|
}
|
|
381
381
|
export { extractResumeSignals, scoreOverlap };
|
|
382
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_byd } from "./apply.js";
|
|
383
|
+
export async function fetchApplicationSchema(postId) {
|
|
384
|
+
const id = (postId ?? "").trim();
|
|
385
|
+
if (!id)
|
|
386
|
+
return { ok: false, source: "job.byd.com", message: "post_id is required" };
|
|
387
|
+
let title = "";
|
|
388
|
+
let applyUrl = "https://job.byd.com";
|
|
389
|
+
try {
|
|
390
|
+
const detail = (await fetchPositionDetail(id));
|
|
391
|
+
if (detail?.ok === false) {
|
|
392
|
+
return { ok: false, source: "job.byd.com", message: detail.message ?? "post not found" };
|
|
393
|
+
}
|
|
394
|
+
title = detail?.title ?? "";
|
|
395
|
+
if (detail?.apply_url)
|
|
396
|
+
applyUrl = detail.apply_url;
|
|
397
|
+
}
|
|
398
|
+
catch { }
|
|
399
|
+
return {
|
|
400
|
+
ok: true,
|
|
401
|
+
schema: _buildBespokeApplySchema_byd({
|
|
402
|
+
source: "job.byd.com",
|
|
403
|
+
postId: id,
|
|
404
|
+
jobTitle: title,
|
|
405
|
+
applyUrl,
|
|
406
|
+
submitEndpoint: "https://job.byd.com/portal/api/portal-api/position/apply",
|
|
407
|
+
submitKind: "multipart-session",
|
|
408
|
+
submitNotes: "BYD — POST /portal/api/portal-api/position/apply with JWT bearer + session. Endpoint inferred from job.byd.com bundle; needs validation.",
|
|
409
|
+
}),
|
|
410
|
+
};
|
|
411
|
+
}
|
package/dist/bytedance.js
CHANGED
|
@@ -586,3 +586,33 @@ export async function matchResume(text, opts = {}) {
|
|
|
586
586
|
"The only authority on selection is HR.",
|
|
587
587
|
};
|
|
588
588
|
}
|
|
589
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_bytedance } from "./apply.js";
|
|
590
|
+
export async function fetchApplicationSchema(postId) {
|
|
591
|
+
const id = (postId ?? "").trim();
|
|
592
|
+
if (!id)
|
|
593
|
+
return { ok: false, source: "jobs.bytedance.com", message: "post_id is required" };
|
|
594
|
+
let title = "";
|
|
595
|
+
let applyUrl = "https://jobs.bytedance.com";
|
|
596
|
+
try {
|
|
597
|
+
const detail = (await fetchPositionDetail(id));
|
|
598
|
+
if (detail?.ok === false) {
|
|
599
|
+
return { ok: false, source: "jobs.bytedance.com", message: detail.message ?? "post not found" };
|
|
600
|
+
}
|
|
601
|
+
title = detail?.title ?? "";
|
|
602
|
+
if (detail?.apply_url)
|
|
603
|
+
applyUrl = detail.apply_url;
|
|
604
|
+
}
|
|
605
|
+
catch { }
|
|
606
|
+
return {
|
|
607
|
+
ok: true,
|
|
608
|
+
schema: _buildBespokeApplySchema_bytedance({
|
|
609
|
+
source: "jobs.bytedance.com",
|
|
610
|
+
postId: id,
|
|
611
|
+
jobTitle: title,
|
|
612
|
+
applyUrl,
|
|
613
|
+
submitEndpoint: "https://jobs.bytedance.com/api/v1/user_apply",
|
|
614
|
+
submitKind: "multipart-session",
|
|
615
|
+
submitNotes: "ByteDance — POST /api/v1/user_apply with session cookie. CAPTCHA verification required for first-time applicants. Endpoint inferred; needs validation.",
|
|
616
|
+
}),
|
|
617
|
+
};
|
|
618
|
+
}
|
package/dist/cainiao.js
CHANGED
|
@@ -24,3 +24,33 @@ export const getNotice = adapter.getNotice;
|
|
|
24
24
|
export const findNoticesByQuestion = adapter.findNoticesByQuestion;
|
|
25
25
|
export const matchResume = adapter.matchResume;
|
|
26
26
|
export const checkResume = adapter.checkResume;
|
|
27
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_cainiao } from "./apply.js";
|
|
28
|
+
export async function fetchApplicationSchema(postId) {
|
|
29
|
+
const id = (postId ?? "").trim();
|
|
30
|
+
if (!id)
|
|
31
|
+
return { ok: false, source: "cainiao.com (via api-c.liepin.com)", message: "post_id is required" };
|
|
32
|
+
let title = "";
|
|
33
|
+
let applyUrl = "https://cainiao.com";
|
|
34
|
+
try {
|
|
35
|
+
const detail = (await fetchPositionDetail(id));
|
|
36
|
+
if (detail?.ok === false) {
|
|
37
|
+
return { ok: false, source: "cainiao.com (via api-c.liepin.com)", message: detail.message ?? "post not found" };
|
|
38
|
+
}
|
|
39
|
+
title = detail?.title ?? "";
|
|
40
|
+
if (detail?.apply_url)
|
|
41
|
+
applyUrl = detail.apply_url;
|
|
42
|
+
}
|
|
43
|
+
catch { }
|
|
44
|
+
return {
|
|
45
|
+
ok: true,
|
|
46
|
+
schema: _buildBespokeApplySchema_cainiao({
|
|
47
|
+
source: "cainiao.com (via api-c.liepin.com)",
|
|
48
|
+
postId: id,
|
|
49
|
+
jobTitle: title,
|
|
50
|
+
applyUrl,
|
|
51
|
+
submitEndpoint: undefined,
|
|
52
|
+
submitKind: "external",
|
|
53
|
+
submitNotes: "Cainiao (Liepin-backed) — submission is recruiter-IM-mediated through Liepin. Open the apply_url to start the chat.",
|
|
54
|
+
}),
|
|
55
|
+
};
|
|
56
|
+
}
|
package/dist/cambricon.js
CHANGED
|
@@ -30,3 +30,4 @@ export const getNotice = adapter.getNotice;
|
|
|
30
30
|
export const findNoticesByQuestion = adapter.findNoticesByQuestion;
|
|
31
31
|
export const matchResume = adapter.matchResume;
|
|
32
32
|
export const checkResume = adapter.checkResume;
|
|
33
|
+
export const fetchApplicationSchema = adapter.fetchApplicationSchema;
|
package/dist/cicc.js
CHANGED
|
@@ -24,3 +24,33 @@ export const getNotice = adapter.getNotice;
|
|
|
24
24
|
export const findNoticesByQuestion = adapter.findNoticesByQuestion;
|
|
25
25
|
export const matchResume = adapter.matchResume;
|
|
26
26
|
export const checkResume = adapter.checkResume;
|
|
27
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_cicc } from "./apply.js";
|
|
28
|
+
export async function fetchApplicationSchema(postId) {
|
|
29
|
+
const id = (postId ?? "").trim();
|
|
30
|
+
if (!id)
|
|
31
|
+
return { ok: false, source: "cicc.com (via api-c.liepin.com)", message: "post_id is required" };
|
|
32
|
+
let title = "";
|
|
33
|
+
let applyUrl = "https://cicc.com";
|
|
34
|
+
try {
|
|
35
|
+
const detail = (await fetchPositionDetail(id));
|
|
36
|
+
if (detail?.ok === false) {
|
|
37
|
+
return { ok: false, source: "cicc.com (via api-c.liepin.com)", message: detail.message ?? "post not found" };
|
|
38
|
+
}
|
|
39
|
+
title = detail?.title ?? "";
|
|
40
|
+
if (detail?.apply_url)
|
|
41
|
+
applyUrl = detail.apply_url;
|
|
42
|
+
}
|
|
43
|
+
catch { }
|
|
44
|
+
return {
|
|
45
|
+
ok: true,
|
|
46
|
+
schema: _buildBespokeApplySchema_cicc({
|
|
47
|
+
source: "cicc.com (via api-c.liepin.com)",
|
|
48
|
+
postId: id,
|
|
49
|
+
jobTitle: title,
|
|
50
|
+
applyUrl,
|
|
51
|
+
submitEndpoint: undefined,
|
|
52
|
+
submitKind: "external",
|
|
53
|
+
submitNotes: "CICC (Liepin-backed) — submission is recruiter-IM-mediated through Liepin. Open the apply_url to start the chat.",
|
|
54
|
+
}),
|
|
55
|
+
};
|
|
56
|
+
}
|
package/dist/deepseek.js
CHANGED
|
@@ -22,3 +22,4 @@ export const getNotice = adapter.getNotice;
|
|
|
22
22
|
export const findNoticesByQuestion = adapter.findNoticesByQuestion;
|
|
23
23
|
export const matchResume = adapter.matchResume;
|
|
24
24
|
export const checkResume = adapter.checkResume;
|
|
25
|
+
export const fetchApplicationSchema = adapter.fetchApplicationSchema;
|
package/dist/didi.js
CHANGED
|
@@ -348,3 +348,33 @@ export async function matchResume(text, opts = {}) {
|
|
|
348
348
|
"The only authority on selection is HR.",
|
|
349
349
|
};
|
|
350
350
|
}
|
|
351
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_didi } from "./apply.js";
|
|
352
|
+
export async function fetchApplicationSchema(postId) {
|
|
353
|
+
const id = (postId ?? "").trim();
|
|
354
|
+
if (!id)
|
|
355
|
+
return { ok: false, source: "talent.didiglobal.com", message: "post_id is required" };
|
|
356
|
+
let title = "";
|
|
357
|
+
let applyUrl = "https://talent.didiglobal.com";
|
|
358
|
+
try {
|
|
359
|
+
const detail = (await fetchPositionDetail(id));
|
|
360
|
+
if (detail?.ok === false) {
|
|
361
|
+
return { ok: false, source: "talent.didiglobal.com", message: detail.message ?? "post not found" };
|
|
362
|
+
}
|
|
363
|
+
title = detail?.title ?? "";
|
|
364
|
+
if (detail?.apply_url)
|
|
365
|
+
applyUrl = detail.apply_url;
|
|
366
|
+
}
|
|
367
|
+
catch { }
|
|
368
|
+
return {
|
|
369
|
+
ok: true,
|
|
370
|
+
schema: _buildBespokeApplySchema_didi({
|
|
371
|
+
source: "talent.didiglobal.com",
|
|
372
|
+
postId: id,
|
|
373
|
+
jobTitle: title,
|
|
374
|
+
applyUrl,
|
|
375
|
+
submitEndpoint: "https://talent.didiglobal.com/talent-api/applyResume",
|
|
376
|
+
submitKind: "multipart-session",
|
|
377
|
+
submitNotes: "Didi — POST /talent-api/applyResume with session cookie. Endpoint inferred; needs validation.",
|
|
378
|
+
}),
|
|
379
|
+
};
|
|
380
|
+
}
|
package/dist/galaxyuniversal.js
CHANGED
|
@@ -21,3 +21,4 @@ export const getNotice = adapter.getNotice;
|
|
|
21
21
|
export const findNoticesByQuestion = adapter.findNoticesByQuestion;
|
|
22
22
|
export const matchResume = adapter.matchResume;
|
|
23
23
|
export const checkResume = adapter.checkResume;
|
|
24
|
+
export const fetchApplicationSchema = adapter.fetchApplicationSchema;
|
package/dist/geely.js
CHANGED
|
@@ -32,3 +32,4 @@ export const getNotice = adapter.getNotice;
|
|
|
32
32
|
export const findNoticesByQuestion = adapter.findNoticesByQuestion;
|
|
33
33
|
export const matchResume = adapter.matchResume;
|
|
34
34
|
export const checkResume = adapter.checkResume;
|
|
35
|
+
export const fetchApplicationSchema = adapter.fetchApplicationSchema;
|
package/dist/hikvision.js
CHANGED
|
@@ -26,3 +26,33 @@ export const getNotice = adapter.getNotice;
|
|
|
26
26
|
export const findNoticesByQuestion = adapter.findNoticesByQuestion;
|
|
27
27
|
export const matchResume = adapter.matchResume;
|
|
28
28
|
export const checkResume = adapter.checkResume;
|
|
29
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_hikvision } from "./apply.js";
|
|
30
|
+
export async function fetchApplicationSchema(postId) {
|
|
31
|
+
const id = (postId ?? "").trim();
|
|
32
|
+
if (!id)
|
|
33
|
+
return { ok: false, source: "hikvision.com (via api-c.liepin.com)", message: "post_id is required" };
|
|
34
|
+
let title = "";
|
|
35
|
+
let applyUrl = "https://hikvision.com";
|
|
36
|
+
try {
|
|
37
|
+
const detail = (await fetchPositionDetail(id));
|
|
38
|
+
if (detail?.ok === false) {
|
|
39
|
+
return { ok: false, source: "hikvision.com (via api-c.liepin.com)", message: detail.message ?? "post not found" };
|
|
40
|
+
}
|
|
41
|
+
title = detail?.title ?? "";
|
|
42
|
+
if (detail?.apply_url)
|
|
43
|
+
applyUrl = detail.apply_url;
|
|
44
|
+
}
|
|
45
|
+
catch { }
|
|
46
|
+
return {
|
|
47
|
+
ok: true,
|
|
48
|
+
schema: _buildBespokeApplySchema_hikvision({
|
|
49
|
+
source: "hikvision.com (via api-c.liepin.com)",
|
|
50
|
+
postId: id,
|
|
51
|
+
jobTitle: title,
|
|
52
|
+
applyUrl,
|
|
53
|
+
submitEndpoint: undefined,
|
|
54
|
+
submitKind: "external",
|
|
55
|
+
submitNotes: "Hikvision (Liepin-backed) — submission is recruiter-IM-mediated through Liepin. Open the apply_url to start the chat.",
|
|
56
|
+
}),
|
|
57
|
+
};
|
|
58
|
+
}
|
package/dist/horizonrobotics.js
CHANGED
|
@@ -43,3 +43,4 @@ export const getNotice = adapter.getNotice;
|
|
|
43
43
|
export const findNoticesByQuestion = adapter.findNoticesByQuestion;
|
|
44
44
|
export const matchResume = adapter.matchResume;
|
|
45
45
|
export const checkResume = adapter.checkResume;
|
|
46
|
+
export const fetchApplicationSchema = adapter.fetchApplicationSchema;
|
package/dist/huawei.js
CHANGED
|
@@ -504,3 +504,33 @@ export async function matchResume(text, opts = {}) {
|
|
|
504
504
|
"The only authority on selection is HR.",
|
|
505
505
|
};
|
|
506
506
|
}
|
|
507
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_huawei } from "./apply.js";
|
|
508
|
+
export async function fetchApplicationSchema(postId) {
|
|
509
|
+
const id = (postId ?? "").trim();
|
|
510
|
+
if (!id)
|
|
511
|
+
return { ok: false, source: "career.huawei.com", message: "post_id is required" };
|
|
512
|
+
let title = "";
|
|
513
|
+
let applyUrl = "https://career.huawei.com";
|
|
514
|
+
try {
|
|
515
|
+
const detail = (await fetchPositionDetail(id));
|
|
516
|
+
if (detail?.ok === false) {
|
|
517
|
+
return { ok: false, source: "career.huawei.com", message: detail.message ?? "post not found" };
|
|
518
|
+
}
|
|
519
|
+
title = detail?.title ?? "";
|
|
520
|
+
if (detail?.apply_url)
|
|
521
|
+
applyUrl = detail.apply_url;
|
|
522
|
+
}
|
|
523
|
+
catch { }
|
|
524
|
+
return {
|
|
525
|
+
ok: true,
|
|
526
|
+
schema: _buildBespokeApplySchema_huawei({
|
|
527
|
+
source: "career.huawei.com",
|
|
528
|
+
postId: id,
|
|
529
|
+
jobTitle: title,
|
|
530
|
+
applyUrl,
|
|
531
|
+
submitEndpoint: "https://career.huawei.com/career/api/web/postApply",
|
|
532
|
+
submitKind: "multipart-session",
|
|
533
|
+
submitNotes: "Huawei — POST /career/api/web/postApply with session cookie. Endpoint inferred; needs validation.",
|
|
534
|
+
}),
|
|
535
|
+
};
|
|
536
|
+
}
|
package/dist/iflytek.js
CHANGED
|
@@ -337,3 +337,41 @@ export { extractResumeSignals, scoreOverlap };
|
|
|
337
337
|
// Silence unused warning for the GET helper — kept for future taxonomy/city
|
|
338
338
|
// endpoints that return BeisenEnvelope JSON via GET.
|
|
339
339
|
void get;
|
|
340
|
+
export async function fetchApplicationSchema(postId) {
|
|
341
|
+
const id = (postId ?? '').trim();
|
|
342
|
+
if (!id)
|
|
343
|
+
return { ok: false, source: SOURCE, message: 'post_id is required' };
|
|
344
|
+
let title = '';
|
|
345
|
+
try {
|
|
346
|
+
const detail = await fetchPositionDetail(id);
|
|
347
|
+
if (detail?.ok === false) {
|
|
348
|
+
return { ok: false, source: SOURCE, message: detail.message ?? 'post not found' };
|
|
349
|
+
}
|
|
350
|
+
title = detail?.title ?? '';
|
|
351
|
+
}
|
|
352
|
+
catch { }
|
|
353
|
+
const questions = [
|
|
354
|
+
{ label: 'Name', required: true, fields: [{ name: 'name', type: 'input_text' }] },
|
|
355
|
+
{ label: 'Email', required: true, fields: [{ name: 'email', type: 'input_text' }] },
|
|
356
|
+
{ label: 'Phone', required: true, fields: [{ name: 'phone', type: 'input_text' }] },
|
|
357
|
+
{ label: 'Resume', required: true, fields: [{ name: 'resume', type: 'input_file' }] },
|
|
358
|
+
];
|
|
359
|
+
return {
|
|
360
|
+
ok: true,
|
|
361
|
+
schema: {
|
|
362
|
+
source: SOURCE,
|
|
363
|
+
post_id: id,
|
|
364
|
+
job_title: title,
|
|
365
|
+
apply_url: 'https://iflytek.zhiye.com/jobs',
|
|
366
|
+
submit_endpoint: 'https://iflytek.zhiye.com/api/Apply/SubmitResume',
|
|
367
|
+
submit_method: 'POST',
|
|
368
|
+
submit_kind: 'beisen-italent',
|
|
369
|
+
submit_notes: 'Beisen iTalent apply: POST /api/Resume/UploadResume (multipart) + ' +
|
|
370
|
+
'POST /api/Apply/SubmitResume with { JobAdId, ResumeId, … }. ' +
|
|
371
|
+
'Requires candidate session — Beisen iTalent uses email+phone+OTP login at ' +
|
|
372
|
+
'/login.html. Capture via extension/, drop session.json under ~/.jobpro/. ' +
|
|
373
|
+
'Multi-step submitter lands in a future iteration.',
|
|
374
|
+
questions,
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -54,7 +54,7 @@ import { loadProfile, loadSession, profileTemplate, stageApplication, submitAppl
|
|
|
54
54
|
import { memoryList, memoryGet, memorySet, memoryEvent, memoryClear, } from "./memory.js";
|
|
55
55
|
import { writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
56
56
|
import { dirname } from "node:path";
|
|
57
|
-
const VERSION = "0.9.
|
|
57
|
+
const VERSION = "0.9.5";
|
|
58
58
|
const COMPANIES = [
|
|
59
59
|
{ key: "tencent", family: "Bespoke", source: "join.qq.com", label: "Tencent / 腾讯" },
|
|
60
60
|
{ key: "bytedance", family: "Bespoke", source: "jobs.bytedance.com", label: "ByteDance / 字节跳动" },
|
|
@@ -123,11 +123,22 @@ USAGE
|
|
|
123
123
|
by ATS family (Bespoke / Feishu / Beisen Wecruit / Beisen iTalent / Moka
|
|
124
124
|
/ Greenhouse-Lever / Liepin). Coverage summary at job.ha7ch.com.
|
|
125
125
|
|
|
126
|
-
PHASE 2 (auto-apply)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
126
|
+
PHASE 2 (auto-apply) — schema coverage is now 50/50:
|
|
127
|
+
✅ 3 Greenhouse / Lever (xpeng / hoyoverse / weride — auto-submit
|
|
128
|
+
ready, no session needed)
|
|
129
|
+
🟡 22 bespoke session (tencent, bytedance, alibaba, …)
|
|
130
|
+
🟡 9 Feishu (xiaomi, nio, minimax, moonshot, zhipu,
|
|
131
|
+
iqiyi, agibot, lilith, zerooneai, baichuan)
|
|
132
|
+
🟡 7 Moka (megvii, deepseek, galaxyuniversal,
|
|
133
|
+
stepfun, cambricon, geely, moonshot)
|
|
134
|
+
🟡 2 Beisen Wecruit (sensetime, horizonrobotics)
|
|
135
|
+
🟡 2 Beisen iTalent (vivo, iflytek)
|
|
136
|
+
⛔ 5 external (unitree WeChat, hikvision/cicc/cainiao/
|
|
137
|
+
webank — Liepin IM-mediated)
|
|
138
|
+
\`apply <postId>\` dry-runs the staged POST for any of them. The 🟡
|
|
139
|
+
families need a session.json (extension/) + a family-specific
|
|
140
|
+
multi-step submitter; --really-submit currently fires only for ✅.
|
|
141
|
+
See docs/auto-apply.md.
|
|
131
142
|
|
|
132
143
|
VERBS (same surface for every company)
|
|
133
144
|
search <kw> search openings (free text)
|
|
@@ -467,6 +478,20 @@ async function runCompany(adapter, company, rawArgs) {
|
|
|
467
478
|
const isAnonMultipart = kind === "multipart-anon";
|
|
468
479
|
const isSessionMultipart = kind === "multipart-session";
|
|
469
480
|
const isGenericMultipart = isAnonMultipart || isSessionMultipart;
|
|
481
|
+
if (kind === "external") {
|
|
482
|
+
return emit({
|
|
483
|
+
ok: false,
|
|
484
|
+
source: company,
|
|
485
|
+
post_id: postId,
|
|
486
|
+
mode: "really-submit-external",
|
|
487
|
+
staged,
|
|
488
|
+
submit_kind: kind,
|
|
489
|
+
apply_url: staged.apply_url,
|
|
490
|
+
message: `${company} has no programmatic submit API — recruiting is mediated ` +
|
|
491
|
+
`via WeChat mini-program / Liepin recruiter chat / other IM channel. ` +
|
|
492
|
+
`Open apply_url in your browser to start the actual application flow.`,
|
|
493
|
+
}, compact);
|
|
494
|
+
}
|
|
470
495
|
if (!isGenericMultipart) {
|
|
471
496
|
return emit({
|
|
472
497
|
ok: false,
|
package/dist/jd.js
CHANGED
|
@@ -526,3 +526,33 @@ export async function matchResume(text, opts = {}) {
|
|
|
526
526
|
"The only authority on selection is HR.",
|
|
527
527
|
};
|
|
528
528
|
}
|
|
529
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_jd } from "./apply.js";
|
|
530
|
+
export async function fetchApplicationSchema(postId) {
|
|
531
|
+
const id = (postId ?? "").trim();
|
|
532
|
+
if (!id)
|
|
533
|
+
return { ok: false, source: "campus.jd.com", message: "post_id is required" };
|
|
534
|
+
let title = "";
|
|
535
|
+
let applyUrl = "https://campus.jd.com";
|
|
536
|
+
try {
|
|
537
|
+
const detail = (await fetchPositionDetail(id));
|
|
538
|
+
if (detail?.ok === false) {
|
|
539
|
+
return { ok: false, source: "campus.jd.com", message: detail.message ?? "post not found" };
|
|
540
|
+
}
|
|
541
|
+
title = detail?.title ?? "";
|
|
542
|
+
if (detail?.apply_url)
|
|
543
|
+
applyUrl = detail.apply_url;
|
|
544
|
+
}
|
|
545
|
+
catch { }
|
|
546
|
+
return {
|
|
547
|
+
ok: true,
|
|
548
|
+
schema: _buildBespokeApplySchema_jd({
|
|
549
|
+
source: "campus.jd.com",
|
|
550
|
+
postId: id,
|
|
551
|
+
jobTitle: title,
|
|
552
|
+
applyUrl,
|
|
553
|
+
submitEndpoint: "https://campus.jd.com/web/job/apply",
|
|
554
|
+
submitKind: "multipart-session",
|
|
555
|
+
submitNotes: "JD — POST /web/job/apply with session cookie. Endpoint inferred from campus.jd.com SPA; needs validation.",
|
|
556
|
+
}),
|
|
557
|
+
};
|
|
558
|
+
}
|
package/dist/kuaishou.js
CHANGED
|
@@ -463,3 +463,33 @@ export async function matchResume(text, opts = {}) {
|
|
|
463
463
|
"The only authority on selection is HR.",
|
|
464
464
|
};
|
|
465
465
|
}
|
|
466
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_kuaishou } from "./apply.js";
|
|
467
|
+
export async function fetchApplicationSchema(postId) {
|
|
468
|
+
const id = (postId ?? "").trim();
|
|
469
|
+
if (!id)
|
|
470
|
+
return { ok: false, source: "campus.kuaishou.cn", message: "post_id is required" };
|
|
471
|
+
let title = "";
|
|
472
|
+
let applyUrl = "https://campus.kuaishou.cn";
|
|
473
|
+
try {
|
|
474
|
+
const detail = (await fetchPositionDetail(id));
|
|
475
|
+
if (detail?.ok === false) {
|
|
476
|
+
return { ok: false, source: "campus.kuaishou.cn", message: detail.message ?? "post not found" };
|
|
477
|
+
}
|
|
478
|
+
title = detail?.title ?? "";
|
|
479
|
+
if (detail?.apply_url)
|
|
480
|
+
applyUrl = detail.apply_url;
|
|
481
|
+
}
|
|
482
|
+
catch { }
|
|
483
|
+
return {
|
|
484
|
+
ok: true,
|
|
485
|
+
schema: _buildBespokeApplySchema_kuaishou({
|
|
486
|
+
source: "campus.kuaishou.cn",
|
|
487
|
+
postId: id,
|
|
488
|
+
jobTitle: title,
|
|
489
|
+
applyUrl,
|
|
490
|
+
submitEndpoint: "https://campus.kuaishou.cn/rest/campus-recruit/post/deliver",
|
|
491
|
+
submitKind: "multipart-session",
|
|
492
|
+
submitNotes: "Kuaishou — POST /rest/campus-recruit/post/deliver with session cookie. Endpoint inferred; needs validation.",
|
|
493
|
+
}),
|
|
494
|
+
};
|
|
495
|
+
}
|
package/dist/liauto.js
CHANGED
|
@@ -360,3 +360,33 @@ export async function matchResume(text, opts = {}) {
|
|
|
360
360
|
"The only authority on selection is HR.",
|
|
361
361
|
};
|
|
362
362
|
}
|
|
363
|
+
import { buildBespokeApplySchema as _buildBespokeApplySchema_liauto } from "./apply.js";
|
|
364
|
+
export async function fetchApplicationSchema(postId) {
|
|
365
|
+
const id = (postId ?? "").trim();
|
|
366
|
+
if (!id)
|
|
367
|
+
return { ok: false, source: "www.lixiang.com", message: "post_id is required" };
|
|
368
|
+
let title = "";
|
|
369
|
+
let applyUrl = "https://www.lixiang.com";
|
|
370
|
+
try {
|
|
371
|
+
const detail = (await fetchPositionDetail(id));
|
|
372
|
+
if (detail?.ok === false) {
|
|
373
|
+
return { ok: false, source: "www.lixiang.com", message: detail.message ?? "post not found" };
|
|
374
|
+
}
|
|
375
|
+
title = detail?.title ?? "";
|
|
376
|
+
if (detail?.apply_url)
|
|
377
|
+
applyUrl = detail.apply_url;
|
|
378
|
+
}
|
|
379
|
+
catch { }
|
|
380
|
+
return {
|
|
381
|
+
ok: true,
|
|
382
|
+
schema: _buildBespokeApplySchema_liauto({
|
|
383
|
+
source: "www.lixiang.com",
|
|
384
|
+
postId: id,
|
|
385
|
+
jobTitle: title,
|
|
386
|
+
applyUrl,
|
|
387
|
+
submitEndpoint: "https://www.lixiang.com/api/career/apply",
|
|
388
|
+
submitKind: "multipart-session",
|
|
389
|
+
submitNotes: "Li Auto — POST /api/career/apply with session cookie. Endpoint inferred; needs validation.",
|
|
390
|
+
}),
|
|
391
|
+
};
|
|
392
|
+
}
|
package/dist/megvii.js
CHANGED
|
@@ -24,3 +24,4 @@ export const getNotice = adapter.getNotice;
|
|
|
24
24
|
export const findNoticesByQuestion = adapter.findNoticesByQuestion;
|
|
25
25
|
export const matchResume = adapter.matchResume;
|
|
26
26
|
export const checkResume = adapter.checkResume;
|
|
27
|
+
export const fetchApplicationSchema = adapter.fetchApplicationSchema;
|