Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 35 additions & 13 deletions src/commands/me.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,34 @@ meCommand
const client = await LinkedInAPIClient.create();
const response = await client.getMe();

// LinkedIn normalized format: profile info in `included` array
const resp = response as any;
const miniProfile = resp.included?.find((item: any) =>
item.$type === 'com.linkedin.voyager.identity.shared.MiniProfile' ||
item.entityUrn?.includes('fs_miniProfile')
) || resp.data?.miniProfile || resp.miniProfile;

const publicId = miniProfile?.publicIdentifier;

// Fetch network info (followers + connections) if we have a public ID
let followersCount: number | null = null;
let connectionsCount: number | null = null;
if (publicId) {
try {
const networkResp = await client.getNetworkInfo(publicId) as any;
followersCount = networkResp.data?.followersCount ?? networkResp.followersCount ?? null;
connectionsCount = networkResp.data?.connectionsCount ?? networkResp.connectionsCount ?? null;
} catch {
// Non-fatal: network info is best-effort
}
}

if (json) {
console.log(JSON.stringify(response, null, 2));
const out: any = { ...resp };
if (followersCount !== null) out.followersCount = followersCount;
if (connectionsCount !== null) out.connectionsCount = connectionsCount;
console.log(JSON.stringify(out, null, 2));
} else {
// LinkedIn normalized format: profile info in `included` array
const resp = response as any;
const miniProfile = resp.included?.find((item: any) =>
item.$type === 'com.linkedin.voyager.identity.shared.MiniProfile' ||
item.entityUrn?.includes('fs_miniProfile')
) || resp.data?.miniProfile || resp.miniProfile;

if (!miniProfile) {
console.log(chalk.yellow('No profile data found'));
return;
Expand All @@ -32,16 +50,20 @@ meCommand
const firstName = miniProfile.firstName || 'Unknown';
const lastName = miniProfile.lastName || '';
const occupation = miniProfile.occupation || resp.data?.occupation || 'No headline';
const publicId = miniProfile.publicIdentifier || 'unknown';

console.log(chalk.blue.bold(`${firstName} ${lastName}`));
console.log(chalk.gray(occupation));

if (followersCount !== null) {
console.log(`Followers: ${chalk.white(followersCount.toLocaleString())}`);
}
if (connectionsCount !== null) {
const connectionsDisplay = connectionsCount >= 500 ? '500+' : String(connectionsCount);
console.log(`Connections: ${chalk.white(connectionsDisplay)}`);
}

console.log();
console.log(`Profile: ${chalk.cyan('https://linkedin.com/in/' + publicId)}`);

if (resp.data?.plainId) {
console.log(`Member ID: ${chalk.gray(resp.data.plainId)}`);
}

const twitter = resp.data?.publicContactInfo?.twitterHandles?.[0]?.name;
if (twitter) {
Expand Down
4 changes: 4 additions & 0 deletions src/lib/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ export class LinkedInAPIClient {
return this.request('/me');
}

async getNetworkInfo(handle: string): Promise<APIResponse> {
return this.request(`/identity/profiles/${handle}/networkinfo`);
}

async getProfile(handle: string): Promise<APIResponse> {
return this.request('/identity/dash/profiles', {
params: {
Expand Down
Loading