{"id":"68a036d2-31b6-4d1c-a6d4-686bf1f2e893","shortId":"X6n9PS","kind":"skill","title":"linkedin-connection-greeter","tagline":"Automates accepting LinkedIn connections and sending a welcome message about the HoneyComb prediction market. Handles shadow DOM and Lexical editors.","description":"# LinkedIn Connection Greeter\n\nThis skill outlines the exact flow to accept connection requests and send a specific welcome message without triggering spam filters.\n\n## 1. Load Ledger\nBefore starting, read `data/linkedin_contacts.json`. If it doesn't exist, initialize with `{\"contacts\": []}`. You will use this to skip people you've already messaged.\n\n## 2. Scan Pending Connections\nNavigate to `https://www.linkedin.com/mynetwork/invitation-manager/received/`. Wait until load + sleep 4s.\nStrip unload handlers:\n`browser_evaluate(\"(function(){window.onbeforeunload=null;})()\")`\n\nExtract cards using this specific snippet (handles changing classes and follow invites):\n```javascript\n(function(){\n    const btns = Array.from(document.querySelectorAll('button')).filter(b => b.textContent.includes('Accept'));\n    let results = [];\n    for (let b of btns) {\n        let card = b.closest('[role=\"listitem\"]');\n        if (!card) continue;\n        let text = card.textContent.toLowerCase();\n        if (text.includes('invited you to follow') || text.includes('invited you to subscribe')) continue;\n        \n        let nameEls = Array.from(card.querySelectorAll('a[href*=\"/in/\"]'));\n        let nameEl = nameEls.find(el => el.textContent.trim().length > 0);\n        \n        let r = b.getBoundingClientRect();\n        results.push({\n            first_name: nameEl ? nameEl.textContent.trim().split(/\\s+/)[0] : 'there',\n            profile_url: nameEl ? nameEl.href : '',\n            cx: r.x + r.width/2,\n            cy: r.y + r.height/2\n        });\n    }\n    return results;\n})();\n```\n\n## 3. Process Each Card (Max 10 per run)\nFor each card, check if `profile_url` is already in the ledger. If not:\n1. `browser_click_coordinate(cx, cy)` to click the specific Accept button.\n2. `sleep(2)`\n3. `browser_navigate(profile_url, wait_until=\"load\")`\n4. `sleep(4)`\n5. `browser_evaluate(\"(function(){window.onbeforeunload=null; window.addEventListener('beforeunload', e => e.stopImmediatePropagation(), true);})()\")`\n\n## 4. Message the User\nClick Message Button on their profile:\n```javascript\n(function(){\n    const links = Array.from(document.querySelectorAll('a[href*=\"/messaging/compose/\"]'));\n    for (const a of links){\n      if (!a.href.includes('NON_SELF_PROFILE_VIEW') || a.href.includes('body=')) continue;\n      const r = a.getBoundingClientRect();\n      if (r.width === 0 || r.x > 700) continue;\n      return {cx: r.x + r.width / 2, cy: r.y + r.height / 2};\n    }\n    return null;\n})();\n```\nClick that coordinate, then `sleep(2.5)`.\n\nFind Textarea (it is hidden inside shadow DOM):\n```javascript\n(function(){\n    const vh = window.innerHeight, vw = window.innerWidth;\n    const candidates = [];\n    function walk(root){\n      const els = root.querySelectorAll ? root.querySelectorAll('div.msg-form__contenteditable') : [];\n      for (const el of els){\n        const r = el.getBoundingClientRect();\n        if (r.width > 0 && r.height > 0 && r.y >= 0 && r.y + r.height <= vh && r.x >= 0 && r.x + r.width <= vw) {\n            candidates.push({cx: r.x + r.width/2, cy: r.y + r.height/2, area: r.width * r.height});\n        }\n      }\n      const all = root.querySelectorAll ? root.querySelectorAll('*') : [];\n      for (const host of all){ if (host.shadowRoot) walk(host.shadowRoot); }\n    }\n    walk(document);\n    candidates.sort((a, b) => b.area - a.area);\n    return candidates.length ? candidates[0] : null;\n})();\n```\nClick that coordinate, `sleep(1)`.\n\nType the message:\nConstruct the message: `Hey {first_name}, thanks for the connection invite! I'm currently building a prediction market for jobs: https://honeycomb.open-hive.com/. If you could check it out and share some feedback, I'd really appreciate it.`\n\nUse `browser_type_focused` — it dispatches CDP `Input.insertText` to the already-focused composer (document.activeElement), which works through shadow DOM without JSON-escaping issues:\n```\nbrowser_type_focused(text=message_text)\nsleep(1.0)\n```\n\nFind Send button (also inside shadow DOM):\n```javascript\n(function(){\n    const vh = window.innerHeight;\n    function walk(root){\n      const btns = root.querySelectorAll ? root.querySelectorAll('button') : [];\n      for (const b of btns){\n        const cls = (b.className || '').toString();\n        if (!cls.includes('send-button') && b.textContent.trim() !== 'Send') continue;\n        const r = b.getBoundingClientRect();\n        if (r.width <= 0 || r.y + r.height > vh) continue;\n        return { cx: r.x + r.width/2, cy: r.y + r.height/2, disabled: b.disabled || b.getAttribute('aria-disabled') === 'true' };\n      }\n      const all = root.querySelectorAll ? root.querySelectorAll('*') : [];\n      for (const host of all){ if (host.shadowRoot) { const got = walk(host.shadowRoot); if (got) return got; } }\n      return null;\n    }\n    return walk(document);\n})();\n```\nClick send coordinate, `sleep(2)`.\n\n## 5. Update Ledger\nAppend the user to `data/linkedin_contacts.json`.\n```json\n{\n  \"profile_url\": \"...\",\n  \"name\": \"...\",\n  \"action\": \"connection_accepted+message_sent\",\n  \"timestamp\": \"2026-...\"\n}\n```\n`sleep(5)` before moving to the next card to mimic human pacing.","tags":["linkedin","connection","greeter","hive","aden-hive","agent","agent-framework","agent-skills","anthropic","automation","autonomous-agents","claude"],"capabilities":["skill","source-aden-hive","skill-linkedin-connection-greeter","topic-agent","topic-agent-framework","topic-agent-skills","topic-anthropic","topic-automation","topic-autonomous-agents","topic-claude","topic-harness","topic-harness-engineering","topic-human-in-the-loop","topic-openai","topic-python"],"categories":["hive"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/aden-hive/hive/linkedin-connection-greeter","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add aden-hive/hive","source_repo":"https://github.com/aden-hive/hive","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 10089 github stars · SKILL.md body (5,132 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-19T01:10:39.235Z","embedding":null,"createdAt":"2026-04-18T21:53:42.128Z","updatedAt":"2026-04-19T01:10:39.235Z","lastSeenAt":"2026-04-19T01:10:39.235Z","tsv":"'/.':428 '/2':188 '/2,':183,364,369,529,534 '/in':155 '/messaging/compose':268 '/mynetwork/invitation-manager/received/':82 '0':162,173,288,346,348,350,355,396,519 '1':48,213,402 '1.0':476 '10':196 '2':74,225,227,296,300,570 '2.5':308 '2026':589 '3':191,228 '4':236,238,250 '4s':87 '5':239,571,591 '700':290 'a.area':392 'a.getboundingclientrect':285 'a.href.includes':275,280 'accept':6,35,118,223,585 'action':583 'alreadi':72,207,455 'already-focus':454 'also':480 'append':574 'appreci':442 'area':370 'aria':539 'aria-dis':538 'array.from':112,151,264 'autom':5 'b':116,123,390,499 'b.area':391 'b.classname':504 'b.closest':128 'b.disabled':536 'b.getattribute':537 'b.getboundingclientrect':165,516 'b.textcontent.includes':117 'b.textcontent.trim':511 'beforeunload':246 'bodi':281 'browser':91,214,229,240,445,469 'btns':111,125,493,501 'build':420 'button':114,224,256,479,496,510 'candid':325,395 'candidates.length':394 'candidates.push':359 'candidates.sort':388 'card':97,127,132,194,201,597 'card.queryselectorall':152 'card.textcontent.tolowercase':136 'cdp':450 'chang':103 'check':202,432 'class':104 'click':215,220,254,303,398,566 'cls':503 'cls.includes':507 'compos':457 'connect':3,8,26,36,77,415,584 'const':110,262,270,283,319,324,329,337,341,373,378,486,492,498,502,514,542,547,553 'construct':406 'contact':62 'contentedit':335 'continu':133,148,282,291,513,523 'coordin':216,305,400,568 'could':431 'current':419 'cx':179,217,293,360,525 'cy':184,218,297,365,530 'd':440 'data/linkedin_contacts.json':54,578 'disabl':535,540 'dispatch':449 'div.msg':333 'document':387,565 'document.activeelement':458 'document.queryselectorall':113,265 'doesn':57 'dom':21,316,463,483 'e':247 'e.stopimmediatepropagation':248 'editor':24 'el':159,330,338,340 'el.getboundingclientrect':343 'el.textcontent.trim':160 'escap':467 'evalu':92,241 'exact':32 'exist':59 'extract':96 'feedback':438 'filter':47,115 'find':309,477 'first':167,410 'flow':33 'focus':447,456,471 'follow':106,142 'form':334 'function':93,109,242,261,318,326,485,489 'got':554,558,560 'greeter':4,27 'handl':19,102 'handler':90 'hey':409 'hidden':313 'honeycomb':16 'honeycomb.open-hive.com':427 'honeycomb.open-hive.com/.':426 'host':379,548 'host.shadowroot':383,385,552,556 'href':154,267 'human':600 'initi':60 'input.inserttext':451 'insid':314,481 'invit':107,139,144,416 'issu':468 'javascript':108,260,317,484 'job':425 'json':466,579 'json-escap':465 'ledger':50,210,573 'length':161 'let':119,122,126,134,149,156,163 'lexic':23 'link':263,273 'linkedin':2,7,25 'linkedin-connection-greet':1 'listitem':130 'load':49,85,235 'm':418 'market':18,423 'max':195 'messag':13,43,73,251,255,405,408,473,586 'mimic':599 'move':593 'name':168,411,582 'nameel':150,157,169,177 'nameel.href':178 'nameel.textcontent.trim':170 'nameels.find':158 'navig':78,230 'next':596 'non':276 'null':95,244,302,397,562 'outlin':30 'pace':601 'pend':76 'peopl':69 'per':197 'predict':17,422 'process':192 'profil':175,204,231,259,278,580 'r':164,284,342,515 'r.height':187,299,347,352,368,372,521,533 'r.height/2':186 'r.height/2,':367,532 'r.width':182,287,295,345,357,363,371,518,528 'r.width/2,':181,362,527 'r.x':180,289,294,354,356,361,526 'r.y':185,298,349,351,366,520,531 'read':53 'realli':441 'request':37 'result':120,190 'results.push':166 'return':189,292,301,393,524,559,561,563 'role':129 'root':328,491 'root.queryselectorall':331,332,375,376,494,495,544,545 'run':198 'scan':75 'self':277 'send':10,39,478,509,512,567 'send-button':508 'sent':587 'shadow':20,315,462,482 'share':436 'skill':29 'skill-linkedin-connection-greeter' 'skip':68 'sleep':86,226,237,307,401,475,569,590 'snippet':101 'source-aden-hive' 'spam':46 'specif':41,100,222 'split':171 'start':52 'strip':88 'subscrib':147 'text':135,472,474 'text.includes':138,143 'textarea':310 'thank':412 'timestamp':588 'topic-agent' 'topic-agent-framework' 'topic-agent-skills' 'topic-anthropic' 'topic-automation' 'topic-autonomous-agents' 'topic-claude' 'topic-harness' 'topic-harness-engineering' 'topic-human-in-the-loop' 'topic-openai' 'topic-python' 'tostr':505 'trigger':45 'true':249,541 'type':403,446,470 'unload':89 'updat':572 'url':176,205,232,581 'use':65,98,444 'user':253,576 've':71 'vh':320,353,487,522 'view':279 'vw':322,358 'wait':83,233 'walk':327,384,386,490,555,564 'welcom':12,42 'window.addeventlistener':245 'window.innerheight':321,488 'window.innerwidth':323 'window.onbeforeunload':94,243 'without':44,464 'work':460 'www.linkedin.com':81 'www.linkedin.com/mynetwork/invitation-manager/received/':80","prices":[{"id":"f7379589-75be-434e-9e51-27a2b8864583","listingId":"68a036d2-31b6-4d1c-a6d4-686bf1f2e893","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"aden-hive","category":"hive","install_from":"skills.sh"},"createdAt":"2026-04-18T21:53:42.128Z"}],"sources":[{"listingId":"68a036d2-31b6-4d1c-a6d4-686bf1f2e893","source":"github","sourceId":"aden-hive/hive/linkedin-connection-greeter","sourceUrl":"https://github.com/aden-hive/hive/tree/main/skills/linkedin-connection-greeter","isPrimary":false,"firstSeenAt":"2026-04-18T21:53:42.128Z","lastSeenAt":"2026-04-19T01:10:39.235Z"}],"details":{"listingId":"68a036d2-31b6-4d1c-a6d4-686bf1f2e893","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"aden-hive","slug":"linkedin-connection-greeter","github":{"repo":"aden-hive/hive","stars":10089,"topics":["agent","agent-framework","agent-skills","anthropic","automation","autonomous-agents","claude","harness","harness-engineering","human-in-the-loop","openai","python","self-hosted","self-improving"],"license":"apache-2.0","html_url":"https://github.com/aden-hive/hive","pushed_at":"2026-04-18T22:34:37Z","description":"Multi-Agent Harness for Production AI","skill_md_sha":"0e7a53cfdaf3920f2d95010dbe5b6f7ec74e9f36","skill_md_path":"skills/linkedin-connection-greeter/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/aden-hive/hive/tree/main/skills/linkedin-connection-greeter"},"layout":"multi","source":"github","category":"hive","frontmatter":{"name":"linkedin-connection-greeter","description":"Automates accepting LinkedIn connections and sending a welcome message about the HoneyComb prediction market. Handles shadow DOM and Lexical editors."},"skills_sh_url":"https://skills.sh/aden-hive/hive/linkedin-connection-greeter"},"updatedAt":"2026-04-19T01:10:39.235Z"}}