rsshub
Version:
Make RSS Great Again!
123 lines (106 loc) • 5.15 kB
JavaScript
import "./esm-shims-CzJ_djXG.mjs";
import "./config-C37vj7VH.mjs";
import { t as ViewType } from "./types-D84BRIt4.mjs";
import "./dist-BInvbO1W.mjs";
import "./logger-Czu8UMNd.mjs";
import { t as ofetch_default } from "./ofetch-BIyrKU3Y.mjs";
import { t as parseDate } from "./parse-date-BrP7mxXf.mjs";
import { a as JOB_TYPES_QUERY_KEY, d as parseParamsToString, f as parseRouteParam, i as JOB_TYPES, l as parseJobSearch, n as EXP_LEVELS, o as KEYWORDS_QUERY_KEY, r as EXP_LEVELS_QUERY_KEY, u as parseParamsToSearchParams } from "./utils-DNtliQi5.mjs";
//#region lib/routes/linkedin/jobs.ts
const BASE_URL = "https://www.linkedin.com/";
const JOB_SEARCH_PATH = "/jobs-guest/jobs/api/seeMoreJobPostings/search";
const route = {
path: "/jobs/:job_types/:exp_levels/:keywords?/:routeParams?",
categories: ["social-media"],
view: ViewType.Notifications,
example: "/linkedin/jobs/C-P/1/software engineer",
parameters: {
job_types: "See the following table for details, use '-' as delimiter",
exp_levels: "See the following table for details, use '-' as delimiter",
keywords: "keywords",
routeParams: "additional query parameters, see the table below"
},
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false
},
radar: [{
source: ["www.linkedin.com/jobs/search"],
target: (params, url) => {
const searchParams = new URLSearchParams(new URL(url).search);
const fJT = parseRouteParam(searchParams.get("f_JT"));
const fE = parseRouteParam(searchParams.get("f_E"));
const keywords = encodeURIComponent(searchParams.get("keywords") || "");
const newSearchParams = new URLSearchParams();
for (const [key, value] of searchParams.entries()) if (![
"f_JT",
"f_E",
"keywords"
].includes(key)) newSearchParams.append(key, value);
return `/linkedin/jobs/${fJT}/${fE}/${keywords}/?${newSearchParams.toString()}`;
}
}],
name: "Jobs",
maintainers: ["BrandNewLifeJackie26", "zhoukuncheng"],
handler,
description: `#### \`job_types\` list
| Full Time | Part Time | Contractor | All |
| --------- | --------- | ---------- | --- |
| F | P | C | all |
#### \`exp_levels\` list
| Intership | Entry Level | Associate | Mid-Senior Level | Director | All |
| --------- | ----------- | --------- | ---------------- | -------- | --- |
| 1 | 2 | 3 | 4 | 5 | all |
#### \`routeParams\` additional query parameters
##### \`f_WT\` list
| Onsite | Remote | Hybrid |
| ------ | ------- | ------ |
| 1 | 2 | 3 |
##### \`geoId\`
Geographic location ID. You can find this ID in the URL of a LinkedIn job search page that is filtered by location.
For example:
91000012 is the ID of East Asia.
##### \`f_TPR\`
Time posted range. Here are some possible values:
* \`r86400\`: Past 24 hours
* \`r604800\`: Past week
* \`r2592000\`: Past month
For example:
1. If we want to search software engineer jobs of all levels and all job types, use \`/linkedin/jobs/all/all/software engineer\`
2. If we want to search all entry level contractor/part time software engineer jobs, use \`/linkedin/jobs/P-C/2/software engineer\`
3. If we want to search remote mid-senior level software engineer jobs in APAC posted within the last month, use \`/linkedin/jobs/F/4/software%20engineer/f_WT=2&geoId=91000003&f_TPR=r2592000\`
**To make it easier, the recommended way is to start a search on [LinkedIn](https://www.linkedin.com/jobs/search) and use [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) to load the specific feed.**`
};
async function handler(ctx) {
const jobTypesParam = parseParamsToSearchParams(ctx.req.param("job_types"), JOB_TYPES);
const expLevelsParam = parseParamsToSearchParams(ctx.req.param("exp_levels"), EXP_LEVELS);
const routeParams = new URLSearchParams(ctx.req.param("routeParams"));
let url = new URL(JOB_SEARCH_PATH, BASE_URL);
url.searchParams.append(KEYWORDS_QUERY_KEY, ctx.req.param("keywords") || "");
url.searchParams.append(JOB_TYPES_QUERY_KEY, jobTypesParam);
url.searchParams.append(EXP_LEVELS_QUERY_KEY, expLevelsParam);
for (const [key, value] of routeParams) if (!url.searchParams.has(key)) url.searchParams.append(key, value);
url = url.toString();
const jobs = parseJobSearch(await ofetch_default(url));
const jobTypes = parseParamsToString(ctx.req.param("job_types"), JOB_TYPES);
const expLevels = parseParamsToString(ctx.req.param("exp_levels"), EXP_LEVELS);
return {
title: "LinkedIn Job Listing" + (jobTypes ? ` | Job Types: ${jobTypes}` : "") + (expLevels ? ` | Experience Levels: ${expLevels}` : "") + (ctx.req.param("keywords") ? ` | Keywords: ${ctx.req.param("keywords")}` : ""),
link: url,
description: "This feed gets LinkedIn job posts",
item: jobs.map((job) => {
return {
title: `${job.company} is hiring ${job.title}`,
description: `Title: ${job.title} | Company: ${job.company} | Location: ${job.location} `,
pubDate: parseDate(job.pubDate),
link: job.link
};
})
};
}
//#endregion
export { route };