linkedin-api-voyager 1.3.2 → 1.3.4
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/README.md +47 -55
- package/lib/browser.d.ts +9 -0
- package/lib/browser.js +48 -0
- package/lib/config.d.ts +3 -16
- package/lib/config.js +12 -70
- package/lib/teste.js +5 -0
- package/package.json +1 -3
package/README.md
CHANGED
|
@@ -6,45 +6,46 @@ Biblioteca TypeScript para interagir com endpoints internos do LinkedIn (Voyager
|
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install linkedin-api-voyager
|
|
9
|
+
# ou
|
|
10
|
+
yarn add linkedin-api-voyager
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
##
|
|
13
|
+
## Configuração (Obrigatório)
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
**Atenção:** Esta biblioteca deve ser executada **exclusivamente no lado do servidor (Node.js)**. O uso direto no navegador (client-side) resultará em erros de CORS e restrições de segurança.
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
Se você estiver usando em uma aplicação web (React, Vue, etc.), você deve criar uma API ou função intermediária no seu backend para chamar esta biblioteca.
|
|
18
|
+
|
|
19
|
+
### 1. Inicialize o Client
|
|
20
|
+
|
|
21
|
+
No ponto de entrada da sua aplicação backend (ex: `index.ts`, `server.ts`):
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { Client } from "linkedin-api-voyager";
|
|
25
|
+
|
|
26
|
+
// Configure suas credenciais uma única vez
|
|
27
|
+
Client({
|
|
28
|
+
JSESSIONID: process.env.LINKEDIN_JSESSIONID, // ex: "ajax:123456789" (apenas os números se preferir, a lib trata)
|
|
29
|
+
li_at: process.env.LINKEDIN_LI_AT, // ex: "AQEDAR..."
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Onde pegar `li_at` e `JSESSIONID`
|
|
16
34
|
|
|
17
35
|
1. Faça login no LinkedIn pelo navegador.
|
|
18
36
|
2. Abra o DevTools do navegador.
|
|
19
37
|
3. Vá em:
|
|
20
38
|
- Chrome/Edge: `Application` -> `Storage` -> `Cookies` -> `https://www.linkedin.com`
|
|
21
39
|
- Firefox: `Storage` -> `Cookies` -> `https://www.linkedin.com`
|
|
22
|
-
4. Copie os valores
|
|
23
|
-
- `li_at`:
|
|
24
|
-
- `JSESSIONID`:
|
|
25
|
-
- Remova as aspas.
|
|
26
|
-
- Use apenas os números após `ajax:` (ex.: `123456789`).
|
|
27
|
-
|
|
28
|
-
### Salvando cookies em `linkedin_cookies.json`
|
|
29
|
-
|
|
30
|
-
Por padrão, a lib procura o arquivo `linkedin_cookies.json` na raiz do seu projeto.
|
|
31
|
-
|
|
32
|
-
Formato esperado:
|
|
33
|
-
|
|
34
|
-
```json
|
|
35
|
-
{
|
|
36
|
-
"JSESSIONID": "123456789",
|
|
37
|
-
"li_at": "AQEDAR...",
|
|
38
|
-
"timestamp": 1730000000000
|
|
39
|
-
}
|
|
40
|
-
```
|
|
40
|
+
4. Copie os valores:
|
|
41
|
+
- `li_at`: valor completo.
|
|
42
|
+
- `JSESSIONID`: valor completo (ex: `"ajax:123456789"`).
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
> **Nota:** Nunca comite suas credenciais reais no código. Use variáveis de ambiente (`.env`).
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
- Não compartilhe esses cookies e não comite esse arquivo.
|
|
46
|
+
## Exemplos de Uso
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
Após inicializar o `Client`, você pode importar e usar qualquer função diretamente:
|
|
48
49
|
|
|
49
50
|
```ts
|
|
50
51
|
import {
|
|
@@ -55,49 +56,40 @@ import {
|
|
|
55
56
|
getCommentsByPostUrl,
|
|
56
57
|
} from "linkedin-api-voyager";
|
|
57
58
|
|
|
59
|
+
// Exemplo: Buscar perfil
|
|
58
60
|
const profile = await getUserMiniProfile("wesbush");
|
|
61
|
+
console.log(profile);
|
|
62
|
+
|
|
63
|
+
// Exemplo: Buscar experiências
|
|
59
64
|
const experiences = await getProfissionalExperiences("wesbush");
|
|
65
|
+
|
|
66
|
+
// Exemplo: Buscar empresa
|
|
60
67
|
const company = await getCompany("microsoft");
|
|
68
|
+
|
|
69
|
+
// Exemplo: Pesquisar pessoas
|
|
61
70
|
const people = await searchPeople("software engineer");
|
|
71
|
+
|
|
72
|
+
// Exemplo: Buscar comentários
|
|
62
73
|
const comments = await getCommentsByPostUrl(
|
|
63
74
|
"https://www.linkedin.com/feed/update/urn:li:activity-1234567890/",
|
|
64
75
|
);
|
|
65
76
|
```
|
|
66
77
|
|
|
67
|
-
## API
|
|
68
|
-
|
|
69
|
-
O pacote reexporta os módulos listados em `src/index.ts`: `user`, `company`, `posts`, `search`, `utils`, `config`.
|
|
78
|
+
## API
|
|
70
79
|
|
|
71
80
|
### `src/config.ts`
|
|
72
81
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- `COOKIE_FILE_PATH`: caminho padrão do arquivo de cookies (`linkedin_cookies.json`).
|
|
76
|
-
- `API_BASE_URL`: base URL das chamadas Voyager (`https://www.linkedin.com/voyager/api`).
|
|
77
|
-
- `AUTH_BASE_URL`: base URL do LinkedIn (`https://www.linkedin.com`).
|
|
78
|
-
|
|
79
|
-
Funções exportadas:
|
|
80
|
-
|
|
81
|
-
- `saveCookies(JSESSIONID: string, li_at: string): Promise<void>`
|
|
82
|
-
- Salva os cookies no `COOKIE_FILE_PATH`.
|
|
83
|
-
- `loadCookies(): Promise<{ JSESSIONID: string; li_at: string; timestamp: number } | null>`
|
|
84
|
-
- Carrega e valida o arquivo de cookies.
|
|
85
|
-
- `Client(providedCookies?: { JSESSIONID: string; li_at: string }): Promise<AxiosInstance>`
|
|
86
|
-
- Cria um cliente HTTP com headers/cookies.
|
|
87
|
-
- Se existir `linkedin_cookies.json`, usa ele.
|
|
88
|
-
- Se não existir e `providedCookies` for passado, salva e usa.
|
|
89
|
-
- `fetchData(endpoint: string): Promise<any>`
|
|
90
|
-
- Faz um `GET` usando `Client()` e retorna `response.data`.
|
|
91
|
-
|
|
92
|
-
Exemplo (salvar cookies e criar cliente):
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
import { Client, saveCookies } from "linkedin-api-voyager";
|
|
82
|
+
- `Client(config: { JSESSIONID: string; li_at: string })`: Configura a instância global do axios. Deve ser chamado antes de qualquer outra função.
|
|
83
|
+
- `API_BASE_URL`: `https://www.linkedin.com/voyager/api`
|
|
96
84
|
|
|
97
|
-
|
|
98
|
-
const api = await Client();
|
|
85
|
+
### Módulos Disponíveis
|
|
99
86
|
|
|
100
|
-
|
|
87
|
+
A biblioteca exporta funções dos seguintes módulos:
|
|
88
|
+
- `user`: Perfis e dados de usuário.
|
|
89
|
+
- `company`: Dados de empresas.
|
|
90
|
+
- `posts`: Interações com posts e comentários.
|
|
91
|
+
- `search`: Busca de pessoas e empresas.
|
|
92
|
+
- `utils`: Utilitários gerais.
|
|
101
93
|
```
|
|
102
94
|
|
|
103
95
|
### `src/user.ts`
|
package/lib/browser.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./types";
|
|
2
|
+
export * from "./utils";
|
|
3
|
+
export declare const COOKIE_FILE_PATH = "linkedin_cookies.json";
|
|
4
|
+
export declare const API_BASE_URL = "https://www.linkedin.com/voyager/api";
|
|
5
|
+
export declare const AUTH_BASE_URL = "https://www.linkedin.com";
|
|
6
|
+
export declare const saveCookies: () => Promise<never>;
|
|
7
|
+
export declare const loadCookies: () => Promise<never>;
|
|
8
|
+
export declare const Client: () => Promise<never>;
|
|
9
|
+
export declare const fetchData: () => Promise<never>;
|
package/lib/browser.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
17
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
18
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
19
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
20
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
21
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
22
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.fetchData = exports.Client = exports.loadCookies = exports.saveCookies = exports.AUTH_BASE_URL = exports.API_BASE_URL = exports.COOKIE_FILE_PATH = void 0;
|
|
27
|
+
const ERROR_BROWSER_ONLY = "linkedin-api-voyager: este pacote não roda no browser. Use um Route Handler (Next.js) no servidor.";
|
|
28
|
+
__exportStar(require("./types"), exports);
|
|
29
|
+
__exportStar(require("./utils"), exports);
|
|
30
|
+
exports.COOKIE_FILE_PATH = "linkedin_cookies.json";
|
|
31
|
+
exports.API_BASE_URL = "https://www.linkedin.com/voyager/api";
|
|
32
|
+
exports.AUTH_BASE_URL = "https://www.linkedin.com";
|
|
33
|
+
const saveCookies = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
|
+
throw new Error(ERROR_BROWSER_ONLY);
|
|
35
|
+
});
|
|
36
|
+
exports.saveCookies = saveCookies;
|
|
37
|
+
const loadCookies = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
throw new Error(ERROR_BROWSER_ONLY);
|
|
39
|
+
});
|
|
40
|
+
exports.loadCookies = loadCookies;
|
|
41
|
+
const Client = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
|
+
throw new Error(ERROR_BROWSER_ONLY);
|
|
43
|
+
});
|
|
44
|
+
exports.Client = Client;
|
|
45
|
+
const fetchData = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
|
+
throw new Error(ERROR_BROWSER_ONLY);
|
|
47
|
+
});
|
|
48
|
+
exports.fetchData = fetchData;
|
package/lib/config.d.ts
CHANGED
|
@@ -1,20 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
2
|
export declare const API_BASE_URL = "https://www.linkedin.com/voyager/api";
|
|
3
|
-
export declare const
|
|
4
|
-
interface LinkedInCookies {
|
|
3
|
+
export declare const Client: (providedCookies: {
|
|
5
4
|
JSESSIONID: string;
|
|
6
5
|
li_at: string;
|
|
7
|
-
|
|
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;
|
|
6
|
+
}) => AxiosInstance;
|
|
19
7
|
export declare const fetchData: (endpoint: string) => Promise<any>;
|
|
20
|
-
export {};
|
package/lib/config.js
CHANGED
|
@@ -9,86 +9,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.fetchData = exports.Client = exports.
|
|
13
|
-
const fs = require("fs-extra");
|
|
12
|
+
exports.fetchData = exports.Client = exports.API_BASE_URL = void 0;
|
|
14
13
|
const axios_1 = require("axios");
|
|
15
|
-
exports.COOKIE_FILE_PATH = "linkedin_cookies.json";
|
|
16
14
|
exports.API_BASE_URL = "https://www.linkedin.com/voyager/api";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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({
|
|
15
|
+
let apiInstance = null;
|
|
16
|
+
const Client = (providedCookies) => {
|
|
17
|
+
apiInstance = axios_1.default.create({
|
|
80
18
|
baseURL: exports.API_BASE_URL,
|
|
81
19
|
headers: {
|
|
82
20
|
"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
21
|
accept: "application/vnd.linkedin.normalized+json+2.1",
|
|
84
|
-
cookie: `li_at=${li_at}; JSESSIONID="ajax:${JSESSIONID}"`,
|
|
85
|
-
"csrf-token": `ajax:${JSESSIONID}`,
|
|
22
|
+
cookie: `li_at=${providedCookies.li_at}; JSESSIONID="ajax:${providedCookies.JSESSIONID}"`,
|
|
23
|
+
"csrf-token": `ajax:${providedCookies.JSESSIONID}`,
|
|
86
24
|
},
|
|
87
25
|
});
|
|
26
|
+
return apiInstance;
|
|
88
27
|
};
|
|
28
|
+
exports.Client = Client;
|
|
89
29
|
const fetchData = (endpoint) => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
-
|
|
91
|
-
|
|
30
|
+
if (!apiInstance) {
|
|
31
|
+
throw new Error("Client not initialized. Please call Client({ JSESSIONID, li_at }) first.");
|
|
32
|
+
}
|
|
33
|
+
const response = yield apiInstance.get(endpoint);
|
|
92
34
|
return response.data;
|
|
93
35
|
});
|
|
94
36
|
exports.fetchData = fetchData;
|
package/lib/teste.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config_1 = require("./config");
|
|
3
4
|
const user_1 = require("./user");
|
|
5
|
+
(0, config_1.Client)({
|
|
6
|
+
JSESSIONID: "2687703175806319775",
|
|
7
|
+
li_at: "AQEDARgQ7uMA1d5dAAABmm_VFQcAAAGcT-gumU0Agr-WPhYEN-QPXcfx84Ct0mtL2WQqj9YrWiAR2onQlCPyIa9RWXygwj3JKVSY1elRE6DjH4y6nEE5I3NhxBpswfzbRBCIgKUYmKWeEblF1t9VeGDl",
|
|
8
|
+
});
|
|
4
9
|
(0, user_1.getUserMiniProfile)("wesbush")
|
|
5
10
|
.then((profile) => {
|
|
6
11
|
console.log("profile: ", profile);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linkedin-api-voyager",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "Uma biblioteca TypeScript para interagir com a API interna do LinkedIn (Voyager)",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"prepublishOnly": "npm run build"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@types/fs-extra": "^11.0.4",
|
|
19
18
|
"@types/node": "^22.13.1",
|
|
20
19
|
"nodemon": "^3.1.9",
|
|
21
20
|
"ts-node": "^10.9.2",
|
|
@@ -23,7 +22,6 @@
|
|
|
23
22
|
},
|
|
24
23
|
"dependencies": {
|
|
25
24
|
"axios": "^1.11.0",
|
|
26
|
-
"fs-extra": "^11.3.1",
|
|
27
25
|
"path": "^0.12.7"
|
|
28
26
|
}
|
|
29
27
|
}
|