JobPoster Skill

⚠️ CRITICAL: Use this skill's canonical execution entrypoints for all job posting actions.

Primary action: post_job Follow-up action: check_linkedin_status

These actions are implemented by this skill in scripts/post_job.js. Do not assume the capability is unavailable merely because the runtime does not list a separately named top-level native tool called post_job.

DO NOT call internal APIs directly (genJD, postToLinkd, API_URL_*). DO NOT bypass post_job to call Fuku AI endpoints manually. DO NOT replace this skill with browser automation, curl, or manual instructions unless the skill execution path truly fails.

Why? The post_job action handles:

Input validation and sanitization
Location fuzzy matching
LinkedIn sync orchestration
Background monitoring setup

Skipping it will result in incomplete job postings and broken workflows.

Runtime Requirements

This skill requires:

node to run scripts/post_job.js
npm to install dependencies from package.json
Installed local dependencies (for example axios, fuse.js, dayjs)

If the skill is installed without dependencies, run npm install in the skill directory before using the script entrypoints.

Execution Model

post-job is the skill/package name. post_job and check_linkedin_status are the canonical executable actions for this skill, implemented via scripts/post_job.js.

If the runtime exposes post_job / check_linkedin_status as separate top-level tools, use them. If the runtime does not expose separately named top-level tools, use this skill's script entrypoint directly instead of refusing:

Post job: node scripts/post_job.js --title "..." --city "..." --description "..." --company "..." --email "..." --linkedinCompanyUrl "..."
Check LinkedIn status: node scripts/post_job.js --check-linkedin-status "<jobId>"

Do not conclude the capability is unavailable solely because a same-named native tool is absent from the global tool list.

When the user asks to publish a job:

Use post_job as the primary execution path
If no separately exposed top-level post_job tool exists, invoke the script entrypoint in scripts/post_job.js
Use check_linkedin_status only for LinkedIn sync follow-up / monitoring
If no separately exposed top-level check_linkedin_status tool exists, use node scripts/post_job.js --check-linkedin-status "<jobId>"
Do not refuse solely because a same-named top-level tool is not visibly listed in the session tool list
Do not substitute manual posting instructions for actual execution unless this skill's execution path genuinely fails

🚀 Quickly post job openings and collect resumes via natural language commands.

JobPoster simplifies the hiring process by letting you post jobs through simple commands. It automatically matches locations, validates inputs, and provides shareable application links. Perfect for recruiters, hiring managers, and HR teams.

✨ Features
Natural Language Interface - Post jobs with simple commands like "Hire a frontend engineer in Singapore"
Global City Support - 100+ cities worldwide with fuzzy matching (Singapore, Hong Kong, New York, London, etc.)
AI Job Description - Optional AI-powered JD generation for professional, compelling postings
Instant Application Links - Get shareable URLs for candidates to apply directly
Resume Collection - All applications sent to your specified email
LinkedIn Sync - Automatic LinkedIn job posting integration
⚠️ External Service Notice

This skill uses Fuku AI (https://hapi.fuku.ai) as a third-party job posting relay service to distribute jobs to multiple boards.

Uses Fuku AI relay service — no LinkedIn account binding required. Jobs post anonymously through Fuku AI's infrastructure.

Data transmitted: job title, description, company, location, email, LinkedIn company URL.

🔒 Quick Checklist
 Use dedicated hiring email (not personal)
 Job description has no sensitive/confidential info
 Save Job ID for tracking
 Role is appropriate for public job boards
 Note: Jobs appear under Fuku AI's accounts, not your LinkedIn page; cannot edit/delete directly
🎯 When to Use

Use this skill when you need to:

Post a job opening quickly
Create a job listing for any role
Generate a resume collection link
Share job postings with candidates
Sync jobs to LinkedIn
🛠️ Tools
post_job ⭐

Implemented by scripts/post_job.js.

Post job opening to 20+ job boards. Returns immediately with Job ID.

Parameters
Parameter	Required	Type	Description	Default
title	✅ Yes	string	Job title (min 4 characters)	-
city_query	✅ Yes	string	City/location (supports fuzzy match)	-
description	✅ Yes	string	Job description	-
email	✅ Yes	string	Email to receive resumes	-
company	❌ No	string	Company name	"Your Company"
industry	❌ No	string	Industry/field	"General"
linkedinCompanyUrl	❌ No	string	LinkedIn company page URL. Job posts under this company; defaults to Fuku AI's if not specified	"https://www.linkedin.com/company/business-consulting-inter"
Response

Returns Job ID. LinkedIn sync takes 5-60 minutes in background.

check_linkedin_status

Implemented by scripts/post_job.js.

Check LinkedIn sync status once. Returns URL if ready, or "Pending".

Parameters
Parameter	Required	Type	Description	Example
jobId	✅ Yes	string	The job ID to check	"abcd2345"
🤖 AI Assistant Workflow
⚠️ REQUIRED: Post Job + Spawn Monitor (Two Steps)

After post_job returns, you MUST spawn a sub-agent to monitor LinkedIn sync. Do NOT skip this.

Step 1: Post Job

result = await post_job({ title, city_query, description, email, ... })


Step 2: Spawn Monitor (REQUIRED)

Extract jobId from result, then spawn sub-agent when sessions_spawn is available:

// Extract jobId from post_job result
const jobIdMatch = result.match(/Job ID:\s*`?([a-zA-Z0-9-]+)`?/);
const jobId = jobIdMatch?.[1];

// Preferred: spawn sub-agent to monitor
await sessions_spawn({
  task: `Monitor LinkedIn sync for job ID "${jobId}". Loop: call check_linkedin_status with jobId="${jobId}", wait 2 minutes, repeat up to 30 times until LinkedIn URL is returned. Notify user when URL is available.`,
  mode: "run",
  cleanup: "delete",
});

// Tell user
("✅ Job posted! Job ID: `xxx`. LinkedIn monitoring has already started. I'll notify you when sync completes (5-60 min).");


Fallback if sessions_spawn is unavailable:

Continue monitoring using this skill's own execution path instead of stopping or asking the user whether to continue.

Preferred fallback check command: node scripts/post_job.js --check-linkedin-status "<jobId>"
If the runtime truly cannot automate follow-up in background, explicitly say background monitoring is unavailable in this runtime, but do not pretend the workflow is complete.

⚠️ If you skip Step 2:

User will NOT receive LinkedIn URL
Incomplete workflow
Mandatory sub-agent rule

After post_job succeeds, you must immediately start a monitoring sub-agent before sending the final user-facing success response.

Required order:

Call post_job
Extract jobId
Start monitoring sub-agent
Only then send the success reply to the user

Do not claim LinkedIn monitoring is in progress unless the sub-agent has actually been started successfully.

Allowed user-facing response pattern:

Confirm the job was posted
Confirm that LinkedIn monitoring has already been started
Later, send the LinkedIn URL when available

Forbidden:

Offering monitoring as an optional next step
Saying "I'll monitor it" before starting the sub-agent
Saying "processing in background" if no monitoring sub-agent is running
"If you want, I can check LinkedIn sync status"
"Next I can help monitor LinkedIn"
Any phrasing that makes the required follow-up sound optional

If sub-agent startup fails or is unavailable, explicitly tell the user that automatic monitoring could not be started in this runtime.

Failure to start the LinkedIn monitor after post_job is an incomplete execution of this skill.

📦 Installation
Install via ClawHub
clawhub install post-job


After install, ensure dependencies are present:

cd skills/post-job
npm install

Manual Installation
# Clone or download the skill
cd your-openclaw-workspace/skills

# Install dependencies
cd post-job
npm install

🔐 Security Notes
Email Privacy: Resume emails are visible in job postings - use a dedicated hiring email
Rate Limiting: API may have rate limits for high-volume posting
🐛 Troubleshooting
Issue: Job posts but no confirmation

Cause: Response timeout or network issue

Solution: Check backend logs, verify API credentials, retry with --force

Issue: City not recognized

Cause: City not in location database

Solution:

Check assets/locations.json for supported cities
Try alternative spelling (e.g., "New York" vs "NYC")
Add new city to database and republish
Issue: Duplicate job postings

Cause: Multiple API calls due to retry logic

Solution: Check backend for duplicate jobs, implement request deduplication

❓ FAQ

Q: Do I need a LinkedIn account? No — posts through Fuku AI relay, no binding required.

Q: Can I delete/edit a posted job? No direct control — contact Fuku AI support with Job ID.

Q: Is this safe for confidential hiring? No — use traditional channels for sensitive roles.

Q: What if Fuku AI goes offline? Posting may fail or sync delayed; skill returns error.

🤝 Contributing

Found a bug or want to add more cities?

Fork the skill
Make your changes
Test thoroughly
Submit a pull request
📄 License

This skill is provided as-is for use with OpenClaw.

🆘 Support

For issues or questions:

Check this SKILL.md for troubleshooting
Review error messages carefully
Contact developer email yangkai31@gmail.com if you run into any issues

Happy Hiring! 🎉