linkedin-api-voyager
v1.3.5
Published
Uma biblioteca TypeScript para interagir com a API interna do LinkedIn (Voyager)
Readme
LinkedIn API Voyager
Biblioteca TypeScript para interagir com endpoints internos do LinkedIn (Voyager). Esta não é uma API oficial.
Instalação
npm install linkedin-api-voyager
# ou
yarn add linkedin-api-voyagerConfiguração (Obrigatório)
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.
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.
1. Inicialize o Client
No ponto de entrada da sua aplicação backend (ex: index.ts, server.ts):
import { Client } from "linkedin-api-voyager";
// Configure suas credenciais uma única vez
Client({
JSESSIONID: process.env.LINKEDIN_JSESSIONID, // ex: "ajax:123456789" (apenas os números se preferir, a lib trata)
li_at: process.env.LINKEDIN_LI_AT, // ex: "AQEDAR..."
});2. Onde pegar li_at e JSESSIONID
- Faça login no LinkedIn pelo navegador.
- Abra o DevTools do navegador.
- Vá em:
- Chrome/Edge:
Application->Storage->Cookies->https://www.linkedin.com - Firefox:
Storage->Cookies->https://www.linkedin.com
- Chrome/Edge:
- Copie os valores:
li_at: valor completo.JSESSIONID: valor completo (ex:"ajax:123456789").
Nota: Nunca comite suas credenciais reais no código. Use variáveis de ambiente (
.env).
Exemplos de Uso
Após inicializar o Client, você pode importar e usar qualquer função diretamente:
import {
getUserMiniProfile,
getProfissionalExperiences,
getCompany,
searchPeople,
getCommentsByPostUrl,
} from "linkedin-api-voyager";
// Exemplo: Buscar perfil
const profile = await getUserMiniProfile("florymignon");
console.log(profile);
// Exemplo: Buscar experiências
const experiences = await getProfissionalExperiences("florymignon");
// Exemplo: Buscar empresa
const company = await getCompany("microsoft");
// Exemplo: Pesquisar pessoas
const people = await searchPeople("software engineer");
// Exemplo: Buscar comentários
const comments = await getCommentsByPostUrl(
"https://www.linkedin.com/feed/update/urn:li:activity-1234567890/",
);API
src/config.ts
Client(config: { JSESSIONID: string; li_at: string }): Configura a instância global do axios. Deve ser chamado antes de qualquer outra função.API_BASE_URL:https://www.linkedin.com/voyager/api
Módulos Disponíveis
A biblioteca exporta funções dos seguintes módulos:
user: Perfis e dados de usuário.company: Dados de empresas.posts: Interações com posts e comentários.search: Busca de pessoas e empresas.utils: Utilitários gerais.
### `src/user.ts`
Tipos exportados:
- `MiniUserProfileLinkedin`
Funções exportadas:
- `getUserMiniProfile(identifier: string): Promise<MiniUserProfileLinkedin>`
- Busca dados básicos do perfil (nome, headline, imagens) e também o `about`.
- `identifier` é o `publicIdentifier` (parte final da URL `linkedin.com/in/<identifier>`).
- `extractProfileIdLinkedin(profileUrl: string): Promise<string | null>`
- Extrai o `publicIdentifier` de uma URL `linkedin.com/in/...`.
- Se você passar apenas o identificador, ele tenta usar diretamente.
- Retorna o ID numérico interno (sem o prefixo `urn:li:fsd_profile:`) quando encontra.
- `getProfileSectionAbout(identifier: string): Promise<string | null>`
- Retorna o texto de “Sobre” (about) do perfil.
- `getProfissionalExperiences(identifier: string): Promise<Array<any>>`
- Retorna a lista de experiências profissionais.
- Para cada experiência, tenta enriquecer com dados de empresa via `getCompany`.
- `getContactInfo(identifier: string): Promise<{ ... }>`
- Retorna informações de contato quando disponíveis (email, telefones, sites etc.).
- `getLinkedinSkills(identifier: string): Promise<Array<string | null>>`
- Retorna as skills (habilidades) listadas no perfil.
- `getLinkedinEducation(identifier: string): Promise<Array<any>>`
- Retorna a educação (escola, degree, datas, skills relacionadas quando houver).
- `getLinkedinCertifications(identifier: string): Promise<Array<any>>`
- Retorna certificações.
Exemplo:
```ts
import {
getUserMiniProfile,
getProfileSectionAbout,
getProfissionalExperiences,
getContactInfo,
getLinkedinSkills,
getLinkedinEducation,
getLinkedinCertifications,
} from "linkedin-api-voyager";
const identifier = "florymignon";
const mini = await getUserMiniProfile(identifier);
const about = await getProfileSectionAbout(identifier);
const experiences = await getProfissionalExperiences(identifier);
const contact = await getContactInfo(identifier);
const skills = await getLinkedinSkills(identifier);
const education = await getLinkedinEducation(identifier);
const certifications = await getLinkedinCertifications(identifier);src/company.ts
Funções exportadas:
getCompany(identifier: string): Promise<any>- Busca dados de uma empresa pelo
universalName(slug da página). - Exemplo de slug:
https://www.linkedin.com/company/microsoft/->microsoft.
- Busca dados de uma empresa pelo
Exemplo:
import { getCompany } from "linkedin-api-voyager";
const company = await getCompany("microsoft");src/posts.ts
Funções exportadas:
parseResponsePostLinkedin(response: any, key: string, accumulatedData: any): any- Helper para selecionar itens do
includeda partir de*elements.
- Helper para selecionar itens do
getCommentsByPostUrl(url: string, start = 0, limit = 50, accumulatedComments: unknown[] = []): Promise<unknown[]>- Busca comentários de um post (paginando recursivamente até acabar).
getPosts(): Promise<unknown[]>- Atualmente retorna
[](placeholder).
- Atualmente retorna
getPostLinkedin(url: string, commentsCount = 10, likesCount = 10): Promise<any>- Busca um post pelo slug da URL e retorna os dados do post e do autor.
getUserPosts({ identifier, start = 0, count = 50, accumulatedPosts = [] }): Promise<any>- Busca posts do usuário por
identifier(publicIdentifier).
- Busca posts do usuário por
helperGetPosts(response: any, key: string, accumulatedPosts?: any, addFields?: Record<string, string>): any- Helper para extrair posts e contagens (likes, comentários, shares).
helperGetImageUrl(item: any): string- Helper para montar a URL de imagem, priorizando o maior artifact.
Exemplo (comentários):
import { getCommentsByPostUrl } from "linkedin-api-voyager";
const comments = await getCommentsByPostUrl(
"https://www.linkedin.com/feed/update/urn:li:activity-1234567890/",
);src/search.ts
Constantes internas:
MAX_SEARCH_COUNT = 25(limite máximo por chamada na busca geral)
Funções exportadas:
search(params: ISearchParams): Promise<SearchResponse>- Busca geral usando
querye/oufilters(formato Voyager). - Aceita paginação via
offset.
- Busca geral usando
searchPeople(queryOrParams: string | ISearchPeopleParams): Promise<ISearchPeopleResponse>- Busca pessoas com helpers para montar filtros (networkDepth, regiões, empresas etc.).
Exemplo:
import { search, searchPeople } from "linkedin-api-voyager";
const res = await search({ query: "react developer" });
const people = await searchPeople({
query: "engenheiro de software",
regions: ["br:0"],
});src/utils.ts
Funções exportadas (helpers usados em parsing e normalização):
filterKeys(obj: any, keysToKeep: string[]): anyfilterOutKeys(obj: any, keysToIgnore: string[]): anygetNestedValue(obj: any, path: string): anyextractFields(data: any[], fieldsMap: Record<string, string>): any[]debugObjectStructure(obj: any, maxDepth = 3, currentDepth = 0): voidresolveReferences(data: any, included: any[]): anyextractDataWithReferences(elements: string[], included: any[], fieldsMap?: Record<string, string>): any[]debugResolvedStructure(elements: string[], included: any[], maxDepth = 2): voidextractFieldsFromIncluded(included: any[], fields: string[]): Array<Record<string, any>>mergeExtraFields(mainData: any[], extraData: Array<Record<string, any>>, matchKey = "companyUrn"): any[]getDataIncludedForEntity(jsonData: Record<string, any>, entityUrn: string): anyextractExperiences(jsonData: Record<string, any>): Array<{ role: string | null; idCompany: string | null; company: string | null; ... }>assert(value: unknown, message?: string | Error): asserts valuegetIdFromUrn(urn?: string): string | undefinedgetUrnFromRawUpdate(update?: string): string | undefinedisLinkedInUrn(urn?: string): booleanparseExperienceItem(item: any, opts: { isGroupItem?: boolean; included: any[] }): ExperienceItemgetGroupedItemId(item: any): string | undefinedomit(inputObj: object, ...keys: string[]): objectresolveImageUrl(vectorImage?: VectorImage): string | undefinedresolveLinkedVectorImageUrl(linkedVectorImage?: LinkedVectorImage): string | undefinedstringifyLinkedInDate(date?: LIDate): string | undefinednormalizeRawOrganization(o?: RawOrganization): Organization
Exemplo (mapear campos com path aninhado):
import { extractFields } from "linkedin-api-voyager";
const fieldsMap = {
nome: "firstName",
headline: "headline",
foto: "profilePicture.displayImageReferenceResolutionResult.vectorImage.rootUrl",
};
const mapped = extractFields([someObject], fieldsMap);src/types.ts
Este arquivo exporta tipos e interfaces TypeScript usados pela biblioteca (por exemplo: ISearchParams, ISearchPeopleParams, SearchResponse, Organization, ExperienceItem).
Limitações e considerações
- Usa endpoints internos do LinkedIn (Voyager), que podem mudar sem aviso.
- Requer cookies válidos de uma sessão autenticada.
- Use com moderação para reduzir risco de bloqueio.
- Respeite os termos de uso do LinkedIn.
Licença
MIT
