ilml-plugin-linkedin 1.20.6 → 1.20.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/dist/messageBot.mjs +2 -2
- package/dist/version.mjs +1 -1
- package/ilml-plugin.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.20.7
|
|
4
|
+
- **Fixed: `messages --send-batch` crashed instead of sending.** The batch JSON's message body can now be either `text` or `message` — the `--draft-batch` command uses `text`, but `--send-batch` previously required `message` and, if you passed `text`, crashed with an unhelpful "Cannot read properties of undefined" instead of sending. Both batch commands now accept the same shape (`[{ "name": "...", "text": "..." }]`). An entry that's missing its message body is now reported as a clear per-entry error and skipped, instead of aborting the whole batch. No schema change.
|
|
5
|
+
|
|
3
6
|
## 1.20.6
|
|
4
7
|
- **Every command that opens LinkedIn now waits through the ~30-second "signing you back in" screen — not just `apply`, `connect` and `sync`.** 1.20.4–1.20.5 taught those commands to wait through LinkedIn's re-verification screen (the one that shows up when you've recently signed in from another location or device) instead of mistaking it for a logout. This release extends the same handling to the rest of the commands that load a page: `sync-connections`, `viewers`, `read-post`, `enrich --with-experience`, and the profile fallback used when sending a message. Before, these could fail or come back empty during that screen — `sync-connections` in particular looked for a login redirect too early (after about 3 seconds) and then waited only 15, so a slow re-verify looked like "not logged in". Now they all wait up to 45 seconds and only report a session problem if a real login page is still showing afterwards. Under the hood this is now one shared piece of logic rather than the same sequence repeated in each command, so coverage stays consistent as new commands are added. No schema change.
|
|
5
8
|
|
package/dist/messageBot.mjs
CHANGED
|
@@ -81,8 +81,8 @@ Reading conversation with: ${r}
|
|
|
81
81
|
Sending message to: ${s.personName}`),console.log(` Text: "${o.slice(0,150)}${o.length>150?"...":""}"`),n)return console.log(`
|
|
82
82
|
[DRY RUN \u2014 message not sent]`),!1;if(s.profileUrl){if(await eo(e,s.personName,s.profileUrl,o))return!0;console.log(" Direct profile-URL send did not complete \u2014 falling back to name search\u2026")}return await e.goto("https://www.linkedin.com/messaging/",{waitUntil:"domcontentloaded",timeout:6e4}),await E(4e3),et(e,s.personName,s.profileUrl,o)}async function Jn(e,t,o){if(console.log(`
|
|
83
83
|
\u2550\u2550 Batch send: ${t.length} messages \u2550\u2550
|
|
84
|
-
`),o){for(let
|
|
85
|
-
\u2500\u2500 [${i+1}/${t.length}] ${l} \u2500\u2500`);let d=Ze(l);if(!d){console.error(` \u2717 Cannot resolve: ${l}`),n.push({name:l,status:"not_found"});continue}if(!t[i].skipSalutationCheck){let m=Ee(d.personName,c);if(!m.ok){xe(d.personName,m),n.push({name:l,status:"aborted_salutation"});continue}}console.log(` Text: "${c.slice(0,100)}${c.length>100?"...":""}"`);let u=await et(e,d.personName,d.profileUrl,c);n.push({name:l,status:u?"sent":"failed"}),await Zt(e)}console.log(`
|
|
84
|
+
`),o){for(let i of t){let l=i.message??i.text??"";console.log(` [DRY RUN] ${i.name}: "${l.slice(0,80)}..."`)}return}await e.goto("https://www.linkedin.com/messaging/",{waitUntil:"domcontentloaded",timeout:6e4}),await E(4e3);let n=[];for(let i=0;i<t.length;i++){let{name:l}=t[i],c=t[i].message??t[i].text;if(console.log(`
|
|
85
|
+
\u2500\u2500 [${i+1}/${t.length}] ${l} \u2500\u2500`),!c){console.error(` \u2717 No message body for "${l}" \u2014 each entry needs a "text" (or "message") field`),n.push({name:l,status:"no_text"});continue}let d=Ze(l);if(!d){console.error(` \u2717 Cannot resolve: ${l}`),n.push({name:l,status:"not_found"});continue}if(!t[i].skipSalutationCheck){let m=Ee(d.personName,c);if(!m.ok){xe(d.personName,m),n.push({name:l,status:"aborted_salutation"});continue}}console.log(` Text: "${c.slice(0,100)}${c.length>100?"...":""}"`);let u=await et(e,d.personName,d.profileUrl,c);n.push({name:l,status:u?"sent":"failed"}),await Zt(e)}console.log(`
|
|
86
86
|
\u2550\u2550 Batch results \u2550\u2550
|
|
87
87
|
`);let s=n.filter(i=>i.status===$.SENT),r=n.filter(i=>i.status!==$.SENT);for(let i of n){let l=i.status===$.SENT?"\u2713":"\u2717";console.log(` ${l} ${i.name} \u2014 ${i.status}`)}console.log(`
|
|
88
88
|
Total: ${s.length} sent, ${r.length} failed/skipped`)}async function Hn(e,t){let o=M(),n=V(),s=Object.entries(o).filter(([,f])=>Qe(f)),r=s.filter(([,f])=>ze(f)?.status===$.CONFIRMED),i=s.filter(([,f])=>{let a=ze(f)?.status;return a===$.DRAFT||a===$.NEEDS_REVIEW}).length;if(s.length===0){console.log(`
|
package/dist/version.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFileSync as e}from"fs";import{fileURLToPath as r}from"url";function i(){return"1.20.
|
|
1
|
+
import{readFileSync as e}from"fs";import{fileURLToPath as r}from"url";function i(){return"1.20.7";try{let n=new URL("./ilml-plugin.json",import.meta.url);return JSON.parse(e(r(n),"utf-8")).version}catch{return"unknown"}}console.log(`ilml-plugin-linkedin ${i()}`);
|
package/ilml-plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linkedin",
|
|
3
|
-
"version": "1.20.
|
|
3
|
+
"version": "1.20.7",
|
|
4
4
|
"description": "Reference ilml plugin: keep a local mirror of your LinkedIn data with AI-assisted workflows",
|
|
5
5
|
"commands": {
|
|
6
6
|
"help": { "run": "node dist/help.mjs", "description": "List all commands with descriptions; or `help <cmd>` for detailed info on one command (usage, flags, ban-risk, when-to-use). Reads ilml-plugin.json directly.", "usage": "ilml linkedin help [<cmd>]", "useWhen": "You forgot what a command does, or you're an AI agent picking the right tool." },
|
package/package.json
CHANGED