linkedin-api-voyager 1.3.0 → 1.3.1
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/lib/company.d.ts +1 -0
- package/lib/company.js +40 -0
- package/lib/config.d.ts +20 -0
- package/lib/config.js +94 -0
- package/{src/index.ts → lib/index.d.ts} +1 -1
- package/lib/index.js +22 -0
- package/lib/posts.d.ts +12 -0
- package/lib/posts.js +134 -0
- package/lib/search.d.ts +3 -0
- package/lib/search.js +184 -0
- package/lib/teste.d.ts +1 -0
- package/lib/teste.js +10 -0
- package/lib/types.d.ts +794 -0
- package/lib/types.js +2 -0
- package/lib/user.d.ts +38 -0
- package/lib/user.js +172 -0
- package/lib/utils.d.ts +45 -0
- package/lib/utils.js +606 -0
- package/package.json +11 -4
- package/src/account.ts +0 -116
- package/src/company.ts +0 -33
- package/src/config.ts +0 -109
- package/src/linkedin.ts +0 -0
- package/src/posts.ts +0 -71
- package/src/search.ts +0 -183
- package/src/utils.ts +0 -213
- package/tsconfig.json +0 -10
package/lib/company.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getCompany: (identifier: string) => Promise<any>;
|
package/lib/company.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getCompany = void 0;
|
|
13
|
+
const config_1 = require("./config");
|
|
14
|
+
const utils_1 = require("./utils");
|
|
15
|
+
const getCompany = (identifier) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
+
const response = yield (0, config_1.fetchData)(`/organization/companies?decorationId=com.linkedin.voyager.deco.organization.web.WebFullCompanyMain-12&q=universalName&universalName=${identifier}`);
|
|
17
|
+
const data = (0, utils_1.extractDataWithReferences)(response.data["*elements"], response.included);
|
|
18
|
+
const fieldsMap = {
|
|
19
|
+
id: "entityUrn",
|
|
20
|
+
name: "name",
|
|
21
|
+
description: "description",
|
|
22
|
+
username: "universalName",
|
|
23
|
+
companyPageUrl: "companyPageUrl",
|
|
24
|
+
staffCount: "staffCount",
|
|
25
|
+
url: "url",
|
|
26
|
+
companyIndustries: "*companyIndustries[0].localizedName",
|
|
27
|
+
location: "locationName",
|
|
28
|
+
jobSearchPageUrl: "jobSearchPageUrl",
|
|
29
|
+
phone: "phone",
|
|
30
|
+
followerCount: "followingInfo.followerCount",
|
|
31
|
+
backgroundCoverImage: "backgroundCoverImage.image",
|
|
32
|
+
logo: "logo.image",
|
|
33
|
+
permissions: "permissions",
|
|
34
|
+
};
|
|
35
|
+
return (0, utils_1.extractFields)(data, fieldsMap).map((item) => {
|
|
36
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
37
|
+
return (Object.assign(Object.assign({}, item), { id: item.id.split(":")[3], backgroundCoverImage: `${(_a = item.backgroundCoverImage) === null || _a === void 0 ? void 0 : _a.rootUrl}${(_d = (_c = (_b = item.backgroundCoverImage) === null || _b === void 0 ? void 0 : _b.artifacts) === null || _c === void 0 ? void 0 : _c.at(-1)) === null || _d === void 0 ? void 0 : _d.fileIdentifyingUrlPathSegment}`, logo: `${(_e = item.logo) === null || _e === void 0 ? void 0 : _e.rootUrl}${(_h = (_g = (_f = item.logo) === null || _f === void 0 ? void 0 : _f.artifacts) === null || _g === void 0 ? void 0 : _g.at(-1)) === null || _h === void 0 ? void 0 : _h.fileIdentifyingUrlPathSegment}` }));
|
|
38
|
+
})[0];
|
|
39
|
+
});
|
|
40
|
+
exports.getCompany = getCompany;
|
package/lib/config.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const COOKIE_FILE_PATH = "linkedin_cookies.json";
|
|
2
|
+
export declare const API_BASE_URL = "https://www.linkedin.com/voyager/api";
|
|
3
|
+
export declare const AUTH_BASE_URL = "https://www.linkedin.com";
|
|
4
|
+
interface LinkedInCookies {
|
|
5
|
+
JSESSIONID: string;
|
|
6
|
+
li_at: string;
|
|
7
|
+
timestamp: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const saveCookies: (JSESSIONID: string, li_at: string) => Promise<void>;
|
|
10
|
+
export declare const loadCookies: () => Promise<LinkedInCookies | null>;
|
|
11
|
+
export declare const Client: (providedCookies?: {
|
|
12
|
+
JSESSIONID: string;
|
|
13
|
+
li_at: string;
|
|
14
|
+
}) => Promise<ReturnType<typeof api>>;
|
|
15
|
+
declare const api: ({ JSESSIONID, li_at }: {
|
|
16
|
+
li_at: string;
|
|
17
|
+
JSESSIONID: number;
|
|
18
|
+
}) => import("axios").AxiosInstance;
|
|
19
|
+
export declare const fetchData: (endpoint: string) => Promise<any>;
|
|
20
|
+
export {};
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.fetchData = exports.Client = exports.loadCookies = exports.saveCookies = exports.AUTH_BASE_URL = exports.API_BASE_URL = exports.COOKIE_FILE_PATH = void 0;
|
|
13
|
+
const fs = require("fs-extra");
|
|
14
|
+
const axios_1 = require("axios");
|
|
15
|
+
exports.COOKIE_FILE_PATH = "linkedin_cookies.json";
|
|
16
|
+
exports.API_BASE_URL = "https://www.linkedin.com/voyager/api";
|
|
17
|
+
exports.AUTH_BASE_URL = "https://www.linkedin.com";
|
|
18
|
+
// Função para salvar cookies no arquivo JSON
|
|
19
|
+
const saveCookies = (JSESSIONID, li_at) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
try {
|
|
21
|
+
const cookies = {
|
|
22
|
+
JSESSIONID,
|
|
23
|
+
li_at,
|
|
24
|
+
timestamp: Date.now(),
|
|
25
|
+
};
|
|
26
|
+
yield fs.ensureFile(exports.COOKIE_FILE_PATH);
|
|
27
|
+
yield fs.writeJson(exports.COOKIE_FILE_PATH, cookies, { spaces: 2 });
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
exports.saveCookies = saveCookies;
|
|
34
|
+
// Função para carregar cookies do arquivo JSON
|
|
35
|
+
const loadCookies = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
+
try {
|
|
37
|
+
const exists = yield fs.pathExists(exports.COOKIE_FILE_PATH);
|
|
38
|
+
if (!exists) {
|
|
39
|
+
throw new Error("Arquivo de cookies não encontrado");
|
|
40
|
+
}
|
|
41
|
+
const cookies = yield fs.readJson(exports.COOKIE_FILE_PATH);
|
|
42
|
+
// Verificar se os cookies têm a estrutura esperada
|
|
43
|
+
if (!cookies.JSESSIONID || !cookies.li_at) {
|
|
44
|
+
throw new Error("Cookies inválidos encontrados no arquivo");
|
|
45
|
+
}
|
|
46
|
+
return cookies;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
exports.loadCookies = loadCookies;
|
|
53
|
+
// Função para criar cliente com cookies automáticos
|
|
54
|
+
const Client = (providedCookies) => __awaiter(void 0, void 0, void 0, function* () {
|
|
55
|
+
let cookiesToUse;
|
|
56
|
+
const savedCookies = yield (0, exports.loadCookies)();
|
|
57
|
+
if (savedCookies) {
|
|
58
|
+
cookiesToUse = {
|
|
59
|
+
JSESSIONID: savedCookies.JSESSIONID,
|
|
60
|
+
li_at: savedCookies.li_at,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
if (providedCookies) {
|
|
65
|
+
yield (0, exports.saveCookies)(providedCookies.JSESSIONID, providedCookies.li_at);
|
|
66
|
+
cookiesToUse = providedCookies;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
throw new Error("Nenhum cookie válido fornecido");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return api({
|
|
73
|
+
JSESSIONID: parseInt(cookiesToUse.JSESSIONID),
|
|
74
|
+
li_at: cookiesToUse.li_at,
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
exports.Client = Client;
|
|
78
|
+
const api = ({ JSESSIONID, li_at }) => {
|
|
79
|
+
return axios_1.default.create({
|
|
80
|
+
baseURL: exports.API_BASE_URL,
|
|
81
|
+
headers: {
|
|
82
|
+
"accept-language": "pt-BR,pt;q=0.9,fr-FR;q=0.8,fr;q=0.7,en-US;q=0.6,en;q=0.5",
|
|
83
|
+
accept: "application/vnd.linkedin.normalized+json+2.1",
|
|
84
|
+
cookie: `li_at=${li_at}; JSESSIONID="ajax:${JSESSIONID}"`,
|
|
85
|
+
"csrf-token": `ajax:${JSESSIONID}`,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
const fetchData = (endpoint) => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
+
const api = yield (0, exports.Client)();
|
|
91
|
+
const response = yield api.get(endpoint);
|
|
92
|
+
return response.data;
|
|
93
|
+
});
|
|
94
|
+
exports.fetchData = fetchData;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./user"), exports);
|
|
18
|
+
__exportStar(require("./company"), exports);
|
|
19
|
+
__exportStar(require("./posts"), exports);
|
|
20
|
+
__exportStar(require("./search"), exports);
|
|
21
|
+
__exportStar(require("./utils"), exports);
|
|
22
|
+
__exportStar(require("./config"), exports);
|
package/lib/posts.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const parseResponsePostLinkedin: (response: any, key: string, accumulatedData: any) => any;
|
|
2
|
+
export declare const getCommentsByPostUrl: (url: string, start?: number, limit?: number, accumulatedComments?: unknown[]) => Promise<unknown[]>;
|
|
3
|
+
export declare const getPosts: () => Promise<never[]>;
|
|
4
|
+
export declare const getPostLinkedin: (url: string, commentsCount?: number, likesCount?: number) => Promise<any>;
|
|
5
|
+
export declare const getUserPosts: ({ identifier, start, count, accumulatedPosts, }: {
|
|
6
|
+
identifier: string;
|
|
7
|
+
start?: number;
|
|
8
|
+
count?: number;
|
|
9
|
+
accumulatedPosts?: unknown[];
|
|
10
|
+
}) => Promise<any[]>;
|
|
11
|
+
export declare const helperGetPosts: (response: any, key: string, accumulatedPosts?: any, addFields?: Record<string, string>) => any[];
|
|
12
|
+
export declare const helperGetImageUrl: (item: any) => any;
|
package/lib/posts.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.helperGetImageUrl = exports.helperGetPosts = exports.getUserPosts = exports.getPostLinkedin = exports.getPosts = exports.getCommentsByPostUrl = exports.parseResponsePostLinkedin = void 0;
|
|
13
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
14
|
+
const user_1 = require("./user");
|
|
15
|
+
const config_1 = require("./config");
|
|
16
|
+
const utils_1 = require("./utils");
|
|
17
|
+
const parseResponsePostLinkedin = (response, key, accumulatedData) => {
|
|
18
|
+
var _a, _b, _c, _d;
|
|
19
|
+
const elements = (_c = (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b[key]) === null || _c === void 0 ? void 0 : _c["*elements"];
|
|
20
|
+
const data = ((_d = response.included) === null || _d === void 0 ? void 0 : _d.filter((item) => elements.includes(item.entityUrn))) || [];
|
|
21
|
+
if (!elements || elements.length === 0) {
|
|
22
|
+
return accumulatedData;
|
|
23
|
+
}
|
|
24
|
+
return data;
|
|
25
|
+
};
|
|
26
|
+
exports.parseResponsePostLinkedin = parseResponsePostLinkedin;
|
|
27
|
+
const getCommentsByPostUrl = (url_1, ...args_1) => __awaiter(void 0, [url_1, ...args_1], void 0, function* (url, start = 0, limit = 50, accumulatedComments = []) {
|
|
28
|
+
var _a, _b, _c, _d, _e;
|
|
29
|
+
const postID = (_a = url.match(/activity-(\d+)/)) === null || _a === void 0 ? void 0 : _a[1];
|
|
30
|
+
const response = yield (0, config_1.fetchData)(`/graphql?includeWebMetadata=false&queryId=voyagerSocialDashComments.95ed44bc87596acce7c460c70934d0ff&variables=(count:${limit},start:${start},numReplies:1,socialDetailUrn:urn%3Ali%3Afsd_socialDetail%3A%28urn%3Ali%3Aactivity%${postID}%2Curn%3Ali%3Aactivity%3A${postID}%2Curn%3Ali%3AhighlightedReply%3A-%29,sortOrder:RELEVANCE)`);
|
|
31
|
+
const elements = (_d = (_c = (_b = response.data) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.socialDashCommentsBySocialDetail) === null || _d === void 0 ? void 0 : _d["*elements"];
|
|
32
|
+
// Se não há elementos, retorna os comentários acumulados
|
|
33
|
+
if (!elements || elements.length === 0) {
|
|
34
|
+
return accumulatedComments;
|
|
35
|
+
}
|
|
36
|
+
const data = ((_e = response.included) === null || _e === void 0 ? void 0 : _e.filter((item) => elements.includes(item.entityUrn))) || [];
|
|
37
|
+
// Mapeamento melhorado dos campos
|
|
38
|
+
const fieldsMap = {
|
|
39
|
+
id: "entityUrn",
|
|
40
|
+
createdAt: "createdAt",
|
|
41
|
+
isAuthor: "commenter.author",
|
|
42
|
+
name: "commenter.title.text",
|
|
43
|
+
headline: "commenter.subtitle",
|
|
44
|
+
profileUrl: "commenter.navigationUrl",
|
|
45
|
+
comment: "commentary.text",
|
|
46
|
+
permalink: "permalink",
|
|
47
|
+
image: "commenter.image.attributes.0.detailData.nonEntityProfilePicture.vectorImage",
|
|
48
|
+
};
|
|
49
|
+
const currentComments = (0, utils_1.extractFields)(data, fieldsMap).map((comment) => {
|
|
50
|
+
var _a, _b, _c, _d;
|
|
51
|
+
return (Object.assign(Object.assign({}, comment), { image: `${(_a = comment.image) === null || _a === void 0 ? void 0 : _a.rootUrl}${(_d = (_c = (_b = comment.image) === null || _b === void 0 ? void 0 : _b.artifacts) === null || _c === void 0 ? void 0 : _c.at(-1)) === null || _d === void 0 ? void 0 : _d.fileIdentifyingUrlPathSegment}` }));
|
|
52
|
+
});
|
|
53
|
+
const allComments = [...accumulatedComments, ...currentComments];
|
|
54
|
+
// console.log(
|
|
55
|
+
// `🔍 Encontrados ${elements.length} comentários (Total: ${allComments.length})`
|
|
56
|
+
// );
|
|
57
|
+
// Continua a busca se há mais elementos
|
|
58
|
+
if (elements.length > 0) {
|
|
59
|
+
return yield (0, exports.getCommentsByPostUrl)(url, start + elements.length, limit, allComments);
|
|
60
|
+
}
|
|
61
|
+
// Se retornou menos que o limite, chegou ao fim
|
|
62
|
+
return allComments;
|
|
63
|
+
});
|
|
64
|
+
exports.getCommentsByPostUrl = getCommentsByPostUrl;
|
|
65
|
+
const getPosts = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
|
+
return [];
|
|
67
|
+
});
|
|
68
|
+
exports.getPosts = getPosts;
|
|
69
|
+
const getPostLinkedin = (url_1, ...args_1) => __awaiter(void 0, [url_1, ...args_1], void 0, function* (url, commentsCount = 10, likesCount = 10) {
|
|
70
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
|
|
71
|
+
const slugPost = (_a = url.match(/\/posts\/([^\/?]+)/)) === null || _a === void 0 ? void 0 : _a[1];
|
|
72
|
+
const response = yield (0, config_1.fetchData)(`/graphql?includeWebMetadata=false&queryId=voyagerFeedDashUpdates.5cf9b25c46b9d86c224647752f7d6bfd&variables=(commentsCount:${commentsCount},likesCount:${likesCount},includeCommentsFirstReply:true,includeReactions:false,moduleKey:feed-item%3Adesktop,slug:${slugPost})`);
|
|
73
|
+
const posts = (_b = (0, exports.helperGetPosts)(response, "feedDashUpdatesByPostSlug", undefined, { actor: "actor" })) === null || _b === void 0 ? void 0 : _b[0];
|
|
74
|
+
const actor = {
|
|
75
|
+
name: (_d = (_c = posts === null || posts === void 0 ? void 0 : posts.actor) === null || _c === void 0 ? void 0 : _c.name) === null || _d === void 0 ? void 0 : _d.text,
|
|
76
|
+
headline: (_f = (_e = posts === null || posts === void 0 ? void 0 : posts.actor) === null || _e === void 0 ? void 0 : _e.description) === null || _f === void 0 ? void 0 : _f.text,
|
|
77
|
+
profileUrl: ((_o = (_m = (_l = (_k = (_j = (_h = (_g = posts === null || posts === void 0 ? void 0 : posts.actor) === null || _g === void 0 ? void 0 : _g.image) === null || _h === void 0 ? void 0 : _h.attributes) === null || _j === void 0 ? void 0 : _j[0]) === null || _k === void 0 ? void 0 : _k.detailData) === null || _l === void 0 ? void 0 : _l.nonEntityProfilePicture) === null || _m === void 0 ? void 0 : _m.vectorImage) === null || _o === void 0 ? void 0 : _o.rootUrl) +
|
|
78
|
+
((_x = (_w = (_v = (_u = (_t = (_s = (_r = (_q = (_p = posts === null || posts === void 0 ? void 0 : posts.actor) === null || _p === void 0 ? void 0 : _p.image) === null || _q === void 0 ? void 0 : _q.attributes) === null || _r === void 0 ? void 0 : _r[0]) === null || _s === void 0 ? void 0 : _s.detailData) === null || _t === void 0 ? void 0 : _t.nonEntityProfilePicture) === null || _u === void 0 ? void 0 : _u.vectorImage) === null || _v === void 0 ? void 0 : _v.artifacts) === null || _w === void 0 ? void 0 : _w.at(-1)) === null || _x === void 0 ? void 0 : _x.fileIdentifyingUrlPathSegment),
|
|
79
|
+
};
|
|
80
|
+
return Object.assign(Object.assign({}, posts), { actor });
|
|
81
|
+
});
|
|
82
|
+
exports.getPostLinkedin = getPostLinkedin;
|
|
83
|
+
const getUserPosts = (_a) => __awaiter(void 0, [_a], void 0, function* ({ identifier, start = 0, count = 50, accumulatedPosts = [], }) {
|
|
84
|
+
const profileId = yield (0, user_1.extractProfileIdLinkedin)(identifier);
|
|
85
|
+
const response = yield (0, config_1.fetchData)(`graphql?variables=(profileUrn:urn%3Ali%3Afsd_profile%3A${profileId},count:${count},start:${start})&queryId=voyagerFeedDashProfileUpdates.4af00b28d60ed0f1488018948daad822`);
|
|
86
|
+
const parsePosts = (0, exports.helperGetPosts)(response, "feedDashProfileUpdatesByMemberShareFeed", accumulatedPosts);
|
|
87
|
+
return parsePosts;
|
|
88
|
+
});
|
|
89
|
+
exports.getUserPosts = getUserPosts;
|
|
90
|
+
const helperGetPosts = (response, key, accumulatedPosts, addFields) => {
|
|
91
|
+
const data = (0, exports.parseResponsePostLinkedin)(response, key, accumulatedPosts);
|
|
92
|
+
const socialActivityData = response.included.filter((item) => (item === null || item === void 0 ? void 0 : item.$type) === "com.linkedin.voyager.dash.feed.SocialActivityCounts");
|
|
93
|
+
const fieldsMap = Object.assign({ urn: "metadata.backendUrn", postUrl: "socialContent.shareUrl", contentText: "commentary.text.text", tags: "commentary.text.attributesV2", media: "content", dateDescription: "actor.subDescription.text" }, addFields);
|
|
94
|
+
const fieldsSocialActivityCountMap = {
|
|
95
|
+
numLikes: "numLikes",
|
|
96
|
+
numComments: "numComments",
|
|
97
|
+
reactionCounts: "reactionTypeCounts",
|
|
98
|
+
numShares: "numShares",
|
|
99
|
+
urn: "urn",
|
|
100
|
+
};
|
|
101
|
+
const extractPosts = (0, utils_1.extractFields)(data, fieldsMap);
|
|
102
|
+
const extractSocialActivityCount = (0, utils_1.extractFields)(socialActivityData, fieldsSocialActivityCountMap);
|
|
103
|
+
const parsePosts = extractPosts === null || extractPosts === void 0 ? void 0 : extractPosts.map((post) => {
|
|
104
|
+
var _a, _b, _c;
|
|
105
|
+
const socialActivity = extractSocialActivityCount.find((item) => item.urn === post.urn) || {};
|
|
106
|
+
if (socialActivity) {
|
|
107
|
+
const mediaNonNullKeys = Object.fromEntries(Object.entries(post.media).filter(([_, value]) => value !== null));
|
|
108
|
+
let media = {};
|
|
109
|
+
if (mediaNonNullKeys === null || mediaNonNullKeys === void 0 ? void 0 : mediaNonNullKeys.imageComponent) {
|
|
110
|
+
media = Object.assign(Object.assign({}, media), { images: (_b = (_a = mediaNonNullKeys === null || mediaNonNullKeys === void 0 ? void 0 : mediaNonNullKeys.imageComponent) === null || _a === void 0 ? void 0 : _a.images) === null || _b === void 0 ? void 0 : _b.map((item) => (0, exports.helperGetImageUrl)(item)) });
|
|
111
|
+
}
|
|
112
|
+
if (mediaNonNullKeys === null || mediaNonNullKeys === void 0 ? void 0 : mediaNonNullKeys.linkedInVideoComponent) {
|
|
113
|
+
const videoentityUrn = (_c = mediaNonNullKeys === null || mediaNonNullKeys === void 0 ? void 0 : mediaNonNullKeys.linkedInVideoComponent) === null || _c === void 0 ? void 0 : _c["*videoPlayMetadata"];
|
|
114
|
+
const videoActivityData = response.included.filter((item) => (item === null || item === void 0 ? void 0 : item.entityUrn) === videoentityUrn);
|
|
115
|
+
media = Object.assign(Object.assign({}, media), { videoActivityData });
|
|
116
|
+
}
|
|
117
|
+
return Object.assign(Object.assign(Object.assign({}, post), { media }), socialActivity);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
return parsePosts;
|
|
121
|
+
};
|
|
122
|
+
exports.helperGetPosts = helperGetPosts;
|
|
123
|
+
const helperGetImageUrl = (item) => {
|
|
124
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
125
|
+
const keyEntity = ((_c = (_b = (_a = item === null || item === void 0 ? void 0 : item.attributes) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.detailData) === null || _c === void 0 ? void 0 : _c.nonEntityProfilePicture)
|
|
126
|
+
? "nonEntityProfilePicture"
|
|
127
|
+
: "vectorImage";
|
|
128
|
+
const itemImage = (_f = (_e = (_d = item === null || item === void 0 ? void 0 : item.attributes) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.detailData) === null || _f === void 0 ? void 0 : _f[keyEntity];
|
|
129
|
+
const biggestWidth = (_g = itemImage === null || itemImage === void 0 ? void 0 : itemImage.artifacts) === null || _g === void 0 ? void 0 : _g.reduce((max, current) => {
|
|
130
|
+
return current.width > max.width ? current : max;
|
|
131
|
+
}, (_h = itemImage === null || itemImage === void 0 ? void 0 : itemImage.artifacts) === null || _h === void 0 ? void 0 : _h[0]);
|
|
132
|
+
return (itemImage === null || itemImage === void 0 ? void 0 : itemImage.rootUrl) + (biggestWidth === null || biggestWidth === void 0 ? void 0 : biggestWidth.fileIdentifyingUrlPathSegment);
|
|
133
|
+
};
|
|
134
|
+
exports.helperGetImageUrl = helperGetImageUrl;
|
package/lib/search.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { ISearchParams, ISearchPeopleParams, ISearchPeopleResponse, SearchResponse } from "./types";
|
|
2
|
+
export declare const search: ({ offset, limit, ...opts }: ISearchParams) => Promise<SearchResponse>;
|
|
3
|
+
export declare function searchPeople(queryOrParams: string | ISearchPeopleParams): Promise<ISearchPeopleResponse>;
|
package/lib/search.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.search = void 0;
|
|
24
|
+
exports.searchPeople = searchPeople;
|
|
25
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
26
|
+
const config_1 = require("./config");
|
|
27
|
+
const utils_1 = require("./utils");
|
|
28
|
+
// Constantes
|
|
29
|
+
const MAX_SEARCH_COUNT = 25;
|
|
30
|
+
const search = (_a) => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
|
+
var _b, _c, _d, _e, _f;
|
|
32
|
+
var { offset = 0, limit = MAX_SEARCH_COUNT } = _a, opts = __rest(_a, ["offset", "limit"]);
|
|
33
|
+
const response = {
|
|
34
|
+
paging: {
|
|
35
|
+
offset: 0,
|
|
36
|
+
count: 0,
|
|
37
|
+
total: -1,
|
|
38
|
+
},
|
|
39
|
+
results: [],
|
|
40
|
+
};
|
|
41
|
+
const params = Object.assign({ start: offset, count: Math.min(limit, MAX_SEARCH_COUNT), filters: "List()", origin: "GLOBAL_SEARCH_HEADER" }, opts);
|
|
42
|
+
const keywords = params.query
|
|
43
|
+
? `keywords:${encodeURIComponent(params.query)},`
|
|
44
|
+
: "";
|
|
45
|
+
const uri = `graphql?variables=(start:${params.start},origin:${params.origin},` +
|
|
46
|
+
`query:(${keywords}flagshipSearchIntent:SEARCH_SRP,` +
|
|
47
|
+
`queryParameters:${params.filters},includeFiltersInResponse:false))` +
|
|
48
|
+
`&queryId=voyagerSearchDashClusters.bb967969ef89137e6dec45d038310505`;
|
|
49
|
+
const res = yield (0, config_1.fetchData)(uri);
|
|
50
|
+
const dataClusters = (_c = (_b = res === null || res === void 0 ? void 0 : res.data) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.searchDashClustersByAll;
|
|
51
|
+
if (!dataClusters)
|
|
52
|
+
return response;
|
|
53
|
+
if (dataClusters.$type !== "com.linkedin.restli.common.CollectionResponse") {
|
|
54
|
+
return response;
|
|
55
|
+
}
|
|
56
|
+
response.paging.count = dataClusters.paging.count;
|
|
57
|
+
response.paging.total = dataClusters.paging.total;
|
|
58
|
+
for (const element of (_d = dataClusters.elements) !== null && _d !== void 0 ? _d : []) {
|
|
59
|
+
if (element.$type !==
|
|
60
|
+
"com.linkedin.voyager.dash.search.SearchClusterViewModel") {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
for (const it of (_e = element.items) !== null && _e !== void 0 ? _e : []) {
|
|
64
|
+
if (it.$type !== "com.linkedin.voyager.dash.search.SearchItem") {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const item = it === null || it === void 0 ? void 0 : it.item;
|
|
68
|
+
if (!item)
|
|
69
|
+
continue;
|
|
70
|
+
let entity = item.entityResult;
|
|
71
|
+
if (!entity) {
|
|
72
|
+
const linkedEntityUrn = item["*entityResult"];
|
|
73
|
+
if (!linkedEntityUrn)
|
|
74
|
+
continue;
|
|
75
|
+
entity = (_f = res.included) === null || _f === void 0 ? void 0 : _f.find((e) => e.entityUrn === linkedEntityUrn);
|
|
76
|
+
if (!entity)
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (entity.$type !==
|
|
80
|
+
"com.linkedin.voyager.dash.search.EntityResultViewModel") {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
response.results.push(entity);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return response;
|
|
87
|
+
});
|
|
88
|
+
exports.search = search;
|
|
89
|
+
function searchPeople(queryOrParams) {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
92
|
+
const _s = typeof queryOrParams === "string"
|
|
93
|
+
? { query: queryOrParams }
|
|
94
|
+
: queryOrParams, { includePrivateProfiles = true } = _s, params = __rest(_s, ["includePrivateProfiles"]);
|
|
95
|
+
const filters = ["(key:resultType,value:List(PEOPLE))"];
|
|
96
|
+
if (params.connectionOf) {
|
|
97
|
+
filters.push(`(key:connectionOf,value:List(${params.connectionOf}))`);
|
|
98
|
+
}
|
|
99
|
+
if (params.networkDepths) {
|
|
100
|
+
const stringify = params.networkDepths.join(" | ");
|
|
101
|
+
filters.push(`(key:network,value:List(${stringify}))`);
|
|
102
|
+
}
|
|
103
|
+
else if (params.networkDepth) {
|
|
104
|
+
filters.push(`(key:network,value:List(${params.networkDepth}))`);
|
|
105
|
+
}
|
|
106
|
+
if (params.regions) {
|
|
107
|
+
const stringify = params.regions.join(" | ");
|
|
108
|
+
filters.push(`(key:geoUrn,value:List(${stringify}))`);
|
|
109
|
+
}
|
|
110
|
+
if (params.industries) {
|
|
111
|
+
const stringify = params.industries.join(" | ");
|
|
112
|
+
filters.push(`(key:industry,value:List(${stringify}))`);
|
|
113
|
+
}
|
|
114
|
+
if (params.currentCompany) {
|
|
115
|
+
const stringify = params.currentCompany.join(" | ");
|
|
116
|
+
filters.push(`(key:currentCompany,value:List(${stringify}))`);
|
|
117
|
+
}
|
|
118
|
+
if (params.pastCompanies) {
|
|
119
|
+
const stringify = params.pastCompanies.join(" | ");
|
|
120
|
+
filters.push(`(key:pastCompany,value:List(${stringify}))`);
|
|
121
|
+
}
|
|
122
|
+
if (params.profileLanguages) {
|
|
123
|
+
const stringify = params.profileLanguages.join(" | ");
|
|
124
|
+
filters.push(`(key:profileLanguage,value:List(${stringify}))`);
|
|
125
|
+
}
|
|
126
|
+
if (params.nonprofitInterests) {
|
|
127
|
+
const stringify = params.nonprofitInterests.join(" | ");
|
|
128
|
+
filters.push(`(key:nonprofitInterest,value:List(${stringify}))`);
|
|
129
|
+
}
|
|
130
|
+
if (params.schools) {
|
|
131
|
+
const stringify = params.schools.join(" | ");
|
|
132
|
+
filters.push(`(key:schools,value:List(${stringify}))`);
|
|
133
|
+
}
|
|
134
|
+
if (params.serviceCategories) {
|
|
135
|
+
const stringify = params.serviceCategories.join(" | ");
|
|
136
|
+
filters.push(`(key:serviceCategory,value:List(${stringify}))`);
|
|
137
|
+
}
|
|
138
|
+
// `Keywords` filter
|
|
139
|
+
const keywordTitle = (_a = params.keywordTitle) !== null && _a !== void 0 ? _a : params.title;
|
|
140
|
+
if (params.keywordFirstName) {
|
|
141
|
+
filters.push(`(key:firstName,value:List(${params.keywordFirstName}))`);
|
|
142
|
+
}
|
|
143
|
+
if (params.keywordLastName) {
|
|
144
|
+
filters.push(`(key:lastName,value:List(${params.keywordLastName}))`);
|
|
145
|
+
}
|
|
146
|
+
if (keywordTitle) {
|
|
147
|
+
filters.push(`(key:title,value:List(${keywordTitle}))`);
|
|
148
|
+
}
|
|
149
|
+
if (params.keywordCompany) {
|
|
150
|
+
filters.push(`(key:company,value:List(${params.keywordCompany}))`);
|
|
151
|
+
}
|
|
152
|
+
if (params.keywordSchool) {
|
|
153
|
+
filters.push(`(key:school,value:List(${params.keywordSchool}))`);
|
|
154
|
+
}
|
|
155
|
+
const res = yield (0, exports.search)(Object.assign({ offset: params.offset, limit: params.limit, filters: `List(${filters.join(",")})` }, (params.query && { query: params.query })));
|
|
156
|
+
const response = {
|
|
157
|
+
paging: res.paging,
|
|
158
|
+
results: [],
|
|
159
|
+
};
|
|
160
|
+
for (const result of res.results) {
|
|
161
|
+
if (!includePrivateProfiles &&
|
|
162
|
+
((_b = result.entityCustomTrackingInfo) === null || _b === void 0 ? void 0 : _b.memberDistance) === "OUT_OF_NETWORK") {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const urnId = (0, utils_1.getIdFromUrn)((0, utils_1.getUrnFromRawUpdate)(result.entityUrn));
|
|
166
|
+
(0, utils_1.assert)(urnId);
|
|
167
|
+
const name = (_c = result.title) === null || _c === void 0 ? void 0 : _c.text;
|
|
168
|
+
(0, utils_1.assert)(name);
|
|
169
|
+
const url = (_d = result.navigationUrl) === null || _d === void 0 ? void 0 : _d.split("?")[0];
|
|
170
|
+
(0, utils_1.assert)(url);
|
|
171
|
+
response.results.push({
|
|
172
|
+
urnId,
|
|
173
|
+
name,
|
|
174
|
+
url,
|
|
175
|
+
distance: (_e = result.entityCustomTrackingInfo) === null || _e === void 0 ? void 0 : _e.memberDistance,
|
|
176
|
+
headline: (_f = result.primarySubtitle) === null || _f === void 0 ? void 0 : _f.text,
|
|
177
|
+
location: (_g = result.secondarySubtitle) === null || _g === void 0 ? void 0 : _g.text,
|
|
178
|
+
summary: ((_h = result.summary) === null || _h === void 0 ? void 0 : _h.text) || undefined,
|
|
179
|
+
image: ((_r = (_q = (_p = (_o = (_m = (_l = (_k = (_j = result.image) === null || _j === void 0 ? void 0 : _j.attributes) === null || _k === void 0 ? void 0 : _k[0]) === null || _l === void 0 ? void 0 : _l.detailData) === null || _m === void 0 ? void 0 : _m.nonEntityProfilePicture) === null || _o === void 0 ? void 0 : _o.vectorImage) === null || _p === void 0 ? void 0 : _p.artifacts) === null || _q === void 0 ? void 0 : _q[0]) === null || _r === void 0 ? void 0 : _r.fileIdentifyingUrlPathSegment) || null,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
return response;
|
|
183
|
+
});
|
|
184
|
+
}
|
package/lib/teste.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/teste.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const user_1 = require("./user");
|
|
4
|
+
(0, user_1.getUserMiniProfile)("wesbush")
|
|
5
|
+
.then((profile) => {
|
|
6
|
+
console.log("profile: ", profile);
|
|
7
|
+
})
|
|
8
|
+
.catch((error) => {
|
|
9
|
+
console.log("error: ", error);
|
|
10
|
+
});
|