Phase 3-4: apply wizard with AI answers, Playwright auto-apply worker, report page, Docker deploy files; add PH government job leads
This commit is contained in:
45
worker/adapters/greenhouse.ts
Normal file
45
worker/adapters/greenhouse.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import fs from "node:fs";
|
||||
import type { Adapter } from "./index";
|
||||
import { launchPage, fillIfPresent } from "./index";
|
||||
|
||||
/** Generic Greenhouse job-board application form (boards.greenhouse.io). */
|
||||
export const genericGreenhouseAdapter: Adapter = {
|
||||
name: "greenhouse",
|
||||
matches: (url) => url.includes("greenhouse.io"),
|
||||
async run({ job, profile, submit }) {
|
||||
const lines: string[] = [];
|
||||
fs.mkdirSync("worker/out", { recursive: true });
|
||||
const { browser, page } = await launchPage();
|
||||
try {
|
||||
await page.goto(job.applyUrl ?? job.url ?? "", { waitUntil: "domcontentloaded" });
|
||||
lines.push(`opened ${page.url()}`);
|
||||
|
||||
const [first, ...rest] = (profile.fullName ?? "").split(" ");
|
||||
await fillIfPresent(page, ["#first_name"], first, lines);
|
||||
await fillIfPresent(page, ["#last_name"], rest.join(" "), lines);
|
||||
await fillIfPresent(page, ["#email"], profile.email, lines);
|
||||
await fillIfPresent(page, ["#phone"], profile.phone, lines);
|
||||
await fillIfPresent(page, ['input[name*="linkedin" i]', 'input[autocomplete="url"]'], profile.linkedin, lines);
|
||||
await page.screenshot({ path: "worker/out/gh-filled.png", fullPage: true });
|
||||
lines.push("NOTE: resume file upload must be done manually in the headed browser (60s pause)");
|
||||
await page.waitForTimeout(60_000);
|
||||
|
||||
if (!submit) {
|
||||
lines.push("dry run: stopping before submit");
|
||||
return { submitted: false, lines };
|
||||
}
|
||||
const btn = page.locator('button[type="submit"], input[type="submit"]').first();
|
||||
if (!(await btn.count())) {
|
||||
lines.push("no submit button found — aborting");
|
||||
return { submitted: false, lines };
|
||||
}
|
||||
await btn.click();
|
||||
await page.waitForLoadState("networkidle");
|
||||
await page.screenshot({ path: "worker/out/gh-submitted.png", fullPage: true });
|
||||
lines.push(`submitted; landed on ${page.url()}`);
|
||||
return { submitted: true, lines };
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user