{"id":46743477,"url":"https://github.com/lucassantana-dev/linkedin-engage","last_synced_at":"2026-04-25T01:01:36.668Z","repository":{"id":342831660,"uuid":"1175338779","full_name":"LucasSantana-Dev/linkedin-engage","owner":"LucasSantana-Dev","description":"Chrome Extension + Playwright connector for automated LinkedIn networking with personalized notes","archived":false,"fork":false,"pushed_at":"2026-04-24T23:25:46.000Z","size":3237,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-25T00:35:40.049Z","etag":null,"topics":["automation","chrome-extension","chrome-extension-mv3","connection-requests","job-search","latam","linkedin","linkedin-automation","linkedin-bot","networking","playwright","recruiter"],"latest_commit_sha":null,"homepage":"https://github.com/LucasSantana-Dev/linkedin-engage","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LucasSantana-Dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-07T15:20:25.000Z","updated_at":"2026-04-24T23:19:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/LucasSantana-Dev/linkedin-engage","commit_stats":null,"previous_names":["lucassantana-dev/linkedin-auto-connect","lucassantana-dev/linkedin-engage"],"tags_count":75,"template":false,"template_full_name":null,"purl":"pkg:github/LucasSantana-Dev/linkedin-engage","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucasSantana-Dev%2Flinkedin-engage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucasSantana-Dev%2Flinkedin-engage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucasSantana-Dev%2Flinkedin-engage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucasSantana-Dev%2Flinkedin-engage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LucasSantana-Dev","download_url":"https://codeload.github.com/LucasSantana-Dev/linkedin-engage/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucasSantana-Dev%2Flinkedin-engage/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32246406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T13:21:15.438Z","status":"ssl_error","status_checked_at":"2026-04-24T13:21:15.005Z","response_time":64,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","chrome-extension","chrome-extension-mv3","connection-requests","job-search","latam","linkedin","linkedin-automation","linkedin-bot","networking","playwright","recruiter"],"created_at":"2026-03-09T18:21:40.960Z","updated_at":"2026-04-25T01:01:36.579Z","avatar_url":"https://github.com/LucasSantana-Dev.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LinkedIn Engage\n\nA Chrome Extension and standalone Playwright connector for automating LinkedIn networking — connections, company follows, and feed engagement.\n\n## Features\n\n### Chrome Extension\n- **Tag-based search builder** — compose LinkedIn search queries by selecting Role, Industry, Market Focus, and Level tags\n- **Boolean-optimized search templates (v1)** — deterministic template engine\n  for Connect/Companies/Jobs with per-mode goals, expected-result buckets\n  (`precise`, `balanced`, `broad`), and controlled operator budgets\n- **Full EN/PT-BR UI localization** — popup, dashboard, notifications, and runtime status copy now follow a single UI language switch (`Auto`, `English`, `Português (Brasil)`) with no inline bilingual UI labels\n- **Locale-aware search language** — Connect, Companies, and Jobs each have an independent search-language strategy (`auto`, `en`, `pt_BR`, `bilingual`) so generated queries can use local-market or global-language terms without changing the UI locale\n- **Area presets for non-tech networking** — one-click presets for Tech, Finance, Real Estate, Headhunting, Legal/Judicial Media, Environmental, Sanitary, Healthcare, Education, Marketing, Sales, Graphic Design, Art Direction, Branding, UI/UX, Motion Design, Video Editing, and Videomaker\n- **Auto + manual template override** — each search mode supports\n  `Usage Goal`, `Expected Results`, `Template`, and `Auto-select template`\n  controls; scheduled runs reuse the same template resolution logic\n- **Area-aware note templates** — Senior, Mid-Level, Junior, Lead, General Networking, and Custom with role-neutral wording adapted to the selected area\n- **300-char validation** — enforces LinkedIn's invitation note character limit\n- **Smart prioritization** — profiles with mutual connections and closer network degree are processed first\n- **Follow-to-Connect** — handles profiles showing \"Follow\" instead of \"Connect\" by opening the \"More\" menu to find the hidden Connect option\n- **Connect mode follow fallback** — if a profile has only `Follow` and no `Connect` option, Connect mode follows the person instead of skipping\n- **Already-connected suppression** — Connect mode ignores cards marked as `1st`/`1º grau`, preventing attempts on people who are already in your network\n- **Email modal detection** — auto-skips profiles that require email verification (3rd+ degree with no mutuals)\n- **Neutral search defaults** — first load starts without preselected role/industry/market tags so users can choose their own area scope\n- **LATAM recruiter targeting** — Market Focus tags (LATAM, Brazil, Nearshore, Remote) + configurable recruiter region selector\n- **\"Actively Hiring\" filter** — leverages LinkedIn's undocumented `activelyHiring=true` URL parameter\n- **Weekly limit guard** — tracks invites per week (150 max), blocks/adjusts when approaching limit\n- **CAPTCHA detection** — auto-stops on security challenges (checkpoint, captcha, verification pages)\n- **Connection log export** — download CSV of sent/skipped profiles with timestamps\n- **Scheduled runs** — recurring automation via Chrome Alarms API (configurable interval)\n- **Deterministic run outcomes** — every Connect/Feed/Companies/Jobs run emits normalized outcome metadata (`runStatus`, `reason`, `processedCount`, `actionCount`, `skippedCount`)\n- **Consistent stop behavior** — clicking `Stop` now finalizes runs as `canceled` (not success/failure), with stable popup messaging and history diagnostics\n- **Engagement mode** — visit profiles + follow as alternative when connect invites are exhausted; toggle in popup or auto-fallback on quota hit\n- **Company follow mode** — background-managed queue runs one target-company search at a time with resilient re-injection across navigation; each step polls for DOM readiness (up to 20s), differentiates explicit `no results` pages from card-detection timeouts, and emits a single final completion when the full queue finishes; supports creative company-area presets (Graphic Design, Art Direction, Branding, UI/UX, Motion Design, Video Editing, Videomaker) with default query + curated global/Brazil company lists; custom preset keeps LATAM defaults; scheduled recurring runs keep batch rotation only when explicit target companies are set and otherwise run by query; empty target list means follow all results\n- **Companies follow confirmation retries** — each follow click is verified in-card with bounded retries and signal polling (`Following`/`Seguindo`, aria followed state, follow-success toast); `already-following` is only counted on confirmed followed state, while unconfirmed attempts are logged as `skipped-follow-not-confirmed` and zero-follow runs can fail with `follow-not-confirmed`\n- **Jobs assist mode (LinkedIn Easy Apply)** — ranks visible jobs by best-fit signals (title/seniority/location/recency/company), honors the `Jobs Easy Apply Only` toggle, skips already-applied/excluded-company listings, progresses multi-step Easy Apply (`Next/Continue` + `Review`) automatically, and stops before final submit\n- **Encrypted jobs profile cache** — structured applicant fields are stored locally with PBKDF2 + AES-GCM encryption; use `Unlock Cache` with a session passphrase to load cached fields (passphrase is never persisted)\n- **Jobs Career Intelligence** — local-only analysis of uploaded `PDF`/`DOCX` resumes plus an explicit LinkedIn profile import derives best-fit roles, hard-skill keywords, seniority, and search terms; generated Jobs query/filters remain editable\n- **Brazil Offshore Friendly jobs filter** — boosts/filters roles using remote contractor signals (`Brazil`, `LATAM`, `contractor`, `EOR`, `nearshore`, `timezone overlap`) and suppresses listings with explicit international restrictions (`US only`, residency/citizenship requirements, on-site only)\n- **Feed engagement mode** — auto-react and comment on LinkedIn feed posts based on content; smart reaction selection (Celebrate, Support, Insightful, Funny, Love) via keyword matching; scheduled recurring runs\n- **Warmup-first feed learning** — first feed runs (default: 2) run in react+learn mode only (no comments) so thread patterns are learned before comment unlock\n- **Feed warmup controls** — configurable warmup enable/disable, required run count (0-10), live progress indicator, and reset action in popup\n- **Comment signal-aware thread gate** — “never first comment” now uses detected post comment counts (EN/PT labels + compact numbers) instead of only currently visible expanded comments\n- **Thread context hydration** — before commenting, feed can open/load comment thread context (up to 2 batches) to reduce false low-context skips\n- **Goal mode selector** — choose between `Networking \u0026 Visibility` (passive) and `Actively Looking` (more direct) to control hiring-post comment tone across Connect and Feed Engage\n- **Never first-comment safeguard** — comment automation skips posts with zero detected comment signal to avoid starting threads\n- **13 post categories** — hiring, achievement, technical, question, tips, story, news, humor, critique, motivation, project, jobseeking, newjob — each with dedicated comment templates\n- **Smart comment generation** — category-aware follow-ups, post-length awareness (short posts get short comments), `{keyPhrase}` templates only when extractable, `{topic}` auto-detected from post content\n- **Thread-style AI comments** — analyzes existing comments (sentiment, brevity, energy, common openers, emoji/question/exclamation style), extracts thread keywords/phrases, and mirrors the conversation vibe with original wording\n- **Hiring tone safety rails** — hiring posts are forced to hiring category and blocked from humor/irony tone; comments avoid ambiguous or offensive phrasing\n- **Context-aware tone engine** — combines post text, image cues, author title archetype, and reaction intensity/dominant reaction to make comments feel native to each post\n- **PT-BR comments** — auto-detects Portuguese posts and generates conversational PT-BR comments with language-appropriate openers/follow-ups\n- **Duplicate post guard** — persists engaged post URNs across sessions to avoid re-engaging the same posts\n- **429 rate limit backoff** — detects failed sends, exponential backoff (30s, 60s, 120s... up to 5min) after 3 consecutive failures\n- **Invite verification** — 4-layer defense against false positives: button state filtering, InMails modal handling, DOM pending state polling, and network API interception (catches LinkedIn's `FUSE_LIMIT_EXCEEDED` 429 responses)\n- **Quota detection** — stops immediately and notifies when LinkedIn's weekly invitation limit is exhausted\n- **Duplicate detection** — skips profiles already sent in previous runs via persistent URL tracking\n- **Desktop notifications** — Chrome notification when automation completes or stops\n- **Acceptance tracker** — check which sent invitations were accepted (cross-references connections page)\n- **Connect-first progressive popup UX** — core run controls stay visible while `Refine Filters`, `Message`, `Automation`, and `Tools` panels are collapsed by default to reduce setup noise\n- **Dashboard page** — stats overview with weekly/total/accepted counts and connection history log\n- **Tabbed dashboard IA** — dashboard is split into `Overview`, `Activity`, `Feed`, `Nurture`, and `Logs` with persisted active tab state\n- **Multi-query rotation** — scheduled runs cycle through multiple saved queries automatically\n- **Recent profiles** — last 5 connection profiles shown inline in popup with avatar, name, headline, and status badge\n- **Error resilience** — tab load timeout, script injection error handling, tab close detection with notifications\n- **Human timing guardrails** — burst delays never reduce below the 500ms floor, preventing unrealistic timing spikes and test flakiness\n- **Dark mode** — respects system `prefers-color-scheme` with GitHub-inspired dark palette\n- **Activity chart** — 14-day bar chart on dashboard showing daily send volume\n- **Feed analytics** — comment success rate, reaction breakdown chart, top reaction type, skip counts on dashboard\n- **State persistence** — all settings saved via `chrome.storage.local`, survives popup close/reopen\n- **UI layout persistence** — popup accordion states/tag search and dashboard active tab are restored between sessions\n- **Custom query mode** — toggle between tag builder and manual query input\n- **Auto-pagination** — navigates through search result pages automatically\n- **Personalized notes** — extracts first name from invite modal and injects it via `{name}` template variable\n- **Brazilian connect notes in PT-BR** — when profile cues indicate a Brazilian contact, Connect automatically switches the default invite note to Portuguese\n- **PT-BR detection kept in More-menu connect** — when Connect is triggered from the card’s `More` menu, profile context is preserved so Brazilian contacts still receive Portuguese notes\n- **Brazil search language lock** — when Recruiter Location/search geo targets Brazil, Connect enforces PT-BR invitation notes even for English-profile cards\n- **Multi-company exclusion skip** — optional `Excluded Companies` filter skips Connect attempts when a profile headline matches any listed company (one per line)\n- **Open-to-Work recruiter skip** — optional Connect safeguard skips recruiter-like profiles when explicit `Open to Work` signals are present on the card/profile\n- **Job-seeking signal skip** — optional Connect filter skips profiles with explicit job-seeking signals (`actively looking`, `#opentowork`, `buscando oportunidades`, etc.)\n- **Connect relevance scoring** — target ordering now prioritizes recruiter-like profiles, mutual connections, degree proximity, domain fit, and geo context for more precise outreach\n- **Connect ranking runtime stability** — ranked-target logging now uses derived counters, preventing runtime `ReferenceError` interruptions during automation\n- **Skip reason insights** — dashboard shows top skip reasons with counts (`open-to-work`, `same-company`, `duplicate`, etc.) for faster filter tuning\n- **Context-first safe commenting v2** — AI comments now prioritize thread context before post text, enforce non-polemic/non-ironic output, and skip on low-confidence context\n- **Hard comment pattern learning (v3)** — deterministic thread pattern analysis (top 15 comments with recency weighting) extracts opener/length/rhythm/intent/n-gram signals and constrains generation to match thread naturality\n- **Persistent local pattern memory** — stores learned style buckets per `lang|category` in `chrome.storage.local` (`commentPatternMemoryV1`) with bounded EMA/decay maps for openers, n-grams, and intent\n- **Pattern-fit gating + low-signal skip** — comments are skipped when thread pattern signal is weak or generated text breaks dominant thread style constraints\n- **Balanced low-signal recovery** — after warmup, posts with real comment signal can still attempt safe AI/fallback comments even when visible-thread pattern confidence is low\n- **Anti-copy comment hardening** — AI and fallback comments now run deterministic near-duplicate checks against visible thread comments, retry AI once on copy-risk, and skip with explicit `skip-copy-risk` diagnostics when originality is not met\n- **Stranger-distance tone guard (career milestones)** — for `newjob`, `career`, and `achievement`, AI/fallback comments block overpersonal wording (`happy for you`, `orgulho de você`, `muito realizado`), retry AI once with stricter neutral wording, then skip with `skip-distance-risk` when needed\n- **Comment skip telemetry** — feed comment decisions now log `skip-low-confidence`, `skip-safety-guard`, `skip-context-mismatch`, `skip-pattern-low-signal`, `skip-pattern-fit`, `skip-copy-risk`, and `skip-distance-risk` for faster prompt/filter calibration\n\n### Standalone Connector\n- **Playwright-based** — runs a full Chromium browser with persistent login session\n- **Express API** — trigger automation via HTTP POST (`/api/linkedin/connect`)\n- **n8n compatible** — includes workflow JSON for scheduled automation via n8n\n\n## Installation\n\n### Chrome Extension (from source)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eStep-by-step with screenshots\u003c/strong\u003e\u003c/summary\u003e\n\n#### 1. Download the extension\n\n**Option A — Clone the repo:**\n```bash\ngit clone https://github.com/LucasSantana-Dev/linkedin-engage.git\n```\n\n**Option B — Download a release:**\nGo to [Releases](https://github.com/LucasSantana-Dev/linkedin-engage/releases), download the `.zip` file, and extract it.\n\n#### 2. Open Chrome Extensions page\n\nNavigate to `chrome://extensions/` in your Chrome browser.\n\n#### 3. Enable Developer Mode\n\nToggle **Developer mode** in the top-right corner of the extensions page.\n\n#### 4. Load the extension\n\nClick **Load unpacked** and select the `extension/` folder (not the repo root).\n\n\u003e If you downloaded a release zip, select the extracted folder directly.\n\n#### 5. Pin the extension\n\nClick the puzzle icon in Chrome's toolbar and pin **LinkedIn Engage** for easy access.\n\n#### 6. Configure and launch\n\n1. Click the extension icon\n2. Select an Area Preset (optional) and adjust search tags (Role, Industry, Market Focus, Level)\n3. Choose a note template or write a custom message\n4. Set your connection limit and recruiter region\n5. Click **Launch Automation**\n\nThe extension opens a LinkedIn search tab and begins sending connection requests automatically.\n\n\u003c/details\u003e\n\n### Standalone Connector (Playwright)\n\n```bash\ngit clone https://github.com/LucasSantana-Dev/linkedin-engage.git\ncd linkedin-engage\nnpm install\nnode linkedin-connector.js\n```\n\nIn another terminal:\n```bash\ncurl -X POST http://localhost:3000/api/linkedin/connect\n```\n\n\u003e First run opens a browser window for manual LinkedIn login. The session is saved in `linkedin_session/` for subsequent runs.\n\n### n8n Integration\n\nImport `n8n-linkedin-workflow.json` into your n8n instance to schedule automated runs via webhook triggers.\n\n## Architecture\n\n```\nextension/\n  content.js        \u003c- MAIN world automation (connect + engagement)\n  company-follow.js \u003c- MAIN world company follow automation\n  jobs-assist.js    \u003c- MAIN world jobs apply assistant (easy-apply prep, manual submit stop)\n  feed-engage.js    \u003c- MAIN world feed reaction/comment automation\n  bridge.js         \u003c- ISOLATED world messaging bridge (chrome.runtime \u003c-\u003e postMessage)\n  background.js     \u003c- Service worker (tab management, alarms, notifications)\n  lib/\n    invite-utils.js  \u003c- Shared invite/connect utility functions\n    feed-utils.js    \u003c- Shared feed engagement utility functions\n    search-templates.js \u003c- Shared search template schema/compiler/resolver\n    jobs-cache.js    \u003c- Shared encrypted jobs profile cache helpers\n    jobs-career-cache.js \u003c- Shared encrypted jobs intelligence helpers\n    jobs-career-intelligence.js \u003c- Shared deterministic resume/profile analysis + jobs-plan generation\n    jobs-utils.js    \u003c- Shared jobs ranking and skip-rule helpers\n    pattern-memory.js \u003c- Shared pattern-memory bucket merge/guidance helpers\n    feed-warmup.js   \u003c- Shared feed warmup runtime/state helpers\n    company-utils.js \u003c- Shared company follow utility functions\n    ui-layout.js     \u003c- Shared popup/dashboard UI layout state helpers\n  popup/            \u003c- Settings UI (search builder, templates, filters, schedule)\n  options.html      \u003c- Dashboard page (stats, connection history)\n  options.js        \u003c- Dashboard logic\n  manifest.json     \u003c- Chrome MV3 manifest\nlinkedin-connector.js      \u003c- Standalone Playwright version\nn8n-linkedin-workflow.json \u003c- n8n workflow for scheduled runs\n.github/workflows/\n  ci.yml        \u003c- Jest test suite on push/PR to main\n  release.yml   \u003c- Auto-creates GitHub release + zip on version tags\n```\n\n### Key Technical Decisions\n\n**Dual-world injection** — LinkedIn renders invite modals inside `about:blank` iframes. Content scripts in Chrome's default ISOLATED world cannot see these elements. The extension injects `content.js` in MAIN world (shares LinkedIn's JS context) and uses `bridge.js` in ISOLATED world for `chrome.runtime` messaging, connected via `window.postMessage`.\n\n**Chrome-native locale catalogs** — UI copy is stored in `extension/_locales/*/messages.json` and resolved through `extension/lib/i18n.js`. Locale catalog keys stay underscore-only for Chrome/Brave compatibility, while dotted logical keys remain the application-level lookup contract. UI locale is global, while search locale is resolved independently per mode (`Connect`, `Companies`, `Jobs`).\n\n**Cross-document querying** — `getAllDocuments()` collects the main `document` plus all same-origin iframe `contentDocument` objects. All element queries (`findInviteButtons`, `dismissModal`, etc.) search across all documents.\n\n**Direct `aria-label` selectors** — LinkedIn's dense DOM (thousands of elements) makes text-based iteration unreliable. Direct CSS selectors like `button[aria-label=\"Add a note\"]` are exact, fast, and unambiguous.\n\n**React textarea bypass** — LinkedIn uses React's synthetic event system. Setting textarea values requires the native property descriptor setter (`HTMLTextAreaElement.prototype.value.set`) followed by dispatching `input` and `change` events.\n\n**Network-first prioritization** — Profiles are sorted before processing: mutual connections first, then by connection degree (2nd \u003e 3rd+). Email-required modals (3rd+ with no mutuals) are auto-dismissed.\n\n## Search Tips\n\n- LinkedIn basic search supports **one OR group max** — keep queries flat\n- Keep operators explicit and uppercase (`AND`, `OR`, `NOT`) and quote\n  multi-word terms\n- Use the tag builder for most cases; switch to manual for advanced queries\n- Set **Recruiter Location** to where the recruiter IS (US/EU), not where they hire from\n- Add LATAM/Remote/Nearshore market tags to find recruiters who hire from Latin America\n\n## Configuration\n\n| Setting | Default | Description |\n|---------|---------|-------------|\n| UI Language | Auto (Browser) | Extension-owned UI locale for popup, dashboard, notifications, and status copy (`auto`, `en`, `pt_BR`) |\n| Limit | 50 | Max connection requests per run |\n| Region | Global (US/CA/UK/DE/NL) | Geographic filter for search results |\n| Connection Degree | 2nd + 3rd+ | Filter by connection degree (uses LinkedIn `network` param) |\n| Actively Hiring | Off | Only show profiles with hiring badge |\n| Engagement Only | Off | Visit profiles + follow instead of connecting |\n| Send Note | On | Include personalized message |\n| Template | General Networking | Pre-written note template (area-aware) |\n| Weekly Limit | 150 | Max invites per week (auto-enforced) |\n| Schedule | Off | Recurring runs every N hours (Chrome must be open) |\n| Query Rotation | Empty | Multiple queries (one per line) cycled on each scheduled run |\n| Area Preset | Custom | One-click role/industry targeting for 18 supported professional areas |\n| Connect Usage Goal | recruiter_outreach | Template goal for Connect (`recruiter_outreach`, `peer_networking`, `decision_makers`, `brazil_focus`) |\n| Connect Expected Results | balanced | Connect query strictness bucket (`precise`, `balanced`, `broad`) |\n| Connect Search Language | auto | Query language strategy for Connect (`auto`, `en`, `pt_BR`, `bilingual`) |\n| Connect Auto-select Template | On | Uses exact/family/default template fallback for Connect unless manual template is forced |\n| Company Area Preset | Custom | Company-mode preset (`custom` + 7 creative presets) with default company search query and curated target-company defaults |\n| Company Usage Goal | talent_watchlist | Template goal for Companies (`talent_watchlist`, `brand_watchlist`, `competitor_watch`) |\n| Company Expected Results | balanced | Company query strictness bucket (`precise`, `balanced`, `broad`) |\n| Company Search Language | auto | Query language strategy for Companies (`auto`, `en`, `pt_BR`, `bilingual`) |\n| Company Auto-select Template | On | Uses exact/family/default template fallback for Companies unless manual template is forced |\n| Company Query | Empty | Search term for company follow mode |\n| Target Companies | Empty | Empty means follow all results; only explicit names (one per line) activate filtering. `Load defaults` is preset-aware and custom keeps LATAM defaults |\n| Jobs Area Preset | Custom | Optional jobs ranking context preset (reuses area taxonomy from Connect) |\n| Jobs Usage Goal | high_fit_easy_apply | Template goal for Jobs (`high_fit_easy_apply`, `market_scan`, `target_company_roles`) |\n| Jobs Expected Results | balanced | Jobs query strictness bucket (`precise`, `balanced`, `broad`) |\n| Jobs Search Language | auto | Query language strategy for Jobs (`auto`, `en`, `pt_BR`, `bilingual`) with `auto` preferring global English for offshore/international searches and Portuguese for Brazil-local searches |\n| Jobs Auto-select Template | On | Uses exact/family/default template fallback for Jobs unless manual template is forced |\n| Jobs Query | Empty | LinkedIn Jobs keywords query; if empty, inferred from role terms/preset |\n| Jobs Use Career Intelligence | Off | Enables encrypted local resume/profile analysis for Jobs search generation and ranking |\n| Jobs Keyword Terms | Empty | Extra hard-skill/domain keywords used for ranking and generated queries |\n| Jobs Brazil Offshore Friendly | Off | Biases Jobs search/ranking toward remote employers that contract from Brazil/LATAM and filters strong international restrictions |\n| Jobs Easy Apply Only | On | Restricts assistant to LinkedIn Easy Apply opportunities |\n| Jobs Excluded Companies | Empty | Skips job cards whose company matches any excluded entry (one per line) |\n| Jobs Profile Cache | Off | Optional encrypted local cache of structured applicant fields; if configured, Jobs start requires passphrase unlock and supports per-run form-field overrides |\n| Feed React | On | React to feed posts (smart reaction based on content) |\n| Feed Comment | Off | Comment on feed posts using templates |\n| Departure-only Guard | On | If a post only announces leaving a company (no new role in same post), comments stay neutral and non-congratulatory |\n| Enable Warmup Learning | On | For feed mode, force first N runs to react+learn only (no comments) |\n| Warmup Runs Required | 2 | Number of learn-only feed runs before comments unlock (0-10) |\n| Role Terms Limit | 6 | Maximum number of role tags included in the `OR` role query (1-10) to keep results precise |\n| Skip Open to Work Recruiters | On | Skips recruiter-like profiles when explicit Open to Work signals are detected |\n| Skip Job-seeking Signals | Off | Skips explicit job-seeking profiles/signals to reduce low-fit outreach |\n| Goal Mode | Networking \u0026 Visibility | `passive` avoids job-seeking signals; `active` allows stronger hiring-post positioning |\n| Comment Templates | Empty | One template per line; `{topic}` and `{excerpt}` are auto-replaced |\n| Skip Keywords | Empty | Skip posts containing these words (one per line) |\n| Excluded Companies | Empty | If set, skips connecting with profiles whose headline contains any listed company name |\n\n## Troubleshooting Console Noise\n\n- This extension now returns deterministic fallbacks for bridge/runtime callback failures (`bridge-runtime-error`) instead of leaving async channels open.\n- Some console errors are external and not owned by this extension:\n  - `net::ERR_BLOCKED_BY_CLIENT` from ad blockers/privacy extensions\n  - `installHook.js` / vendor framework errors from third-party page scripts\n  - Trusted Types/CSP warnings from page bundles\n  - repeated `chrome-extension://invalid/...` fetch failures from other extensions\n- Non-HTTP(S) fetches are bypassed by invite-status tracking instrumentation, so this extension does not instrument `chrome-extension://` resource checks.\n\n## Releasing\n\nPush a version tag to trigger the release workflow:\n\n```bash\ngit tag v1.0.0\ngit push origin v1.0.0\n```\n\nThis creates a GitHub Release with auto-generated release notes and a downloadable `linkedin-engage-v\u003cversion\u003e.zip` asset.\n\nIf a previous tag release appears without assets, re-upload with:\n```bash\ngh release upload \u003ctag\u003e linkedin-engage-\u003ctag\u003e.zip --clobber\n```\n\nWorkflows currently use `actions/checkout@v6` and `actions/setup-node@v6` for Node 24-ready GitHub Actions runtime compatibility.\n\nCoverage policy is enforced in Jest for shared testable modules (`extension/lib/**`) with release gate minimums of `80%` statements and `80%` lines.\n\n## Disclaimer\n\nThis tool is for personal networking purposes. Use responsibly and in accordance with LinkedIn's Terms of Service. Excessive automation may result in account restrictions. Recommended limits:\n\n- **50-100 requests per day** max\n- **Random delays** between actions (built-in)\n- **Auto-backoff** on rate limits (429) — pauses 30-60s after 3 consecutive failures\n- **Don't run 24/7** — simulate human behavior\n- **Jobs mode requires manual final submit** — review each Easy Apply before submitting\n- **Jobs mode may stop with `manual-input-required`** — complete missing required answers in the open Easy Apply modal; `Continue Manually` now focuses the existing Jobs tab instead of starting a new run\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucassantana-dev%2Flinkedin-engage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucassantana-dev%2Flinkedin-engage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucassantana-dev%2Flinkedin-engage/lists"}