linkedin-agent 1.0.0
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/README.md +119 -0
- package/assets/default-logo.png +0 -0
- package/dist/auth.js +235 -0
- package/dist/browser.js +72 -0
- package/dist/cli.js +514 -0
- package/dist/dev-app.js +422 -0
- package/dist/index.js +12 -0
- package/dist/poster.js +120 -0
- package/dist/scraper.js +256 -0
- package/package.json +47 -0
- package/scripts/postinstall.js +11 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const scraper_1 = require("./scraper");
|
|
40
|
+
const auth_1 = require("./auth");
|
|
41
|
+
const poster_1 = require("./poster");
|
|
42
|
+
const dev_app_1 = require("./dev-app");
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Help
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
function printHelp() {
|
|
47
|
+
console.log(`
|
|
48
|
+
Usage: linkedin-agent <command> [options]
|
|
49
|
+
|
|
50
|
+
LinkedIn 자동화 도구 - 게시글 수집, 작성, 수정, 삭제
|
|
51
|
+
|
|
52
|
+
Commands:
|
|
53
|
+
get 게시글 수집
|
|
54
|
+
post 게시글 작성
|
|
55
|
+
auth OAuth 인증 설정
|
|
56
|
+
edit 게시글 수정
|
|
57
|
+
delete 게시글 삭제
|
|
58
|
+
|
|
59
|
+
Global Options:
|
|
60
|
+
--json JSON 출력 (agent/프로그램 연동용)
|
|
61
|
+
|
|
62
|
+
Run 'linkedin-agent <command> --help' for command-specific options.
|
|
63
|
+
`);
|
|
64
|
+
}
|
|
65
|
+
function printGetHelp() {
|
|
66
|
+
console.log(`
|
|
67
|
+
Usage: linkedin-agent get [options]
|
|
68
|
+
|
|
69
|
+
게시글과 반응 데이터를 수집합니다.
|
|
70
|
+
|
|
71
|
+
Options:
|
|
72
|
+
-p, --profile <url> 대상 프로필 URL (기본: 내 프로필)
|
|
73
|
+
-l, --limit <n> 최근 게시글 N개만 수집
|
|
74
|
+
-o, --output <dir> 출력 디렉토리 (기본: 현재 디렉토리)
|
|
75
|
+
-m, --max-scrolls <n> 최대 스크롤 횟수 (기본: 100)
|
|
76
|
+
-h, --help 도움말 출력
|
|
77
|
+
|
|
78
|
+
Examples:
|
|
79
|
+
linkedin-agent get 내 게시글 수집
|
|
80
|
+
linkedin-agent get -p https://www.linkedin.com/in/someone 특정 프로필 게시글 수집
|
|
81
|
+
linkedin-agent get -l 10 최근 10개만 수집
|
|
82
|
+
`);
|
|
83
|
+
}
|
|
84
|
+
function printPostHelp() {
|
|
85
|
+
console.log(`
|
|
86
|
+
Usage: linkedin-agent post [options]
|
|
87
|
+
|
|
88
|
+
LinkedIn에 새 게시글을 작성합니다.
|
|
89
|
+
|
|
90
|
+
Options:
|
|
91
|
+
-t, --text <text> 게시글 내용
|
|
92
|
+
-f, --file <path> 파일에서 게시글 내용 읽기
|
|
93
|
+
--link <url> 링크 첨부
|
|
94
|
+
--json JSON 출력
|
|
95
|
+
-h, --help 도움말 출력
|
|
96
|
+
|
|
97
|
+
Examples:
|
|
98
|
+
linkedin-agent post -t "오늘의 게시글입니다."
|
|
99
|
+
linkedin-agent post -f ./post.md --json
|
|
100
|
+
linkedin-agent post -t "내용" --link https://example.com
|
|
101
|
+
`);
|
|
102
|
+
}
|
|
103
|
+
function printAuthHelp() {
|
|
104
|
+
console.log(`
|
|
105
|
+
Usage: linkedin-agent auth [options]
|
|
106
|
+
|
|
107
|
+
LinkedIn OAuth 인증을 설정합니다.
|
|
108
|
+
|
|
109
|
+
인자 없이 실행하면 Developer App 자동 생성 → OAuth 인증까지 한번에 진행합니다.
|
|
110
|
+
이미 Developer App이 있다면 --client-id, --client-secret 옵션으로 바로 인증합니다.
|
|
111
|
+
|
|
112
|
+
Options:
|
|
113
|
+
--client-id <id> LinkedIn App Client ID (수동 모드)
|
|
114
|
+
--client-secret <secret> LinkedIn App Client Secret (수동 모드)
|
|
115
|
+
--company-page <url> LinkedIn Company Page URL (자동 모드, 기본: https://www.linkedin.com/company/103290544/)
|
|
116
|
+
-h, --help 도움말 출력
|
|
117
|
+
|
|
118
|
+
Examples:
|
|
119
|
+
linkedin-agent auth 자동: App 생성 + OAuth
|
|
120
|
+
linkedin-agent auth --client-id 86xxx --client-secret WPL_xxx 수동: 기존 App으로 OAuth
|
|
121
|
+
linkedin-agent auth --company-page https://www.linkedin.com/company/12345/
|
|
122
|
+
`);
|
|
123
|
+
}
|
|
124
|
+
function printEditHelp() {
|
|
125
|
+
console.log(`
|
|
126
|
+
Usage: linkedin-agent edit [options]
|
|
127
|
+
|
|
128
|
+
기존 LinkedIn 게시글의 텍스트를 수정합니다.
|
|
129
|
+
(링크, 이미지 등 첨부는 수정 불가 — LinkedIn API 제한)
|
|
130
|
+
|
|
131
|
+
Options:
|
|
132
|
+
--id <post-id> 수정할 게시글 ID (urn:li:share:... 형식)
|
|
133
|
+
-t, --text <text> 새 게시글 내용
|
|
134
|
+
-f, --file <path> 파일에서 새 게시글 내용 읽기
|
|
135
|
+
--json JSON 출력
|
|
136
|
+
-h, --help 도움말 출력
|
|
137
|
+
|
|
138
|
+
Examples:
|
|
139
|
+
linkedin-agent edit --id "urn:li:share:123456" -t "수정된 내용"
|
|
140
|
+
linkedin-agent edit --id "urn:li:share:123456" -f ./updated.md
|
|
141
|
+
`);
|
|
142
|
+
}
|
|
143
|
+
function printDeleteHelp() {
|
|
144
|
+
console.log(`
|
|
145
|
+
Usage: linkedin-agent delete [options]
|
|
146
|
+
|
|
147
|
+
LinkedIn 게시글을 삭제합니다.
|
|
148
|
+
|
|
149
|
+
Options:
|
|
150
|
+
--id <post-id> 삭제할 게시글 ID (urn:li:share:... 형식)
|
|
151
|
+
--json JSON 출력
|
|
152
|
+
-h, --help 도움말 출력
|
|
153
|
+
|
|
154
|
+
Examples:
|
|
155
|
+
linkedin-agent delete --id "urn:li:share:123456"
|
|
156
|
+
`);
|
|
157
|
+
}
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
// JSON output helper
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
function outputResult(result, json, action) {
|
|
162
|
+
if (json) {
|
|
163
|
+
console.log(JSON.stringify(result));
|
|
164
|
+
if (!result.success)
|
|
165
|
+
process.exit(1);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (result.success) {
|
|
169
|
+
switch (action) {
|
|
170
|
+
case "post":
|
|
171
|
+
console.log(`\n✅ Posted successfully!`);
|
|
172
|
+
if (result.postId)
|
|
173
|
+
console.log(` Post ID: ${result.postId}`);
|
|
174
|
+
break;
|
|
175
|
+
case "edit":
|
|
176
|
+
console.log(`\n✅ Post updated successfully!`);
|
|
177
|
+
break;
|
|
178
|
+
case "delete":
|
|
179
|
+
console.log(`\n✅ Post deleted successfully!`);
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
console.error(`\n❌ Failed to ${action}: ${result.error}`);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function fail(message, json) {
|
|
189
|
+
if (json) {
|
|
190
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
console.error(message);
|
|
194
|
+
}
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
// ---------------------------------------------------------------------------
|
|
198
|
+
// Parsers
|
|
199
|
+
// ---------------------------------------------------------------------------
|
|
200
|
+
function parseGetArgs(args) {
|
|
201
|
+
let output = process.cwd();
|
|
202
|
+
let maxScrolls = 100;
|
|
203
|
+
let profile;
|
|
204
|
+
let limit;
|
|
205
|
+
for (let i = 0; i < args.length; i++) {
|
|
206
|
+
switch (args[i]) {
|
|
207
|
+
case "-h":
|
|
208
|
+
case "--help":
|
|
209
|
+
printGetHelp();
|
|
210
|
+
process.exit(0);
|
|
211
|
+
case "-p":
|
|
212
|
+
case "--profile":
|
|
213
|
+
profile = args[++i];
|
|
214
|
+
if (!profile) {
|
|
215
|
+
console.error("Error: --profile requires a LinkedIn profile URL");
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
break;
|
|
219
|
+
case "-l":
|
|
220
|
+
case "--limit":
|
|
221
|
+
limit = parseInt(args[++i], 10);
|
|
222
|
+
if (isNaN(limit) || limit <= 0) {
|
|
223
|
+
console.error("Error: --limit requires a positive number");
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
break;
|
|
227
|
+
case "-o":
|
|
228
|
+
case "--output":
|
|
229
|
+
output = args[++i];
|
|
230
|
+
if (!output) {
|
|
231
|
+
console.error("Error: --output requires a directory path");
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
break;
|
|
235
|
+
case "-m":
|
|
236
|
+
case "--max-scrolls":
|
|
237
|
+
maxScrolls = parseInt(args[++i], 10);
|
|
238
|
+
if (isNaN(maxScrolls) || maxScrolls <= 0) {
|
|
239
|
+
console.error("Error: --max-scrolls requires a positive number");
|
|
240
|
+
process.exit(1);
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
default:
|
|
244
|
+
console.error(`Unknown option: ${args[i]}`);
|
|
245
|
+
printGetHelp();
|
|
246
|
+
process.exit(1);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return { output, maxScrolls, profile, limit };
|
|
250
|
+
}
|
|
251
|
+
function parsePostArgs(args) {
|
|
252
|
+
let text;
|
|
253
|
+
let file;
|
|
254
|
+
let link;
|
|
255
|
+
let json = false;
|
|
256
|
+
for (let i = 0; i < args.length; i++) {
|
|
257
|
+
switch (args[i]) {
|
|
258
|
+
case "-h":
|
|
259
|
+
case "--help":
|
|
260
|
+
printPostHelp();
|
|
261
|
+
process.exit(0);
|
|
262
|
+
case "-t":
|
|
263
|
+
case "--text":
|
|
264
|
+
text = args[++i];
|
|
265
|
+
if (!text) {
|
|
266
|
+
console.error("Error: --text requires content");
|
|
267
|
+
process.exit(1);
|
|
268
|
+
}
|
|
269
|
+
break;
|
|
270
|
+
case "-f":
|
|
271
|
+
case "--file":
|
|
272
|
+
file = args[++i];
|
|
273
|
+
if (!file) {
|
|
274
|
+
console.error("Error: --file requires a file path");
|
|
275
|
+
process.exit(1);
|
|
276
|
+
}
|
|
277
|
+
break;
|
|
278
|
+
case "--link":
|
|
279
|
+
link = args[++i];
|
|
280
|
+
if (!link) {
|
|
281
|
+
console.error("Error: --link requires a URL");
|
|
282
|
+
process.exit(1);
|
|
283
|
+
}
|
|
284
|
+
break;
|
|
285
|
+
case "--json":
|
|
286
|
+
json = true;
|
|
287
|
+
break;
|
|
288
|
+
default:
|
|
289
|
+
console.error(`Unknown option: ${args[i]}`);
|
|
290
|
+
printPostHelp();
|
|
291
|
+
process.exit(1);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return { text, file, link, json };
|
|
295
|
+
}
|
|
296
|
+
function parseAuthArgs(args) {
|
|
297
|
+
let clientId;
|
|
298
|
+
let clientSecret;
|
|
299
|
+
let companyPage;
|
|
300
|
+
for (let i = 0; i < args.length; i++) {
|
|
301
|
+
switch (args[i]) {
|
|
302
|
+
case "-h":
|
|
303
|
+
case "--help":
|
|
304
|
+
printAuthHelp();
|
|
305
|
+
process.exit(0);
|
|
306
|
+
case "--client-id":
|
|
307
|
+
clientId = args[++i];
|
|
308
|
+
if (!clientId) {
|
|
309
|
+
console.error("Error: --client-id requires a value");
|
|
310
|
+
process.exit(1);
|
|
311
|
+
}
|
|
312
|
+
break;
|
|
313
|
+
case "--client-secret":
|
|
314
|
+
clientSecret = args[++i];
|
|
315
|
+
if (!clientSecret) {
|
|
316
|
+
console.error("Error: --client-secret requires a value");
|
|
317
|
+
process.exit(1);
|
|
318
|
+
}
|
|
319
|
+
break;
|
|
320
|
+
case "--company-page":
|
|
321
|
+
companyPage = args[++i];
|
|
322
|
+
if (!companyPage) {
|
|
323
|
+
console.error("Error: --company-page requires a LinkedIn Company Page URL");
|
|
324
|
+
process.exit(1);
|
|
325
|
+
}
|
|
326
|
+
break;
|
|
327
|
+
default:
|
|
328
|
+
console.error(`Unknown option: ${args[i]}`);
|
|
329
|
+
printAuthHelp();
|
|
330
|
+
process.exit(1);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return { clientId, clientSecret, companyPage };
|
|
334
|
+
}
|
|
335
|
+
function parseEditArgs(args) {
|
|
336
|
+
let postId;
|
|
337
|
+
let text;
|
|
338
|
+
let file;
|
|
339
|
+
let json = false;
|
|
340
|
+
for (let i = 0; i < args.length; i++) {
|
|
341
|
+
switch (args[i]) {
|
|
342
|
+
case "-h":
|
|
343
|
+
case "--help":
|
|
344
|
+
printEditHelp();
|
|
345
|
+
process.exit(0);
|
|
346
|
+
case "--id":
|
|
347
|
+
postId = args[++i];
|
|
348
|
+
if (!postId) {
|
|
349
|
+
console.error("Error: --id requires a post ID");
|
|
350
|
+
process.exit(1);
|
|
351
|
+
}
|
|
352
|
+
break;
|
|
353
|
+
case "-t":
|
|
354
|
+
case "--text":
|
|
355
|
+
text = args[++i];
|
|
356
|
+
if (!text) {
|
|
357
|
+
console.error("Error: --text requires content");
|
|
358
|
+
process.exit(1);
|
|
359
|
+
}
|
|
360
|
+
break;
|
|
361
|
+
case "-f":
|
|
362
|
+
case "--file":
|
|
363
|
+
file = args[++i];
|
|
364
|
+
if (!file) {
|
|
365
|
+
console.error("Error: --file requires a file path");
|
|
366
|
+
process.exit(1);
|
|
367
|
+
}
|
|
368
|
+
break;
|
|
369
|
+
case "--json":
|
|
370
|
+
json = true;
|
|
371
|
+
break;
|
|
372
|
+
default:
|
|
373
|
+
console.error(`Unknown option: ${args[i]}`);
|
|
374
|
+
printEditHelp();
|
|
375
|
+
process.exit(1);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return { postId, text, file, json };
|
|
379
|
+
}
|
|
380
|
+
function parseDeleteArgs(args) {
|
|
381
|
+
let postId;
|
|
382
|
+
let json = false;
|
|
383
|
+
for (let i = 0; i < args.length; i++) {
|
|
384
|
+
switch (args[i]) {
|
|
385
|
+
case "-h":
|
|
386
|
+
case "--help":
|
|
387
|
+
printDeleteHelp();
|
|
388
|
+
process.exit(0);
|
|
389
|
+
case "--id":
|
|
390
|
+
postId = args[++i];
|
|
391
|
+
if (!postId) {
|
|
392
|
+
console.error("Error: --id requires a post ID");
|
|
393
|
+
process.exit(1);
|
|
394
|
+
}
|
|
395
|
+
break;
|
|
396
|
+
case "--json":
|
|
397
|
+
json = true;
|
|
398
|
+
break;
|
|
399
|
+
default:
|
|
400
|
+
console.error(`Unknown option: ${args[i]}`);
|
|
401
|
+
printDeleteHelp();
|
|
402
|
+
process.exit(1);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return { postId, json };
|
|
406
|
+
}
|
|
407
|
+
// ---------------------------------------------------------------------------
|
|
408
|
+
// Handlers
|
|
409
|
+
// ---------------------------------------------------------------------------
|
|
410
|
+
async function handleAuth(args) {
|
|
411
|
+
const opts = parseAuthArgs(args);
|
|
412
|
+
if (opts.clientId && opts.clientSecret) {
|
|
413
|
+
await (0, auth_1.authenticate)(opts.clientId, opts.clientSecret);
|
|
414
|
+
console.log("\n✅ Auth successful. Credentials saved.");
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
console.log("\n🚀 Auto-creating LinkedIn Developer App...\n");
|
|
418
|
+
const { launchBrowser } = await Promise.resolve().then(() => __importStar(require("./browser")));
|
|
419
|
+
const logoPath = path.join(__dirname, "..", "assets", "default-logo.png");
|
|
420
|
+
const context = await launchBrowser();
|
|
421
|
+
try {
|
|
422
|
+
const devApp = await (0, dev_app_1.setupDevApp)(context, logoPath, opts.companyPage);
|
|
423
|
+
console.log("🔐 Starting OAuth flow...\n");
|
|
424
|
+
const page = context.pages()[0] || (await context.newPage());
|
|
425
|
+
await (0, auth_1.authenticate)(devApp.clientId, devApp.clientSecret, async (url) => {
|
|
426
|
+
await page.goto(url, { waitUntil: "domcontentloaded" });
|
|
427
|
+
});
|
|
428
|
+
console.log("\n✅ Auth successful. Credentials saved.");
|
|
429
|
+
console.log(` App ID: ${devApp.appId}`);
|
|
430
|
+
console.log(` Client ID: ${devApp.clientId}`);
|
|
431
|
+
}
|
|
432
|
+
finally {
|
|
433
|
+
await context.close();
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
function resolveText(opts, json) {
|
|
437
|
+
if (opts.file) {
|
|
438
|
+
if (!fs.existsSync(opts.file))
|
|
439
|
+
fail(`Error: File not found: ${opts.file}`, json);
|
|
440
|
+
return fs.readFileSync(opts.file, "utf-8").trim();
|
|
441
|
+
}
|
|
442
|
+
if (opts.text)
|
|
443
|
+
return opts.text;
|
|
444
|
+
fail("Error: Provide content with -t or -f.", json);
|
|
445
|
+
}
|
|
446
|
+
async function handlePost(args) {
|
|
447
|
+
const opts = parsePostArgs(args);
|
|
448
|
+
if (!(0, auth_1.loadCredentials)()) {
|
|
449
|
+
fail("❌ Authentication required. Run 'linkedin-agent auth' first.", opts.json);
|
|
450
|
+
}
|
|
451
|
+
const text = resolveText(opts, opts.json);
|
|
452
|
+
if (!opts.json) {
|
|
453
|
+
console.log(`\n📝 Posting to LinkedIn (${text.length} chars)...`);
|
|
454
|
+
if (opts.link)
|
|
455
|
+
console.log(`🔗 Link: ${opts.link}`);
|
|
456
|
+
}
|
|
457
|
+
const result = await (0, poster_1.postToLinkedIn)({ text, linkUrl: opts.link });
|
|
458
|
+
outputResult(result, opts.json, "post");
|
|
459
|
+
}
|
|
460
|
+
async function handleEdit(args) {
|
|
461
|
+
const opts = parseEditArgs(args);
|
|
462
|
+
if (!(0, auth_1.loadCredentials)())
|
|
463
|
+
fail("❌ Authentication required. Run 'linkedin-agent auth' first.", opts.json);
|
|
464
|
+
if (!opts.postId)
|
|
465
|
+
fail("Error: --id is required.", opts.json);
|
|
466
|
+
const text = resolveText(opts, opts.json);
|
|
467
|
+
if (!opts.json)
|
|
468
|
+
console.log(`\n✏️ Editing post ${opts.postId} (${text.length} chars)...`);
|
|
469
|
+
const result = await (0, poster_1.editLinkedInPost)({ postId: opts.postId, text });
|
|
470
|
+
outputResult(result, opts.json, "edit");
|
|
471
|
+
}
|
|
472
|
+
async function handleDelete(args) {
|
|
473
|
+
const opts = parseDeleteArgs(args);
|
|
474
|
+
if (!(0, auth_1.loadCredentials)())
|
|
475
|
+
fail("❌ Authentication required. Run 'linkedin-agent auth' first.", opts.json);
|
|
476
|
+
if (!opts.postId)
|
|
477
|
+
fail("Error: --id is required.", opts.json);
|
|
478
|
+
if (!opts.json)
|
|
479
|
+
console.log(`\n🗑️ Deleting post ${opts.postId}...`);
|
|
480
|
+
const result = await (0, poster_1.deleteLinkedInPost)(opts.postId);
|
|
481
|
+
outputResult(result, opts.json, "delete");
|
|
482
|
+
}
|
|
483
|
+
// ---------------------------------------------------------------------------
|
|
484
|
+
// Main
|
|
485
|
+
// ---------------------------------------------------------------------------
|
|
486
|
+
const command = process.argv[2];
|
|
487
|
+
const commandArgs = process.argv.slice(3);
|
|
488
|
+
switch (command) {
|
|
489
|
+
case "get":
|
|
490
|
+
const getOpts = parseGetArgs(commandArgs);
|
|
491
|
+
(0, scraper_1.getLinkedInPosts)(getOpts).catch((err) => { console.error("❌ Error:", err); process.exit(1); });
|
|
492
|
+
break;
|
|
493
|
+
case "post":
|
|
494
|
+
handlePost(commandArgs).catch((err) => { console.error("❌ Error:", err); process.exit(1); });
|
|
495
|
+
break;
|
|
496
|
+
case "auth":
|
|
497
|
+
handleAuth(commandArgs).catch((err) => { console.error("❌ Error:", err); process.exit(1); });
|
|
498
|
+
break;
|
|
499
|
+
case "edit":
|
|
500
|
+
handleEdit(commandArgs).catch((err) => { console.error("❌ Error:", err); process.exit(1); });
|
|
501
|
+
break;
|
|
502
|
+
case "delete":
|
|
503
|
+
handleDelete(commandArgs).catch((err) => { console.error("❌ Error:", err); process.exit(1); });
|
|
504
|
+
break;
|
|
505
|
+
case "-h":
|
|
506
|
+
case "--help":
|
|
507
|
+
case undefined:
|
|
508
|
+
printHelp();
|
|
509
|
+
break;
|
|
510
|
+
default:
|
|
511
|
+
console.error(`Unknown command: ${command}`);
|
|
512
|
+
printHelp();
|
|
513
|
+
process.exit(1);
|
|
514
|
+
}
|