feat(apify): add LinkedIn profile scraping (harvestapi)

Merged
SW
4mo ago
+161-0

Part of recoupable/chat#1833 (platform coverage). Base: main.

Why

LinkedIn was the only one of {YouTube, TikTok, LinkedIn, X, Instagram} unsupported by POST /api/socials/{social_id}/scrape — a linkedin.com profile returned 400 "Unsupported social media platform" (verified live). getSocialPlatformByLink also returned NONE for LinkedIn.

Fix

  • lib/apify/linkedin/startLinkedinProfileScraping.ts → harvestapi/linkedin-profile-scraper (mirrors the tiktok/youtube modules). Ref: https://apify.com/harvestapi/linkedin-profile-scraper (+ harvestapi/linkedin-profile-posts for posts, follow-up).
  • scrapeProfileUrl.ts: dispatch linkedin.com → the new scraper.
  • getSocialPlatformByLink.ts: linkedin.com → LINKEDIN.

Tests (TDD)

  • RED→GREEN getSocialPlatformByLink.test.ts (LINKEDIN) + scrapeProfileUrl.test.ts (dispatches linkedin.com; unsupported → null). tsc + eslint clean.

Follow-ups (noted, not in this PR)

  • Confirm the harvestapi input shape (profiles: [url]) against the actor on the preview.
  • Result persistence — the webhook only routes Instagram actors today; LinkedIn (and TikTok/X/YouTube) results won't persist until the companion persistence PR lands.

🤖 Generated with Claude Code


Summary by cubic

Adds LinkedIn profile scraping via harvestapi/linkedin-profile-scraper. The scrape API now supports LinkedIn; the scraper builds a profile URL from a handle or accepts a full URL and rejects invalid legacy handles.

  • New Features

    • Added startLinkedinProfileScraping using harvestapi/linkedin-profile-scraper.
    • Routed linkedin.com to the LinkedIn scraper and mapped it to LINKEDIN in getSocialPlatformByLink.
    • Added unit tests for routing, platform mapping, actor input, and LinkedIn handle parsing.
  • Bug Fixes

    • Guard against legacy LinkedIn usernames equal to in, company, or school; accept full profile URLs, trim spaces, and ignore a leading @.
    • Use the actor input key urls when starting runs.
    • getUsernameFromProfileUrl now extracts LinkedIn handles from /in, /company, and /school.

Summary by CodeRabbit

  • New Features
    • Added support for LinkedIn profile scraping from profile links or handles.
    • LinkedIn profiles are now recognized as a supported social platform.
  • Bug Fixes
    • Improved input handling by trimming extra spaces and ignoring a leading @ in LinkedIn handles.
    • Added validation to prevent invalid or empty LinkedIn profile inputs from being submitted.
    • Better error handling when a scrape run fails or is aborted.