mirror of
https://github.com/ION606/linkedin-api.git
synced 2026-05-14 22:06:54 +00:00
added npm files
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import { LinkedInProfile } from "./Profile.js";
|
||||
|
||||
export class Company {
|
||||
/** @type {import('../index.js').linkedInAPIClass} */
|
||||
#APIRef;
|
||||
|
||||
|
||||
/**
|
||||
* gets the employees of a company
|
||||
* @param {Number} [limit=Infinity] to make things simpler I used increments of 50, so the limit is essentially ceiled to the nearest multiple of 50
|
||||
* @param {Boolean} [raw=false] whether or not you want the raw JSON returned
|
||||
* @returns {Promise<JSON[] | LinkedInProfile[]>}
|
||||
* @note This function skips over any employees who's profile is marked as private
|
||||
*/
|
||||
async getEmployees(limit = Infinity, raw = false) {
|
||||
const employeesInit = await this.#APIRef._makeReq(`variables=(start:0,origin:FACETED_SEARCH,query:(flagshipSearchIntent:ORGANIZATIONS_PEOPLE_ALUMNI,queryParameters:List((key:currentCompany,value:List(${this.urn})),(key:resultType,value:List(ORGANIZATION_ALUMNI))),includeFiltersInResponse:true),count:1)`)
|
||||
|
||||
const numEmp = employeesInit.data.data.searchDashClustersByAll.paging.total,
|
||||
empAll = []
|
||||
|
||||
|
||||
// since the max cap is 50, we need to iterate until it's over 50
|
||||
for (let i = 0; i < numEmp; i += 50) {
|
||||
if (empAll.length >= limit) break;
|
||||
|
||||
const c = (i + 50 >= limit) ? limit - i : 50;
|
||||
|
||||
const employeeRes = await this.#APIRef._makeReq(`variables=(start:${i},origin:FACETED_SEARCH,query:(flagshipSearchIntent:ORGANIZATIONS_PEOPLE_ALUMNI,queryParameters:List((key:currentCompany,value:List(${this.urn})),(key:resultType,value:List(ORGANIZATION_ALUMNI))),includeFiltersInResponse:true),count:${c})`);
|
||||
const employees = employeeRes.included;
|
||||
|
||||
const empParsed = employees.filter(e => (e.$type === "com.linkedin.voyager.dash.search.EntityResultViewModel"))
|
||||
.filter(o => o.title.text !== "LinkedIn Member");
|
||||
|
||||
if (empParsed.length) empAll.push(...empParsed);
|
||||
await this.#APIRef.evade();
|
||||
}
|
||||
|
||||
|
||||
return (raw) ? empAll : empAll.map(eRaw => new LinkedInProfile(eRaw, this.#APIRef));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @returns {Promise<JSON[] | LinkedInProfile[]>}
|
||||
* @param {string} name
|
||||
* @param {boolean} raw
|
||||
*/
|
||||
getEmployees = (name, limit=1000, raw=false) => this.#APIRef.searchEmployees(name, limit, !raw, [this.urn]);
|
||||
|
||||
async getInfo() {
|
||||
const toAdd = `q=universalName&universalName=${this.urn}`;
|
||||
return await this.#APIRef._makeReq(toAdd);
|
||||
}
|
||||
|
||||
checkIfCompleted = () => !!(this.name && this.url && this.urn && this.#APIRef);
|
||||
|
||||
/**
|
||||
* @param {{title: {text: String}, entityUrn: String, navigationUrl: String}} data
|
||||
* @param {import('../index.js').linkedInAPIClass} APIRef
|
||||
*/
|
||||
constructor(data, APIRef) {
|
||||
this.#APIRef = APIRef;
|
||||
// this.entityUrn = entityUrn?.replace("urn:li:fsd_company:", "");
|
||||
this.name = data.title.text;
|
||||
this.urn = data.entityUrn;
|
||||
this.url = data.navigationUrl;
|
||||
|
||||
if (!this.checkIfCompleted()) throw "NOT ALL NEEDED PARAMS FOUND!";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { linkedInAPIClass } from "../index.js";
|
||||
|
||||
export class LinkedInProfile {
|
||||
/** @type {linkedInAPIClass} */
|
||||
#APIRef;
|
||||
|
||||
/**
|
||||
* Attempts to get the contact info for the person
|
||||
* @returns {Promise<{websites: [{label:string, category:string, url:string}], emailAddress:string, phoneNumbers:[string],weChatContactInfo:any,twitterHandles:[string], instantMessengers:[]}>}
|
||||
*/
|
||||
async getContactInfo() {
|
||||
const r = await this.#APIRef._makeReq(`includeWebMetadata=true&variables=(memberIdentity:${this.entityNameJoined})`, true);
|
||||
if (r?.data?.errors) return console.error(JSON.stringify(r.data.errors));
|
||||
const uObj = r.included.find(o => o.publicIdentifier === this.entityNameJoined);
|
||||
if (!uObj) return;
|
||||
let { phoneNumbers, emailAddress, websites, weChatContactInfo, twitterHandles, instantMessengers } = uObj;
|
||||
|
||||
if (websites) websites = websites.map(w => ({ label: w.label, category: w.category, url: w.url }));
|
||||
return { phoneNumbers, emailAddress, websites, weChatContactInfo, twitterHandles, instantMessengers };
|
||||
}
|
||||
|
||||
// Parse specific services offered, contained in the 'simpleInsight' section of 'insightsResolutionResults'
|
||||
parseServices(insights) {
|
||||
for (let insight of insights) {
|
||||
if (insight.simpleInsight && insight.simpleInsight.title && insight.simpleInsight.title.text) {
|
||||
return insight.simpleInsight.title.text;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
constructor(jsonData, apiRef) {
|
||||
this.#APIRef = apiRef;
|
||||
this.name = jsonData.title ? jsonData.title.text : '';
|
||||
this.entityNameJoined = jsonData.navigationUrl?.split("/in/")[1]?.split("?")[0];
|
||||
this.profileUrl = jsonData.navigationUrl || '';
|
||||
this.trackingUrn = jsonData.trackingUrn || '';
|
||||
|
||||
const match = jsonData.entityUrn?.match(/urn:li:fsd_profile:(.*?),/);
|
||||
this.entityUrn = match ? match[1] : '';
|
||||
|
||||
this.jobServices = jsonData.insightsResolutionResults ? this.parseServices(jsonData.insightsResolutionResults) : '';
|
||||
this.primarySubtitle = jsonData.primarySubtitle ? jsonData.primarySubtitle.text : '';
|
||||
this.secondarySubtitle = jsonData.secondarySubtitle ? jsonData.secondarySubtitle.text : '';
|
||||
this.bserpEntityNavigationalUrl = jsonData.bserpEntityNavigationalUrl || '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import linkedInAPIClass from "../index.js";
|
||||
import { LinkedInProfile } from "./Profile.js";
|
||||
import { Company } from "./Company.js";
|
||||
import { GenericEntity, Group, ReactionTypeCount, SocialActivityCounts } from './misc.js'
|
||||
|
||||
|
||||
export { linkedInAPIClass, LinkedInProfile, Company, GenericEntity, Group, ReactionTypeCount, SocialActivityCounts };
|
||||
@@ -0,0 +1,30 @@
|
||||
export class ReactionTypeCount {
|
||||
constructor({ count, reactionType }) {
|
||||
this.count = count;
|
||||
this.reactionType = reactionType;
|
||||
}
|
||||
}
|
||||
|
||||
export class SocialActivityCounts {
|
||||
constructor({ entityUrn, numComments, numLikes, reactionTypeCounts, liked, preDashEntityUrn }) {
|
||||
this.entityUrn = entityUrn;
|
||||
this.numComments = numComments;
|
||||
this.numLikes = numLikes;
|
||||
this.reactionTypeCounts = reactionTypeCounts.map(count => new ReactionTypeCount(count));
|
||||
this.liked = liked;
|
||||
this.preDashEntityUrn = preDashEntityUrn;
|
||||
}
|
||||
}
|
||||
|
||||
export class Group {
|
||||
constructor({ entityUrn }) {
|
||||
this.entityUrn = entityUrn;
|
||||
}
|
||||
}
|
||||
|
||||
// Placeholder class for any other types
|
||||
export class GenericEntity {
|
||||
constructor(data) {
|
||||
Object.assign(this, data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user