postiz 2.0.12 → 2.0.14
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 +57 -7
- package/SKILL.md +126 -43
- package/dist/index.js +275 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## Install as a skill
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
npx skills add gitroomhq/postiz-agent
|
|
5
|
+
```
|
|
6
|
+
|
|
1
7
|
# Postiz CLI
|
|
2
8
|
|
|
3
9
|
**Social media automation CLI for AI agents** - Schedule posts across 28+ platforms programmatically.
|
|
@@ -18,9 +24,34 @@ pnpm install -g postiz
|
|
|
18
24
|
|
|
19
25
|
---
|
|
20
26
|
|
|
21
|
-
##
|
|
27
|
+
## Authentication
|
|
28
|
+
|
|
29
|
+
### Option 1: OAuth2 (Recommended)
|
|
30
|
+
|
|
31
|
+
Authenticate using the device flow — no client ID or secret needed:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
postiz auth:login
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This will:
|
|
38
|
+
1. Display a one-time code in your terminal
|
|
39
|
+
2. Open your browser to authorize
|
|
40
|
+
3. Automatically save credentials to `~/.postiz/credentials.json`
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Check current auth status (verifies credentials are still valid)
|
|
44
|
+
postiz auth:status
|
|
45
|
+
|
|
46
|
+
# Remove stored credentials
|
|
47
|
+
postiz auth:logout
|
|
48
|
+
```
|
|
22
49
|
|
|
23
|
-
|
|
50
|
+
#### Self-Hosting the Auth Server
|
|
51
|
+
|
|
52
|
+
By default, `postiz auth:login` uses the hosted auth server at `cli-auth.postiz.com`. If you want to self-host the OAuth2 device flow server, follow the guide in [`server/SERVER.md`](./server/SERVER.md).
|
|
53
|
+
|
|
54
|
+
### Option 2: API Key
|
|
24
55
|
|
|
25
56
|
```bash
|
|
26
57
|
export POSTIZ_API_KEY=your_api_key_here
|
|
@@ -32,6 +63,8 @@ export POSTIZ_API_KEY=your_api_key_here
|
|
|
32
63
|
export POSTIZ_API_URL=https://your-custom-api.com
|
|
33
64
|
```
|
|
34
65
|
|
|
66
|
+
> **Note:** OAuth2 credentials take priority over the API key when both are present.
|
|
67
|
+
|
|
35
68
|
---
|
|
36
69
|
|
|
37
70
|
## Commands
|
|
@@ -149,6 +182,14 @@ Defaults to last 30 days to next 30 days if dates not specified.
|
|
|
149
182
|
postiz posts:delete <post-id>
|
|
150
183
|
```
|
|
151
184
|
|
|
185
|
+
**Change post status (draft ↔ schedule)**
|
|
186
|
+
```bash
|
|
187
|
+
postiz posts:status <post-id> --status draft
|
|
188
|
+
postiz posts:status <post-id> --status schedule
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Move a scheduled post back to a draft, or promote a draft into the publishing queue. Switching to `draft` also terminates any workflow that's already running for the post, so it won't publish. Switching to `schedule` queues the post for publishing at its stored date.
|
|
192
|
+
|
|
152
193
|
---
|
|
153
194
|
|
|
154
195
|
### Analytics
|
|
@@ -526,8 +567,11 @@ The CLI interacts with these Postiz API endpoints:
|
|
|
526
567
|
|
|
527
568
|
| Variable | Required | Default | Description |
|
|
528
569
|
|----------|----------|---------|-------------|
|
|
529
|
-
| `POSTIZ_API_KEY` |
|
|
570
|
+
| `POSTIZ_API_KEY` | No* | - | Your Postiz API key |
|
|
530
571
|
| `POSTIZ_API_URL` | No | `https://api.postiz.com` | Custom API endpoint |
|
|
572
|
+
| `POSTIZ_AUTH_SERVER` | No | `https://cli-auth.postiz.com` | Custom auth server URL |
|
|
573
|
+
|
|
574
|
+
*Either OAuth2 (via `postiz auth:login`) or `POSTIZ_API_KEY` is required.
|
|
531
575
|
|
|
532
576
|
---
|
|
533
577
|
|
|
@@ -542,7 +586,7 @@ The CLI provides clear error messages with exit codes:
|
|
|
542
586
|
|
|
543
587
|
| Error | Solution |
|
|
544
588
|
|-------|----------|
|
|
545
|
-
| `
|
|
589
|
+
| `Not authenticated` | Run `postiz auth:login` or set `POSTIZ_API_KEY` |
|
|
546
590
|
| `Integration not found` | Run `integrations:list` to get valid IDs |
|
|
547
591
|
| `startDate/endDate required` | Use ISO 8601 format: `"2024-12-31T12:00:00Z"` |
|
|
548
592
|
| `Invalid settings` | Check `integrations:settings` for required fields |
|
|
@@ -560,8 +604,9 @@ The CLI provides clear error messages with exit codes:
|
|
|
560
604
|
src/
|
|
561
605
|
├── index.ts # CLI entry point with yargs
|
|
562
606
|
├── api.ts # PostizAPI client class
|
|
563
|
-
├── config.ts #
|
|
607
|
+
├── config.ts # Configuration (OAuth2 + API key)
|
|
564
608
|
└── commands/
|
|
609
|
+
├── auth.ts # OAuth2 authentication (login/logout/status)
|
|
565
610
|
├── posts.ts # Post management commands
|
|
566
611
|
├── integrations.ts # Integration commands
|
|
567
612
|
├── analytics.ts # Analytics commands
|
|
@@ -599,8 +644,11 @@ Output in `dist/`:
|
|
|
599
644
|
## Quick Reference
|
|
600
645
|
|
|
601
646
|
```bash
|
|
602
|
-
#
|
|
603
|
-
|
|
647
|
+
# Authentication
|
|
648
|
+
postiz auth:login # OAuth2 device flow
|
|
649
|
+
postiz auth:status # Check auth
|
|
650
|
+
postiz auth:logout # Remove credentials
|
|
651
|
+
export POSTIZ_API_KEY=your_key # Or use API key
|
|
604
652
|
|
|
605
653
|
# Discovery
|
|
606
654
|
postiz integrations:list # List integrations
|
|
@@ -618,6 +666,8 @@ postiz posts:create --json file.json
|
|
|
618
666
|
# Management
|
|
619
667
|
postiz posts:list # List posts
|
|
620
668
|
postiz posts:delete <id> # Delete post
|
|
669
|
+
postiz posts:status <id> --status draft # Move to draft (stops workflow)
|
|
670
|
+
postiz posts:status <id> --status schedule # Queue draft for publishing
|
|
621
671
|
postiz upload <file> # Upload media
|
|
622
672
|
|
|
623
673
|
# Analytics
|
package/SKILL.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: postiz
|
|
3
3
|
description: Postiz is a tool to schedule social media and chat posts to 28+ channels X, LinkedIn, LinkedIn Page, Reddit, Instagram, Facebook Page, Threads, YouTube, Google My Business, TikTok, Pinterest, Dribbble, Discord, Slack, Kick, Twitch, Mastodon, Bluesky, Lemmy, Farcaster, Telegram, Nostr, VK, Medium, Dev.to, Hashnode, WordPress, ListMonk
|
|
4
4
|
homepage: https://docs.postiz.com/public-api/introduction
|
|
5
|
-
metadata: {"
|
|
5
|
+
metadata: {"openclaw":{"emoji":"🌎","requires":{"bins":[],"env":["POSTIZ_API_URL"]}}}
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
## Install Postiz if it doesn't exist
|
|
@@ -28,36 +28,74 @@ official website: https://postiz.com
|
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
+
## ⚠️ Two Hard Rules (Read First)
|
|
32
|
+
|
|
33
|
+
**Rule 1 — Authenticate before anything.** All commands fail without valid credentials.
|
|
34
|
+
|
|
35
|
+
**Rule 2 — Every file passed to `-m` (or to `image`/media fields in JSON mode) MUST first go through `postiz upload`.** Raw filesystem paths (`image.jpg`, `video.mp4`) and external URLs (`https://example.com/...`) are **NOT** accepted by the publishing pipeline. TikTok, Instagram, YouTube, and most other providers reject anything that isn't a Postiz-verified URL. Always:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
RESULT=$(postiz upload <file>)
|
|
39
|
+
URL=$(echo "$RESULT" | jq -r '.path')
|
|
40
|
+
postiz posts:create ... -m "$URL" ...
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If you see `-m "something.jpg"` anywhere below, treat it as shorthand for "the `.path` you got back from `postiz upload something.jpg`" — never a raw local file.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## ⚠️ Authentication Required
|
|
48
|
+
|
|
49
|
+
**You MUST authenticate before running any Postiz CLI command.** All commands will fail without valid credentials.
|
|
50
|
+
|
|
51
|
+
Before doing anything else, check auth status:
|
|
52
|
+
```bash
|
|
53
|
+
postiz auth:status
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
If not authenticated, either:
|
|
57
|
+
1. **OAuth2:** `postiz auth:login`
|
|
58
|
+
2. **API Key:** `export POSTIZ_API_KEY=your_api_key`
|
|
59
|
+
|
|
60
|
+
**Do NOT proceed with any other commands until authentication is confirmed.**
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
31
64
|
## Core Workflow
|
|
32
65
|
|
|
33
66
|
The fundamental pattern for using Postiz CLI:
|
|
34
67
|
|
|
35
|
-
1. **
|
|
36
|
-
2. **
|
|
37
|
-
3. **
|
|
38
|
-
4. **
|
|
39
|
-
5. **
|
|
40
|
-
6. **
|
|
68
|
+
1. **Authenticate** - Verify or set up authentication (see above)
|
|
69
|
+
2. **Discover** - List integrations and get their settings
|
|
70
|
+
3. **Fetch** - Use integration tools to retrieve dynamic data (flairs, playlists, companies)
|
|
71
|
+
4. **Prepare** - Upload media files if needed
|
|
72
|
+
5. **Post** - Create posts with content, media, and platform-specific settings
|
|
73
|
+
6. **Analyze** - Track performance with platform and post-level analytics
|
|
74
|
+
7. **Resolve** - If analytics returns `{"missing": true}`, run `posts:missing` to list provider content, then `posts:connect` to link it
|
|
41
75
|
|
|
42
76
|
```bash
|
|
43
|
-
# 1.
|
|
77
|
+
# 1. Authenticate
|
|
78
|
+
postiz auth:status
|
|
79
|
+
# If not authenticated: postiz auth:login --client-id <id> --client-secret <secret>
|
|
80
|
+
|
|
81
|
+
# 2. Discover
|
|
44
82
|
postiz integrations:list
|
|
45
83
|
postiz integrations:settings <integration-id>
|
|
46
84
|
|
|
47
|
-
#
|
|
85
|
+
# 3. Fetch (if needed)
|
|
48
86
|
postiz integrations:trigger <integration-id> <method> -d '{"key":"value"}'
|
|
49
87
|
|
|
50
|
-
#
|
|
88
|
+
# 4. Prepare
|
|
51
89
|
postiz upload image.jpg
|
|
52
90
|
|
|
53
|
-
#
|
|
91
|
+
# 5. Post
|
|
54
92
|
postiz posts:create -c "Content" -m "image.jpg" -i "<integration-id>"
|
|
55
93
|
|
|
56
|
-
#
|
|
94
|
+
# 6. Analyze
|
|
57
95
|
postiz analytics:platform <integration-id> -d 30
|
|
58
96
|
postiz analytics:post <post-id> -d 7
|
|
59
97
|
|
|
60
|
-
#
|
|
98
|
+
# 7. Resolve (if analytics returns {"missing": true})
|
|
61
99
|
postiz posts:missing <post-id>
|
|
62
100
|
postiz posts:connect <post-id> --release-id "<content-id>"
|
|
63
101
|
```
|
|
@@ -66,13 +104,29 @@ postiz posts:connect <post-id> --release-id "<content-id>"
|
|
|
66
104
|
|
|
67
105
|
## Essential Commands
|
|
68
106
|
|
|
69
|
-
###
|
|
107
|
+
### Authentication
|
|
70
108
|
|
|
109
|
+
**Option 1: OAuth2 (Recommended)**
|
|
110
|
+
```bash
|
|
111
|
+
# Login via device flow (opens browser, no client ID/secret needed)
|
|
112
|
+
postiz auth:login
|
|
113
|
+
|
|
114
|
+
# Check auth status (verifies credentials are still valid)
|
|
115
|
+
postiz auth:status
|
|
116
|
+
|
|
117
|
+
# Logout (remove stored credentials)
|
|
118
|
+
postiz auth:logout
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Credentials are stored in `~/.postiz/credentials.json`. OAuth2 credentials take priority over API key.
|
|
122
|
+
|
|
123
|
+
**Option 2: API Key**
|
|
71
124
|
```bash
|
|
72
|
-
# Required environment variable
|
|
73
125
|
export POSTIZ_API_KEY=your_api_key_here
|
|
126
|
+
```
|
|
74
127
|
|
|
75
|
-
|
|
128
|
+
**Optional custom API URL:**
|
|
129
|
+
```bash
|
|
76
130
|
export POSTIZ_API_URL=https://custom-api-url.com
|
|
77
131
|
```
|
|
78
132
|
|
|
@@ -99,14 +153,20 @@ postiz posts:create -c "Content" -s "2024-12-31T12:00:00Z" -i "integration-id"
|
|
|
99
153
|
# Draft post
|
|
100
154
|
postiz posts:create -c "Content" -s "2024-12-31T12:00:00Z" -t draft -i "integration-id"
|
|
101
155
|
|
|
102
|
-
# Post with media
|
|
103
|
-
postiz
|
|
156
|
+
# Post with media (upload each file FIRST — see Rule 2)
|
|
157
|
+
IMG1=$(postiz upload img1.jpg | jq -r '.path')
|
|
158
|
+
IMG2=$(postiz upload img2.jpg | jq -r '.path')
|
|
159
|
+
postiz posts:create -c "Content" -m "$IMG1,$IMG2" -s "2024-12-31T12:00:00Z" -i "integration-id"
|
|
104
160
|
|
|
105
|
-
# Post with comments (each with own media)
|
|
161
|
+
# Post with comments (each with own media — every file uploaded first)
|
|
162
|
+
MAIN=$(postiz upload main.jpg | jq -r '.path')
|
|
163
|
+
C1=$(postiz upload comment1.jpg | jq -r '.path')
|
|
164
|
+
C2A=$(postiz upload comment2.jpg | jq -r '.path')
|
|
165
|
+
C2B=$(postiz upload comment3.jpg | jq -r '.path')
|
|
106
166
|
postiz posts:create \
|
|
107
|
-
-c "Main post" -m "
|
|
108
|
-
-c "First comment" -m "
|
|
109
|
-
-c "Second comment" -m "
|
|
167
|
+
-c "Main post" -m "$MAIN" \
|
|
168
|
+
-c "First comment" -m "$C1" \
|
|
169
|
+
-c "Second comment" -m "$C2A,$C2B" \
|
|
110
170
|
-s "2024-12-31T12:00:00Z" \
|
|
111
171
|
-i "integration-id"
|
|
112
172
|
|
|
@@ -135,6 +195,10 @@ postiz posts:list --startDate "2024-01-01T00:00:00Z" --endDate "2024-12-31T23:59
|
|
|
135
195
|
|
|
136
196
|
# Delete post
|
|
137
197
|
postiz posts:delete <post-id>
|
|
198
|
+
|
|
199
|
+
# Change post status (draft ↔ schedule)
|
|
200
|
+
postiz posts:status <post-id> --status draft # Move back to draft, terminates any running publish workflow
|
|
201
|
+
postiz posts:status <post-id> --status schedule # Promote a draft into the publishing queue (uses the post's stored date)
|
|
138
202
|
```
|
|
139
203
|
|
|
140
204
|
### Analytics
|
|
@@ -276,11 +340,17 @@ postiz posts:create \
|
|
|
276
340
|
### Pattern 3: Twitter Thread
|
|
277
341
|
|
|
278
342
|
```bash
|
|
343
|
+
# Upload every image first (Rule 2)
|
|
344
|
+
INTRO=$(postiz upload intro.jpg | jq -r '.path')
|
|
345
|
+
P1=$(postiz upload point1.jpg | jq -r '.path')
|
|
346
|
+
P2=$(postiz upload point2.jpg | jq -r '.path')
|
|
347
|
+
OUTRO=$(postiz upload outro.jpg | jq -r '.path')
|
|
348
|
+
|
|
279
349
|
postiz posts:create \
|
|
280
|
-
-c "🧵 Thread starter (1/4)" -m "
|
|
281
|
-
-c "Point one (2/4)" -m "
|
|
282
|
-
-c "Point two (3/4)" -m "
|
|
283
|
-
-c "Conclusion (4/4)" -m "
|
|
350
|
+
-c "🧵 Thread starter (1/4)" -m "$INTRO" \
|
|
351
|
+
-c "Point one (2/4)" -m "$P1" \
|
|
352
|
+
-c "Point two (3/4)" -m "$P2" \
|
|
353
|
+
-c "Conclusion (4/4)" -m "$OUTRO" \
|
|
284
354
|
-s "2024-12-31T12:00:00Z" \
|
|
285
355
|
-d 2000 \
|
|
286
356
|
-i "twitter-id"
|
|
@@ -299,7 +369,7 @@ cat > campaign.json << 'EOF'
|
|
|
299
369
|
"post": [
|
|
300
370
|
{
|
|
301
371
|
"content": "Short tweet version #tech",
|
|
302
|
-
"image": ["twitter-image.jpg"]
|
|
372
|
+
"image": ["<URL returned by `postiz upload twitter-image.jpg`>"]
|
|
303
373
|
}
|
|
304
374
|
]
|
|
305
375
|
},
|
|
@@ -308,7 +378,7 @@ cat > campaign.json << 'EOF'
|
|
|
308
378
|
"post": [
|
|
309
379
|
{
|
|
310
380
|
"content": "Professional LinkedIn version with more context...",
|
|
311
|
-
"image": ["linkedin-image.jpg"]
|
|
381
|
+
"image": ["<URL returned by `postiz upload linkedin-image.jpg`>"]
|
|
312
382
|
}
|
|
313
383
|
]
|
|
314
384
|
}
|
|
@@ -364,11 +434,13 @@ CONTENT=(
|
|
|
364
434
|
)
|
|
365
435
|
|
|
366
436
|
for i in "${!DATES[@]}"; do
|
|
437
|
+
# Rule 2: upload each file before passing to -m
|
|
438
|
+
IMG=$(postiz upload "post-${i}.jpg" | jq -r '.path')
|
|
367
439
|
postiz posts:create \
|
|
368
440
|
-c "${CONTENT[$i]}" \
|
|
369
441
|
-s "${DATES[$i]}" \
|
|
370
442
|
-i "twitter-id" \
|
|
371
|
-
-m "
|
|
443
|
+
-m "$IMG"
|
|
372
444
|
echo "Scheduled: ${CONTENT[$i]} for ${DATES[$i]}"
|
|
373
445
|
done
|
|
374
446
|
```
|
|
@@ -459,24 +531,30 @@ postiz posts:create -c "Content" -s "2024-12-31T12:00:00Z" --settings '{"subredd
|
|
|
459
531
|
Posts can have comments (threads on Twitter/X, replies elsewhere). Each comment can have its own media:
|
|
460
532
|
|
|
461
533
|
```bash
|
|
462
|
-
#
|
|
534
|
+
# Upload every file first (Rule 2)
|
|
535
|
+
I1=$(postiz upload image1.jpg | jq -r '.path')
|
|
536
|
+
I2=$(postiz upload image2.jpg | jq -r '.path')
|
|
537
|
+
CI=$(postiz upload comment-img.jpg | jq -r '.path')
|
|
538
|
+
A1=$(postiz upload another.jpg | jq -r '.path')
|
|
539
|
+
A2=$(postiz upload more.jpg | jq -r '.path')
|
|
540
|
+
|
|
463
541
|
postiz posts:create \
|
|
464
|
-
-c "Main post" -m "
|
|
465
|
-
-c "Comment 1" -m "
|
|
466
|
-
-c "Comment 2" -m "
|
|
542
|
+
-c "Main post" -m "$I1,$I2" \
|
|
543
|
+
-c "Comment 1" -m "$CI" \
|
|
544
|
+
-c "Comment 2" -m "$A1,$A2" \
|
|
467
545
|
-s "2024-12-31T12:00:00Z" \
|
|
468
546
|
-d 5 \ # Delay between comments in minutes
|
|
469
547
|
-i "integration-id"
|
|
470
548
|
```
|
|
471
549
|
|
|
472
|
-
Internally creates:
|
|
550
|
+
Internally creates (note: every URL is a Postiz-uploaded `.path`, not a raw filename):
|
|
473
551
|
```json
|
|
474
552
|
{
|
|
475
553
|
"posts": [{
|
|
476
554
|
"value": [
|
|
477
|
-
{ "content": "Main post", "image": ["image1
|
|
478
|
-
{ "content": "Comment 1", "image": ["comment-img
|
|
479
|
-
{ "content": "Comment 2", "image": ["another
|
|
555
|
+
{ "content": "Main post", "image": ["<uploaded image1>", "<uploaded image2>"] },
|
|
556
|
+
{ "content": "Comment 1", "image": ["<uploaded comment-img>"], "delay": 5 },
|
|
557
|
+
{ "content": "Comment 2", "image": ["<uploaded another>", "<uploaded more>"], "delay": 5 }
|
|
480
558
|
]
|
|
481
559
|
}]
|
|
482
560
|
}
|
|
@@ -654,10 +732,10 @@ https://clawhub.ai/nevo-david/agent-media
|
|
|
654
732
|
|
|
655
733
|
## Common Gotchas
|
|
656
734
|
|
|
657
|
-
1. **
|
|
735
|
+
1. **Not authenticated** - Run `postiz auth:login` or `export POSTIZ_API_KEY=key` before using CLI
|
|
658
736
|
2. **Invalid integration ID** - Run `integrations:list` to get current IDs
|
|
659
737
|
3. **Settings schema mismatch** - Check `integrations:settings` for required fields
|
|
660
|
-
4. **Media MUST be uploaded to Postiz first** - ⚠️ **CRITICAL:**
|
|
738
|
+
4. **Media MUST be uploaded to Postiz first** - ⚠️ **CRITICAL (Rule 2):** Every value passed to `-m` or to an `image`/media field in JSON mode must be a `.path` returned by `postiz upload`. Raw local filenames (`image.jpg`) and external URLs (`https://...`) will be rejected — TikTok, Instagram, YouTube and most other providers only accept Postiz-verified URLs. No exceptions: even a "quick test post" needs the upload step.
|
|
661
739
|
5. **JSON escaping in shell** - Use single quotes for JSON: `--settings '{...}'`
|
|
662
740
|
6. **Date format** - Must be ISO 8601: `"2024-12-31T12:00:00Z"` and is REQUIRED
|
|
663
741
|
7. **Tool not found** - Check available tools in `integrations:settings` output
|
|
@@ -671,10 +749,13 @@ https://clawhub.ai/nevo-david/agent-media
|
|
|
671
749
|
## Quick Reference
|
|
672
750
|
|
|
673
751
|
```bash
|
|
674
|
-
#
|
|
675
|
-
|
|
752
|
+
# ⚠️ AUTHENTICATE FIRST - required before any other command
|
|
753
|
+
postiz auth:status # Check if authenticated
|
|
754
|
+
postiz auth:login # OAuth2 device flow login
|
|
755
|
+
postiz auth:logout # Remove credentials
|
|
756
|
+
export POSTIZ_API_KEY=key # Or use API key
|
|
676
757
|
|
|
677
|
-
# Discovery
|
|
758
|
+
# Discovery (only after auth is confirmed)
|
|
678
759
|
postiz integrations:list # Get integration IDs
|
|
679
760
|
postiz integrations:settings <id> # Get settings schema
|
|
680
761
|
postiz integrations:trigger <id> <method> -d '{}' # Fetch dynamic data
|
|
@@ -682,7 +763,7 @@ postiz integrations:trigger <id> <method> -d '{}' # Fetch dynamic data
|
|
|
682
763
|
# Posting (date is REQUIRED)
|
|
683
764
|
postiz posts:create -c "text" -s "2024-12-31T12:00:00Z" -i "id" # Simple
|
|
684
765
|
postiz posts:create -c "text" -s "2024-12-31T12:00:00Z" -t draft -i "id" # Draft
|
|
685
|
-
postiz posts:create -c "text" -m "img.jpg" -s "2024-12-31T12:00:00Z" -i "id"
|
|
766
|
+
postiz posts:create -c "text" -m "$(postiz upload img.jpg | jq -r '.path')" -s "2024-12-31T12:00:00Z" -i "id" # With media (upload first — Rule 2)
|
|
686
767
|
postiz posts:create -c "main" -c "comment" -s "2024-12-31T12:00:00Z" -i "id" # With comment
|
|
687
768
|
postiz posts:create -c "text" -s "2024-12-31T12:00:00Z" --settings '{}' -i "id" # Platform-specific
|
|
688
769
|
postiz posts:create --json file.json # Complex
|
|
@@ -690,6 +771,8 @@ postiz posts:create --json file.json
|
|
|
690
771
|
# Management
|
|
691
772
|
postiz posts:list # List posts
|
|
692
773
|
postiz posts:delete <id> # Delete post
|
|
774
|
+
postiz posts:status <id> --status draft # Move to draft (stops workflow)
|
|
775
|
+
postiz posts:status <id> --status schedule # Queue draft for publishing
|
|
693
776
|
postiz upload <file> # Upload media
|
|
694
777
|
|
|
695
778
|
# Analytics
|
package/dist/index.js
CHANGED
|
@@ -162,6 +162,12 @@ var PostizAPI = class {
|
|
|
162
162
|
body: JSON.stringify({ releaseId })
|
|
163
163
|
});
|
|
164
164
|
}
|
|
165
|
+
async changePostStatus(postId, status) {
|
|
166
|
+
return this.request(`/public/v1/posts/${postId}/status`, {
|
|
167
|
+
method: "PUT",
|
|
168
|
+
body: JSON.stringify({ status })
|
|
169
|
+
});
|
|
170
|
+
}
|
|
165
171
|
async getAnalytics(integrationId, date) {
|
|
166
172
|
return this.request(`/public/v1/analytics/${integrationId}?date=${encodeURIComponent(date)}`, {
|
|
167
173
|
method: "GET"
|
|
@@ -190,13 +196,207 @@ var PostizAPI = class {
|
|
|
190
196
|
}
|
|
191
197
|
};
|
|
192
198
|
|
|
199
|
+
// src/commands/auth.ts
|
|
200
|
+
var import_fs = require("fs");
|
|
201
|
+
var import_path = require("path");
|
|
202
|
+
var import_os = require("os");
|
|
203
|
+
var import_node_fetch2 = __toESM(require("node-fetch"));
|
|
204
|
+
var CREDENTIALS_DIR = (0, import_path.join)((0, import_os.homedir)(), ".postiz");
|
|
205
|
+
var CREDENTIALS_FILE = (0, import_path.join)(CREDENTIALS_DIR, "credentials.json");
|
|
206
|
+
var DEFAULT_AUTH_SERVER = "https://cli-auth.postiz.com";
|
|
207
|
+
function loadCredentials() {
|
|
208
|
+
try {
|
|
209
|
+
if (!(0, import_fs.existsSync)(CREDENTIALS_FILE)) return null;
|
|
210
|
+
const data = JSON.parse((0, import_fs.readFileSync)(CREDENTIALS_FILE, "utf-8"));
|
|
211
|
+
if (!data.accessToken) return null;
|
|
212
|
+
return data;
|
|
213
|
+
} catch (e) {
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function saveCredentials(credentials) {
|
|
218
|
+
if (!(0, import_fs.existsSync)(CREDENTIALS_DIR)) {
|
|
219
|
+
(0, import_fs.mkdirSync)(CREDENTIALS_DIR, { recursive: true, mode: 448 });
|
|
220
|
+
}
|
|
221
|
+
(0, import_fs.writeFileSync)(CREDENTIALS_FILE, JSON.stringify(credentials, null, 2), { encoding: "utf-8", mode: 384 });
|
|
222
|
+
(0, import_fs.chmodSync)(CREDENTIALS_FILE, 384);
|
|
223
|
+
}
|
|
224
|
+
function deleteCredentials() {
|
|
225
|
+
if ((0, import_fs.existsSync)(CREDENTIALS_FILE)) {
|
|
226
|
+
(0, import_fs.unlinkSync)(CREDENTIALS_FILE);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function openBrowser(url) {
|
|
230
|
+
const { exec } = require("child_process");
|
|
231
|
+
const platform = process.platform;
|
|
232
|
+
if (platform === "darwin") {
|
|
233
|
+
exec(`open "${url}"`);
|
|
234
|
+
} else if (platform === "win32") {
|
|
235
|
+
exec(`start "" "${url}"`);
|
|
236
|
+
} else {
|
|
237
|
+
exec(`xdg-open "${url}"`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function sleep(ms) {
|
|
241
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
242
|
+
}
|
|
243
|
+
async function authLogin(argv) {
|
|
244
|
+
const authServer = argv.authServer || process.env.POSTIZ_AUTH_SERVER || DEFAULT_AUTH_SERVER;
|
|
245
|
+
console.log("\u{1F510} Starting device authorization flow...\n");
|
|
246
|
+
let deviceCode;
|
|
247
|
+
let userCode;
|
|
248
|
+
let verificationUri;
|
|
249
|
+
let expiresIn;
|
|
250
|
+
let interval;
|
|
251
|
+
try {
|
|
252
|
+
const response = await (0, import_node_fetch2.default)(`${authServer}/device/code`, {
|
|
253
|
+
method: "POST",
|
|
254
|
+
headers: { "Content-Type": "application/json" }
|
|
255
|
+
});
|
|
256
|
+
if (!response.ok) {
|
|
257
|
+
const error = await response.text();
|
|
258
|
+
console.error(`\u274C Failed to start authorization (${response.status}): ${error}`);
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
const data = await response.json();
|
|
262
|
+
deviceCode = data.device_code;
|
|
263
|
+
userCode = data.user_code;
|
|
264
|
+
verificationUri = data.verification_uri;
|
|
265
|
+
expiresIn = data.expires_in;
|
|
266
|
+
interval = data.interval || 5;
|
|
267
|
+
} catch (error) {
|
|
268
|
+
console.error(`\u274C Could not reach auth server at ${authServer}: ${error.message}`);
|
|
269
|
+
process.exit(1);
|
|
270
|
+
}
|
|
271
|
+
console.log(" Your authorization code:\n");
|
|
272
|
+
console.log(` \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510`);
|
|
273
|
+
console.log(` \u2502 ${userCode} \u2502`);
|
|
274
|
+
console.log(` \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
275
|
+
`);
|
|
276
|
+
console.log(` Open this URL and enter the code above:`);
|
|
277
|
+
console.log(` ${verificationUri}
|
|
278
|
+
`);
|
|
279
|
+
openBrowser(`${verificationUri}?code=${encodeURIComponent(userCode)}`);
|
|
280
|
+
console.log(" Waiting for authorization...\n");
|
|
281
|
+
const deadline = Date.now() + expiresIn * 1e3;
|
|
282
|
+
while (Date.now() < deadline) {
|
|
283
|
+
await sleep(interval * 1e3);
|
|
284
|
+
try {
|
|
285
|
+
const response = await (0, import_node_fetch2.default)(`${authServer}/device/token`, {
|
|
286
|
+
method: "POST",
|
|
287
|
+
headers: { "Content-Type": "application/json" },
|
|
288
|
+
body: JSON.stringify({ device_code: deviceCode })
|
|
289
|
+
});
|
|
290
|
+
const data = await response.json();
|
|
291
|
+
if (response.ok && data.access_token) {
|
|
292
|
+
saveCredentials({
|
|
293
|
+
accessToken: data.access_token,
|
|
294
|
+
apiUrl: data.api_url || "https://api.postiz.com",
|
|
295
|
+
organizationId: data.organization_id
|
|
296
|
+
});
|
|
297
|
+
console.log("\u2705 Successfully authenticated!");
|
|
298
|
+
console.log(`\u{1F4C1} Credentials saved to ${CREDENTIALS_FILE}`);
|
|
299
|
+
if (data.organization_id) {
|
|
300
|
+
console.log(`\u{1F3E2} Organization ID: ${data.organization_id}`);
|
|
301
|
+
}
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (data.error === "authorization_pending") {
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
if (data.error === "expired_token") {
|
|
308
|
+
console.error("\u274C Authorization expired. Please try again.");
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
console.error(`\u274C Authorization failed: ${data.error}`);
|
|
312
|
+
process.exit(1);
|
|
313
|
+
} catch (e) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
console.error("\u274C Authorization timed out. Please try again.");
|
|
318
|
+
process.exit(1);
|
|
319
|
+
}
|
|
320
|
+
async function authLogout() {
|
|
321
|
+
const creds = loadCredentials();
|
|
322
|
+
if (!creds) {
|
|
323
|
+
console.log("\u2139\uFE0F No stored credentials found.");
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
deleteCredentials();
|
|
327
|
+
console.log("\u2705 Credentials removed.");
|
|
328
|
+
}
|
|
329
|
+
async function authStatus() {
|
|
330
|
+
const envKey = process.env.POSTIZ_API_KEY;
|
|
331
|
+
const creds = loadCredentials();
|
|
332
|
+
let apiKey;
|
|
333
|
+
let apiUrl;
|
|
334
|
+
if (creds) {
|
|
335
|
+
console.log("\u{1F510} Authentication method: OAuth2");
|
|
336
|
+
console.log(`\u{1F4E1} API URL: ${creds.apiUrl}`);
|
|
337
|
+
console.log(`\u{1F511} Token: ${creds.accessToken.substring(0, 8)}...`);
|
|
338
|
+
if (creds.organizationId) {
|
|
339
|
+
console.log(`\u{1F3E2} Organization: ${creds.organizationId}`);
|
|
340
|
+
}
|
|
341
|
+
console.log(`\u{1F4C1} Credentials file: ${CREDENTIALS_FILE}`);
|
|
342
|
+
apiKey = creds.accessToken;
|
|
343
|
+
apiUrl = creds.apiUrl;
|
|
344
|
+
} else if (envKey) {
|
|
345
|
+
console.log("\u{1F511} Authentication method: API Key (environment variable)");
|
|
346
|
+
console.log(`\u{1F511} Key: ${envKey.substring(0, 8)}...`);
|
|
347
|
+
apiKey = envKey;
|
|
348
|
+
apiUrl = process.env.POSTIZ_API_URL || "https://api.postiz.com";
|
|
349
|
+
} else {
|
|
350
|
+
console.log("\u274C Not authenticated.");
|
|
351
|
+
console.log("\nOptions:");
|
|
352
|
+
console.log(" 1. OAuth2: postiz auth:login");
|
|
353
|
+
console.log(" 2. API Key: export POSTIZ_API_KEY=your_api_key");
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
console.log("\n\u{1F504} Verifying credentials...");
|
|
357
|
+
try {
|
|
358
|
+
const response = await (0, import_node_fetch2.default)(`${apiUrl}/public/v1/integrations`, {
|
|
359
|
+
method: "GET",
|
|
360
|
+
headers: {
|
|
361
|
+
"Content-Type": "application/json",
|
|
362
|
+
Authorization: apiKey
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
if (response.ok) {
|
|
366
|
+
const integrations = await response.json();
|
|
367
|
+
console.log(`\u2705 Credentials are valid. ${integrations.length} integration(s) connected.`);
|
|
368
|
+
} else if (response.status === 401 || response.status === 403) {
|
|
369
|
+
console.log("\u274C Credentials are expired or invalid. Please re-authenticate.");
|
|
370
|
+
if (creds) {
|
|
371
|
+
console.log(" Run: postiz auth:login");
|
|
372
|
+
} else {
|
|
373
|
+
console.log(" Update your POSTIZ_API_KEY environment variable.");
|
|
374
|
+
}
|
|
375
|
+
} else {
|
|
376
|
+
const error = await response.text();
|
|
377
|
+
console.log(`\u26A0\uFE0F Could not verify credentials (HTTP ${response.status}): ${error}`);
|
|
378
|
+
}
|
|
379
|
+
} catch (error) {
|
|
380
|
+
console.log(`\u26A0\uFE0F Could not reach API to verify credentials: ${error.message}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
193
384
|
// src/config.ts
|
|
194
385
|
function getConfig() {
|
|
386
|
+
const creds = loadCredentials();
|
|
387
|
+
if (creds) {
|
|
388
|
+
return {
|
|
389
|
+
apiKey: creds.accessToken,
|
|
390
|
+
apiUrl: creds.apiUrl
|
|
391
|
+
};
|
|
392
|
+
}
|
|
195
393
|
const apiKey = process.env.POSTIZ_API_KEY;
|
|
196
394
|
const apiUrl = process.env.POSTIZ_API_URL;
|
|
197
395
|
if (!apiKey) {
|
|
198
|
-
console.error("\u274C Error:
|
|
199
|
-
console.error("
|
|
396
|
+
console.error("\u274C Error: No authentication found.");
|
|
397
|
+
console.error("Options:");
|
|
398
|
+
console.error(" 1. OAuth2: postiz auth:login --client-id <id> --client-secret <secret>");
|
|
399
|
+
console.error(" 2. API Key: export POSTIZ_API_KEY=your_api_key");
|
|
200
400
|
process.exit(1);
|
|
201
401
|
}
|
|
202
402
|
return {
|
|
@@ -206,7 +406,7 @@ function getConfig() {
|
|
|
206
406
|
}
|
|
207
407
|
|
|
208
408
|
// src/commands/posts.ts
|
|
209
|
-
var
|
|
409
|
+
var import_fs2 = require("fs");
|
|
210
410
|
async function getMissingContent(args) {
|
|
211
411
|
const config = getConfig();
|
|
212
412
|
const api = new PostizAPI(config);
|
|
@@ -251,11 +451,11 @@ async function createPost(args) {
|
|
|
251
451
|
if (args.json) {
|
|
252
452
|
try {
|
|
253
453
|
const jsonPath = args.json;
|
|
254
|
-
if (!(0,
|
|
454
|
+
if (!(0, import_fs2.existsSync)(jsonPath)) {
|
|
255
455
|
console.error(`\u274C JSON file not found: ${jsonPath}`);
|
|
256
456
|
process.exit(1);
|
|
257
457
|
}
|
|
258
|
-
const jsonContent = (0,
|
|
458
|
+
const jsonContent = (0, import_fs2.readFileSync)(jsonPath, "utf-8");
|
|
259
459
|
postData = JSON.parse(jsonContent);
|
|
260
460
|
} catch (error) {
|
|
261
461
|
console.error("\u274C Failed to parse JSON file:", error.message);
|
|
@@ -299,6 +499,7 @@ async function createPost(args) {
|
|
|
299
499
|
postData = {
|
|
300
500
|
type: args.type || "schedule",
|
|
301
501
|
// 'schedule' or 'draft'
|
|
502
|
+
creationMethod: "CLI",
|
|
302
503
|
date: args.date,
|
|
303
504
|
// Required date field
|
|
304
505
|
shortLink: args.shortLink !== false,
|
|
@@ -344,6 +545,27 @@ async function listPosts(args) {
|
|
|
344
545
|
process.exit(1);
|
|
345
546
|
}
|
|
346
547
|
}
|
|
548
|
+
async function changePostStatus(args) {
|
|
549
|
+
const config = getConfig();
|
|
550
|
+
const api = new PostizAPI(config);
|
|
551
|
+
if (!args.id) {
|
|
552
|
+
console.error("\u274C Post ID is required");
|
|
553
|
+
process.exit(1);
|
|
554
|
+
}
|
|
555
|
+
if (args.status !== "draft" && args.status !== "schedule") {
|
|
556
|
+
console.error('\u274C --status must be either "draft" or "schedule"');
|
|
557
|
+
process.exit(1);
|
|
558
|
+
}
|
|
559
|
+
try {
|
|
560
|
+
const result = await api.changePostStatus(args.id, args.status);
|
|
561
|
+
console.log(`\u2705 Post ${args.id} status changed to ${args.status}`);
|
|
562
|
+
console.log(JSON.stringify(result, null, 2));
|
|
563
|
+
return result;
|
|
564
|
+
} catch (error) {
|
|
565
|
+
console.error("\u274C Failed to change post status:", error.message);
|
|
566
|
+
process.exit(1);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
347
569
|
async function deletePost(args) {
|
|
348
570
|
const config = getConfig();
|
|
349
571
|
const api = new PostizAPI(config);
|
|
@@ -461,7 +683,7 @@ async function getPostAnalytics(args) {
|
|
|
461
683
|
}
|
|
462
684
|
|
|
463
685
|
// src/commands/upload.ts
|
|
464
|
-
var
|
|
686
|
+
var import_fs3 = require("fs");
|
|
465
687
|
async function uploadFile(args) {
|
|
466
688
|
const config = getConfig();
|
|
467
689
|
const api = new PostizAPI(config);
|
|
@@ -470,7 +692,7 @@ async function uploadFile(args) {
|
|
|
470
692
|
process.exit(1);
|
|
471
693
|
}
|
|
472
694
|
try {
|
|
473
|
-
const fileBuffer = (0,
|
|
695
|
+
const fileBuffer = (0, import_fs3.readFileSync)(args.file);
|
|
474
696
|
const filename = args.file.split("/").pop() || "file";
|
|
475
697
|
const result = await api.upload(fileBuffer, filename);
|
|
476
698
|
console.log("\u2705 File uploaded successfully!");
|
|
@@ -614,6 +836,28 @@ async function uploadFile(args) {
|
|
|
614
836
|
);
|
|
615
837
|
},
|
|
616
838
|
getMissingContent
|
|
839
|
+
).command(
|
|
840
|
+
"posts:status <id>",
|
|
841
|
+
"Change a post status between draft and schedule",
|
|
842
|
+
(yargs2) => {
|
|
843
|
+
return yargs2.positional("id", {
|
|
844
|
+
describe: "Post ID",
|
|
845
|
+
type: "string"
|
|
846
|
+
}).option("status", {
|
|
847
|
+
alias: "s",
|
|
848
|
+
describe: 'New status: "draft" or "schedule"',
|
|
849
|
+
type: "string",
|
|
850
|
+
choices: ["draft", "schedule"],
|
|
851
|
+
demandOption: true
|
|
852
|
+
}).example(
|
|
853
|
+
"$0 posts:status post-123 --status draft",
|
|
854
|
+
"Move a scheduled post back to draft (stops the running workflow)"
|
|
855
|
+
).example(
|
|
856
|
+
"$0 posts:status post-123 --status schedule",
|
|
857
|
+
"Schedule a draft post so it is queued for publishing"
|
|
858
|
+
);
|
|
859
|
+
},
|
|
860
|
+
changePostStatus
|
|
617
861
|
).command(
|
|
618
862
|
"posts:connect <id>",
|
|
619
863
|
"Connect a post to its published content by updating the release ID",
|
|
@@ -730,7 +974,30 @@ async function uploadFile(args) {
|
|
|
730
974
|
}).example("$0 upload ./image.png", "Upload an image");
|
|
731
975
|
},
|
|
732
976
|
uploadFile
|
|
977
|
+
).command(
|
|
978
|
+
"auth:login",
|
|
979
|
+
"Authenticate using OAuth2 (device flow)",
|
|
980
|
+
(yargs2) => {
|
|
981
|
+
return yargs2.option("auth-server", {
|
|
982
|
+
describe: "Auth server URL (default: https://cli-auth.postiz.com)",
|
|
983
|
+
type: "string"
|
|
984
|
+
}).example(
|
|
985
|
+
"$0 auth:login",
|
|
986
|
+
"Login via OAuth2 device flow"
|
|
987
|
+
);
|
|
988
|
+
},
|
|
989
|
+
authLogin
|
|
990
|
+
).command(
|
|
991
|
+
"auth:logout",
|
|
992
|
+
"Remove stored OAuth2 credentials",
|
|
993
|
+
{},
|
|
994
|
+
authLogout
|
|
995
|
+
).command(
|
|
996
|
+
"auth:status",
|
|
997
|
+
"Show current authentication status",
|
|
998
|
+
{},
|
|
999
|
+
authStatus
|
|
733
1000
|
).demandCommand(1, "You need at least one command").help().alias("h", "help").version().alias("v", "version").epilogue(
|
|
734
|
-
"For more information, visit: https://postiz.com\n\
|
|
1001
|
+
"For more information, visit: https://postiz.com\n\nAuthentication:\n OAuth2: postiz auth:login\n API Key: export POSTIZ_API_KEY=your_api_key\n\n\u{1F4FD}\uFE0F Recommendation: Use agent-media to generate AI videos & images (Kling, Veo, Sora, Seedance, Flux, Grok) and post them directly with Postiz.\n Install: npm install -g agent-media-cli\n Learn more: https://agent-media.ai"
|
|
735
1002
|
).parse();
|
|
736
1003
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/api.ts","../src/config.ts","../src/commands/posts.ts","../src/commands/integrations.ts","../src/commands/analytics.ts","../src/commands/upload.ts"],"sourcesContent":["import yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport { createPost, listPosts, deletePost, getMissingContent, connectPost } from './commands/posts';\nimport { listIntegrations, getIntegrationSettings, triggerIntegrationTool } from './commands/integrations';\nimport { getAnalytics, getPostAnalytics } from './commands/analytics';\nimport { uploadFile } from './commands/upload';\nimport type { Argv } from 'yargs';\n\nyargs(hideBin(process.argv))\n .scriptName('postiz')\n .usage('$0 <command> [options]')\n .command(\n 'posts:create',\n 'Create a new post',\n (yargs: Argv) => {\n return yargs\n .option('content', {\n alias: 'c',\n describe: 'Post/comment content (can be used multiple times)',\n type: 'string',\n })\n .option('media', {\n alias: 'm',\n describe: 'Comma-separated media URLs for the corresponding -c (can be used multiple times)',\n type: 'string',\n })\n .option('integrations', {\n alias: 'i',\n describe: 'Comma-separated list of integration IDs',\n type: 'string',\n })\n .option('date', {\n alias: 's',\n describe: 'Schedule date (ISO 8601 format) - REQUIRED',\n type: 'string',\n })\n .option('type', {\n alias: 't',\n describe: 'Post type: \"schedule\" or \"draft\"',\n type: 'string',\n choices: ['schedule', 'draft'],\n default: 'schedule',\n })\n .option('delay', {\n alias: 'd',\n describe: 'Delay in minutes between comments (default: 0)',\n type: 'number',\n default: 0,\n })\n .option('json', {\n alias: 'j',\n describe: 'Path to JSON file with full post structure',\n type: 'string',\n })\n .option('shortLink', {\n describe: 'Use short links',\n type: 'boolean',\n default: true,\n })\n .option('settings', {\n describe: 'Platform-specific settings as JSON string',\n type: 'string',\n })\n .check((argv) => {\n if (!argv.json && !argv.content) {\n throw new Error('Either --content or --json is required');\n }\n if (!argv.json && !argv.integrations) {\n throw new Error('--integrations is required when not using --json');\n }\n if (!argv.json && !argv.date) {\n throw new Error('--date is required when not using --json');\n }\n return true;\n })\n .example(\n '$0 posts:create -c \"Hello World!\" -s \"2024-12-31T12:00:00Z\" -i \"twitter-123\"',\n 'Simple scheduled post'\n )\n .example(\n '$0 posts:create -c \"Draft post\" -s \"2024-12-31T12:00:00Z\" -t draft -i \"twitter-123\"',\n 'Create draft post'\n )\n .example(\n '$0 posts:create -c \"Main post\" -m \"img1.jpg,img2.jpg\" -s \"2024-12-31T12:00:00Z\" -i \"twitter-123\"',\n 'Post with multiple images'\n )\n .example(\n '$0 posts:create -c \"Main post\" -m \"img1.jpg\" -c \"First comment\" -m \"img2.jpg\" -c \"Second comment\" -m \"img3.jpg,img4.jpg\" -s \"2024-12-31T12:00:00Z\" -i \"twitter-123\"',\n 'Post with comments, each having their own media'\n )\n .example(\n '$0 posts:create -c \"Main\" -c \"Comment with semicolon; see?\" -c \"Another!\" -s \"2024-12-31T12:00:00Z\" -i \"twitter-123\"',\n 'Comments can contain semicolons'\n )\n .example(\n '$0 posts:create -c \"Thread 1/3\" -c \"Thread 2/3\" -c \"Thread 3/3\" -d 5 -s \"2024-12-31T12:00:00Z\" -i \"twitter-123\"',\n 'Twitter thread with 5 minute delay'\n )\n .example(\n '$0 posts:create --json ./post.json',\n 'Complex post from JSON file'\n )\n .example(\n '$0 posts:create -c \"Post to subreddit\" -s \"2024-12-31T12:00:00Z\" --settings \\'{\"subreddit\":[{\"value\":{\"subreddit\":\"programming\",\"title\":\"My Title\",\"type\":\"text\",\"url\":\"\",\"is_flair_required\":false}}]}\\' -i \"reddit-123\"',\n 'Reddit post with specific subreddit settings'\n )\n .example(\n '$0 posts:create -c \"Video description\" -s \"2024-12-31T12:00:00Z\" --settings \\'{\"title\":\"My Video\",\"type\":\"public\",\"tags\":[{\"value\":\"tech\",\"label\":\"Tech\"}]}\\' -i \"youtube-123\"',\n 'YouTube post with title and tags'\n )\n .example(\n '$0 posts:create -c \"Tweet content\" -s \"2024-12-31T12:00:00Z\" --settings \\'{\"who_can_reply_post\":\"everyone\"}\\' -i \"twitter-123\"',\n 'X (Twitter) post with reply settings'\n );\n },\n createPost as any\n )\n .command(\n 'posts:list',\n 'List all posts',\n (yargs: Argv) => {\n return yargs\n .option('startDate', {\n describe: 'Start date (ISO 8601 format). Default: 30 days ago',\n type: 'string',\n })\n .option('endDate', {\n describe: 'End date (ISO 8601 format). Default: 30 days from now',\n type: 'string',\n })\n .option('customer', {\n describe: 'Customer ID (optional)',\n type: 'string',\n })\n .example('$0 posts:list', 'List all posts (last 30 days to next 30 days)')\n .example(\n '$0 posts:list --startDate \"2024-01-01T00:00:00Z\" --endDate \"2024-12-31T23:59:59Z\"',\n 'List posts for a specific date range'\n )\n .example(\n '$0 posts:list --customer \"customer-id\"',\n 'List posts for a specific customer'\n );\n },\n listPosts as any\n )\n .command(\n 'posts:delete <id>',\n 'Delete a post',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Post ID to delete',\n type: 'string',\n })\n .example('$0 posts:delete abc123', 'Delete post with ID abc123');\n },\n deletePost as any\n )\n .command(\n 'posts:missing <id>',\n 'List available content from the provider for a post with missing release ID',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Post ID',\n type: 'string',\n })\n .example(\n '$0 posts:missing post-123',\n 'Get available content to connect to a post'\n );\n },\n getMissingContent as any\n )\n .command(\n 'posts:connect <id>',\n 'Connect a post to its published content by updating the release ID',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Post ID',\n type: 'string',\n })\n .option('release-id', {\n describe: 'The platform-specific content ID to connect',\n type: 'string',\n demandOption: true,\n })\n .example(\n '$0 posts:connect post-123 --release-id \"7321456789012345678\"',\n 'Connect a post to its published content'\n );\n },\n connectPost as any\n )\n .command(\n 'integrations:list',\n 'List all connected integrations',\n {},\n listIntegrations as any\n )\n .command(\n 'integrations:settings <id>',\n 'Get settings schema for a specific integration',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Integration ID',\n type: 'string',\n })\n .example(\n '$0 integrations:settings reddit-123',\n 'Get settings schema for Reddit integration'\n )\n .example(\n '$0 integrations:settings youtube-456',\n 'Get settings schema for YouTube integration'\n );\n },\n getIntegrationSettings as any\n )\n .command(\n 'integrations:trigger <id> <method>',\n 'Trigger an integration tool to fetch additional data',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Integration ID',\n type: 'string',\n })\n .positional('method', {\n describe: 'Method name from the integration tools',\n type: 'string',\n })\n .option('data', {\n alias: 'd',\n describe: 'Data to pass to the tool as JSON string',\n type: 'string',\n })\n .example(\n '$0 integrations:trigger reddit-123 getSubreddits',\n 'Get list of subreddits'\n )\n .example(\n '$0 integrations:trigger reddit-123 searchSubreddits -d \\'{\"query\":\"programming\"}\\'',\n 'Search for subreddits'\n )\n .example(\n '$0 integrations:trigger youtube-123 getPlaylists',\n 'Get YouTube playlists'\n );\n },\n triggerIntegrationTool as any\n )\n .command(\n 'analytics:platform <id>',\n 'Get analytics for a specific integration/channel',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Integration ID',\n type: 'string',\n })\n .option('date', {\n alias: 'd',\n describe: 'Number of days to look back (default: 7)',\n type: 'string',\n default: '7',\n })\n .example(\n '$0 analytics:platform integration-123',\n 'Get last 7 days of analytics'\n )\n .example(\n '$0 analytics:platform integration-123 -d 30',\n 'Get last 30 days of analytics'\n );\n },\n getAnalytics as any\n )\n .command(\n 'analytics:post <id>',\n 'Get analytics for a specific post',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Post ID',\n type: 'string',\n })\n .option('date', {\n alias: 'd',\n describe: 'Number of days to look back (default: 7)',\n type: 'string',\n default: '7',\n })\n .example(\n '$0 analytics:post post-123',\n 'Get last 7 days of post analytics'\n )\n .example(\n '$0 analytics:post post-123 -d 30',\n 'Get last 30 days of post analytics'\n );\n },\n getPostAnalytics as any\n )\n .command(\n 'upload <file>',\n 'Upload a file',\n (yargs: Argv) => {\n return yargs\n .positional('file', {\n describe: 'File path to upload',\n type: 'string',\n })\n .example('$0 upload ./image.png', 'Upload an image');\n },\n uploadFile as any\n )\n .demandCommand(1, 'You need at least one command')\n .help()\n .alias('h', 'help')\n .version()\n .alias('v', 'version')\n .epilogue(\n 'For more information, visit: https://postiz.com\\n\\nSet your API key: export POSTIZ_API_KEY=your_api_key\\n\\n📽️ Recommendation: Use agent-media to generate AI videos & images (Kling, Veo, Sora, Seedance, Flux, Grok) and post them directly with Postiz.\\n Install: npm install -g agent-media-cli\\n Learn more: https://agent-media.ai'\n )\n .parse();\n","import fetch, { FormData } from 'node-fetch';\n\nexport interface PostizConfig {\n apiKey: string;\n apiUrl?: string;\n}\n\nexport class PostizAPI {\n private apiKey: string;\n private apiUrl: string;\n\n constructor(config: PostizConfig) {\n this.apiKey = config.apiKey;\n this.apiUrl = config.apiUrl || 'https://api.postiz.com';\n }\n\n private async request(endpoint: string, options: any = {}) {\n const url = `${this.apiUrl}${endpoint}`;\n const headers = {\n 'Content-Type': 'application/json',\n Authorization: this.apiKey,\n ...options.headers,\n };\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`API Error (${response.status}): ${error}`);\n }\n\n return await response.json();\n } catch (error: any) {\n throw new Error(`Request failed: ${error.message}`);\n }\n }\n\n async createPost(data: any) {\n return this.request('/public/v1/posts', {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async listPosts(filters: any = {}) {\n const queryString = new URLSearchParams(\n Object.entries(filters).reduce((acc, [key, value]) => {\n if (value !== undefined && value !== null) {\n acc[key] = String(value);\n }\n return acc;\n }, {} as Record<string, string>)\n ).toString();\n\n const endpoint = queryString\n ? `/public/v1/posts?${queryString}`\n : '/public/v1/posts';\n\n return this.request(endpoint, {\n method: 'GET',\n });\n }\n\n async deletePost(id: string) {\n return this.request(`/public/v1/posts/${id}`, {\n method: 'DELETE',\n });\n }\n\n async upload(file: Buffer, filename: string) {\n const formData = new FormData();\n const extension = filename.split('.').pop()?.toLowerCase() || '';\n\n // Determine MIME type based on file extension\n const mimeTypes: Record<string, string> = {\n // Images\n 'png': 'image/png',\n 'jpg': 'image/jpeg',\n 'jpeg': 'image/jpeg',\n 'gif': 'image/gif',\n 'webp': 'image/webp',\n 'svg': 'image/svg+xml',\n 'bmp': 'image/bmp',\n 'ico': 'image/x-icon',\n\n // Videos\n 'mp4': 'video/mp4',\n 'mov': 'video/quicktime',\n 'avi': 'video/x-msvideo',\n 'mkv': 'video/x-matroska',\n 'webm': 'video/webm',\n 'flv': 'video/x-flv',\n 'wmv': 'video/x-ms-wmv',\n 'm4v': 'video/x-m4v',\n 'mpeg': 'video/mpeg',\n 'mpg': 'video/mpeg',\n '3gp': 'video/3gpp',\n\n // Audio\n 'mp3': 'audio/mpeg',\n 'wav': 'audio/wav',\n 'ogg': 'audio/ogg',\n 'aac': 'audio/aac',\n 'flac': 'audio/flac',\n 'm4a': 'audio/mp4',\n\n // Documents\n 'pdf': 'application/pdf',\n 'doc': 'application/msword',\n 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n };\n\n const type = mimeTypes[extension] || 'application/octet-stream';\n\n const blob = new Blob([file], { type });\n formData.append('file', blob, filename);\n\n const url = `${this.apiUrl}/public/v1/upload`;\n const response = await fetch(url, {\n method: 'POST',\n // @ts-ignore\n body: formData,\n headers: {\n Authorization: this.apiKey,\n },\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Upload failed (${response.status}): ${error}`);\n }\n\n return await response.json();\n }\n\n async getMissingContent(postId: string) {\n return this.request(`/public/v1/posts/${postId}/missing`, {\n method: 'GET',\n });\n }\n\n async updateReleaseId(postId: string, releaseId: string) {\n return this.request(`/public/v1/posts/${postId}/release-id`, {\n method: 'PUT',\n body: JSON.stringify({ releaseId }),\n });\n }\n\n async getAnalytics(integrationId: string, date: string) {\n return this.request(`/public/v1/analytics/${integrationId}?date=${encodeURIComponent(date)}`, {\n method: 'GET',\n });\n }\n\n async getPostAnalytics(postId: string, date: string) {\n return this.request(`/public/v1/analytics/post/${postId}?date=${encodeURIComponent(date)}`, {\n method: 'GET',\n });\n }\n\n async listIntegrations() {\n return this.request('/public/v1/integrations', {\n method: 'GET',\n });\n }\n\n async getIntegrationSettings(integrationId: string) {\n return this.request(`/public/v1/integration-settings/${integrationId}`, {\n method: 'GET',\n });\n }\n\n async triggerIntegrationTool(\n integrationId: string,\n methodName: string,\n data: Record<string, string>\n ) {\n return this.request(`/public/v1/integration-trigger/${integrationId}`, {\n method: 'POST',\n body: JSON.stringify({ methodName, data }),\n });\n }\n}\n","import { PostizConfig } from './api';\n\nexport function getConfig(): PostizConfig {\n const apiKey = process.env.POSTIZ_API_KEY;\n const apiUrl = process.env.POSTIZ_API_URL;\n\n if (!apiKey) {\n console.error('❌ Error: POSTIZ_API_KEY environment variable is required');\n console.error('Please set it using: export POSTIZ_API_KEY=your_api_key');\n process.exit(1);\n }\n\n return {\n apiKey,\n apiUrl,\n };\n}\n","import { PostizAPI } from '../api';\nimport { getConfig } from '../config';\nimport { readFileSync, existsSync } from 'fs';\n\nexport async function getMissingContent(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Post ID is required');\n process.exit(1);\n }\n\n try {\n const result = await api.getMissingContent(args.id);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to get missing content:', error.message);\n process.exit(1);\n }\n}\n\nexport async function connectPost(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Post ID is required');\n process.exit(1);\n }\n\n if (!args.releaseId) {\n console.error('❌ --release-id is required');\n process.exit(1);\n }\n\n try {\n const result = await api.updateReleaseId(args.id, args.releaseId);\n console.log(`✅ Post ${args.id} connected to release ${args.releaseId}`);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to connect post:', error.message);\n process.exit(1);\n }\n}\n\nexport async function createPost(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n // Support both simple and complex post creation\n let postData: any;\n\n if (args.json) {\n // Load from JSON file for complex posts with comments and media\n try {\n const jsonPath = args.json;\n if (!existsSync(jsonPath)) {\n console.error(`❌ JSON file not found: ${jsonPath}`);\n process.exit(1);\n }\n const jsonContent = readFileSync(jsonPath, 'utf-8');\n postData = JSON.parse(jsonContent);\n } catch (error: any) {\n console.error('❌ Failed to parse JSON file:', error.message);\n process.exit(1);\n }\n } else {\n const integrations = args.integrations\n ? args.integrations.split(',').map((id: string) => id.trim())\n : [];\n\n if (integrations.length === 0) {\n console.error('❌ At least one integration ID is required');\n console.error('Use -i or --integrations to specify integration IDs');\n console.error('Run \"postiz integrations:list\" to see available integrations');\n process.exit(1);\n }\n\n // Support multiple -c and -m flags\n // Normalize to arrays\n const contents = Array.isArray(args.content) ? args.content : [args.content];\n const medias = Array.isArray(args.media) ? args.media : (args.media ? [args.media] : []);\n\n if (!contents[0]) {\n console.error('❌ At least one -c/--content is required');\n process.exit(1);\n }\n\n // Build value array by pairing contents with their media\n const values = contents.map((content: string, index: number) => {\n const mediaForThisContent = medias[index];\n const images = mediaForThisContent\n ? mediaForThisContent.split(',').map((img: string) => ({\n id: Math.random().toString(36).substring(7),\n path: img.trim(),\n }))\n : [];\n\n return {\n content: content,\n image: images,\n delay: args?.delay || 0,\n };\n });\n\n // Parse provider-specific settings if provided\n // Note: __type is automatically added by the backend based on integration ID\n let settings: any = undefined;\n\n if (args.settings) {\n try {\n settings = typeof args.settings === 'string'\n ? JSON.parse(args.settings)\n : args.settings;\n } catch (error: any) {\n console.error('❌ Failed to parse settings JSON:', error.message);\n process.exit(1);\n }\n }\n\n // Build the proper post structure\n postData = {\n type: args.type || 'schedule', // 'schedule' or 'draft'\n date: args.date, // Required date field\n shortLink: args.shortLink !== false,\n tags: [],\n posts: integrations.map((integrationId: string) => ({\n integration: { id: integrationId },\n value: values,\n settings: settings,\n })),\n };\n }\n\n try {\n const result = await api.createPost(postData);\n console.log('✅ Post created successfully!');\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to create post:', error.message);\n process.exit(1);\n }\n}\n\nexport async function listPosts(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n // Set default date range: last 30 days to 30 days in the future\n const defaultStartDate = new Date();\n defaultStartDate.setDate(defaultStartDate.getDate() - 30);\n\n const defaultEndDate = new Date();\n defaultEndDate.setDate(defaultEndDate.getDate() + 30);\n\n // Only send fields that are in GetPostsDto\n const filters: any = {\n startDate: args.startDate || defaultStartDate.toISOString(),\n endDate: args.endDate || defaultEndDate.toISOString(),\n };\n\n // customer is optional in the DTO\n if (args.customer) {\n filters.customer = args.customer;\n }\n\n try {\n const result = await api.listPosts(filters);\n console.log('📋 Posts:');\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to list posts:', error.message);\n process.exit(1);\n }\n}\n\nexport async function deletePost(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Post ID is required');\n process.exit(1);\n }\n\n try {\n await api.deletePost(args.id);\n console.log(`✅ Post ${args.id} deleted successfully!`);\n } catch (error: any) {\n console.error('❌ Failed to delete post:', error.message);\n process.exit(1);\n }\n}\n","import { PostizAPI } from '../api';\nimport { getConfig } from '../config';\n\nexport async function listIntegrations() {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n try {\n const result = await api.listIntegrations();\n console.log('🔌 Connected Integrations:');\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to list integrations:', error.message);\n process.exit(1);\n }\n}\n\nexport async function getIntegrationSettings(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Integration ID is required');\n process.exit(1);\n }\n\n try {\n const result = await api.getIntegrationSettings(args.id);\n console.log(`⚙️ Settings for integration: ${args.id}`);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to get integration settings:', error.message);\n process.exit(1);\n }\n}\n\nexport async function triggerIntegrationTool(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Integration ID is required');\n process.exit(1);\n }\n\n if (!args.method) {\n console.error('❌ Method name is required');\n process.exit(1);\n }\n\n // Parse data from JSON string or use empty object\n let data: Record<string, string> = {};\n if (args.data) {\n try {\n data = JSON.parse(args.data);\n } catch (error: any) {\n console.error('❌ Failed to parse data JSON:', error.message);\n process.exit(1);\n }\n }\n\n try {\n const result = await api.triggerIntegrationTool(args.id, args.method, data);\n console.log(`🔧 Tool result for ${args.method}:`);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to trigger tool:', error.message);\n process.exit(1);\n }\n}\n","import { PostizAPI } from '../api';\nimport { getConfig } from '../config';\n\nexport async function getAnalytics(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Integration ID is required');\n process.exit(1);\n }\n\n const date = args.date || '7';\n\n try {\n const result = await api.getAnalytics(args.id, date);\n console.log(`📊 Analytics for integration: ${args.id}`);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to get analytics:', error.message);\n process.exit(1);\n }\n}\n\nexport async function getPostAnalytics(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Post ID is required');\n process.exit(1);\n }\n\n const date = args.date || '7';\n\n try {\n const result = await api.getPostAnalytics(args.id, date);\n console.log(`📊 Analytics for post: ${args.id}`);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to get post analytics:', error.message);\n process.exit(1);\n }\n}\n","import { PostizAPI } from '../api';\nimport { getConfig } from '../config';\nimport { readFileSync } from 'fs';\n\nexport async function uploadFile(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.file) {\n console.error('❌ File path is required');\n process.exit(1);\n }\n\n try {\n const fileBuffer = readFileSync(args.file);\n const filename = args.file.split('/').pop() || 'file';\n\n const result = await api.upload(fileBuffer, filename);\n console.log('✅ File uploaded successfully!');\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to upload file:', error.message);\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["fetch","import_fs","yargs"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/api.ts","../src/commands/auth.ts","../src/config.ts","../src/commands/posts.ts","../src/commands/integrations.ts","../src/commands/analytics.ts","../src/commands/upload.ts"],"sourcesContent":["import yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport { createPost, listPosts, deletePost, getMissingContent, connectPost, changePostStatus } from './commands/posts';\nimport { listIntegrations, getIntegrationSettings, triggerIntegrationTool } from './commands/integrations';\nimport { getAnalytics, getPostAnalytics } from './commands/analytics';\nimport { uploadFile } from './commands/upload';\nimport { authLogin, authLogout, authStatus } from './commands/auth';\nimport type { Argv } from 'yargs';\n\nyargs(hideBin(process.argv))\n .scriptName('postiz')\n .usage('$0 <command> [options]')\n .command(\n 'posts:create',\n 'Create a new post',\n (yargs: Argv) => {\n return yargs\n .option('content', {\n alias: 'c',\n describe: 'Post/comment content (can be used multiple times)',\n type: 'string',\n })\n .option('media', {\n alias: 'm',\n describe: 'Comma-separated media URLs for the corresponding -c (can be used multiple times)',\n type: 'string',\n })\n .option('integrations', {\n alias: 'i',\n describe: 'Comma-separated list of integration IDs',\n type: 'string',\n })\n .option('date', {\n alias: 's',\n describe: 'Schedule date (ISO 8601 format) - REQUIRED',\n type: 'string',\n })\n .option('type', {\n alias: 't',\n describe: 'Post type: \"schedule\" or \"draft\"',\n type: 'string',\n choices: ['schedule', 'draft'],\n default: 'schedule',\n })\n .option('delay', {\n alias: 'd',\n describe: 'Delay in minutes between comments (default: 0)',\n type: 'number',\n default: 0,\n })\n .option('json', {\n alias: 'j',\n describe: 'Path to JSON file with full post structure',\n type: 'string',\n })\n .option('shortLink', {\n describe: 'Use short links',\n type: 'boolean',\n default: true,\n })\n .option('settings', {\n describe: 'Platform-specific settings as JSON string',\n type: 'string',\n })\n .check((argv) => {\n if (!argv.json && !argv.content) {\n throw new Error('Either --content or --json is required');\n }\n if (!argv.json && !argv.integrations) {\n throw new Error('--integrations is required when not using --json');\n }\n if (!argv.json && !argv.date) {\n throw new Error('--date is required when not using --json');\n }\n return true;\n })\n .example(\n '$0 posts:create -c \"Hello World!\" -s \"2024-12-31T12:00:00Z\" -i \"twitter-123\"',\n 'Simple scheduled post'\n )\n .example(\n '$0 posts:create -c \"Draft post\" -s \"2024-12-31T12:00:00Z\" -t draft -i \"twitter-123\"',\n 'Create draft post'\n )\n .example(\n '$0 posts:create -c \"Main post\" -m \"img1.jpg,img2.jpg\" -s \"2024-12-31T12:00:00Z\" -i \"twitter-123\"',\n 'Post with multiple images'\n )\n .example(\n '$0 posts:create -c \"Main post\" -m \"img1.jpg\" -c \"First comment\" -m \"img2.jpg\" -c \"Second comment\" -m \"img3.jpg,img4.jpg\" -s \"2024-12-31T12:00:00Z\" -i \"twitter-123\"',\n 'Post with comments, each having their own media'\n )\n .example(\n '$0 posts:create -c \"Main\" -c \"Comment with semicolon; see?\" -c \"Another!\" -s \"2024-12-31T12:00:00Z\" -i \"twitter-123\"',\n 'Comments can contain semicolons'\n )\n .example(\n '$0 posts:create -c \"Thread 1/3\" -c \"Thread 2/3\" -c \"Thread 3/3\" -d 5 -s \"2024-12-31T12:00:00Z\" -i \"twitter-123\"',\n 'Twitter thread with 5 minute delay'\n )\n .example(\n '$0 posts:create --json ./post.json',\n 'Complex post from JSON file'\n )\n .example(\n '$0 posts:create -c \"Post to subreddit\" -s \"2024-12-31T12:00:00Z\" --settings \\'{\"subreddit\":[{\"value\":{\"subreddit\":\"programming\",\"title\":\"My Title\",\"type\":\"text\",\"url\":\"\",\"is_flair_required\":false}}]}\\' -i \"reddit-123\"',\n 'Reddit post with specific subreddit settings'\n )\n .example(\n '$0 posts:create -c \"Video description\" -s \"2024-12-31T12:00:00Z\" --settings \\'{\"title\":\"My Video\",\"type\":\"public\",\"tags\":[{\"value\":\"tech\",\"label\":\"Tech\"}]}\\' -i \"youtube-123\"',\n 'YouTube post with title and tags'\n )\n .example(\n '$0 posts:create -c \"Tweet content\" -s \"2024-12-31T12:00:00Z\" --settings \\'{\"who_can_reply_post\":\"everyone\"}\\' -i \"twitter-123\"',\n 'X (Twitter) post with reply settings'\n );\n },\n createPost as any\n )\n .command(\n 'posts:list',\n 'List all posts',\n (yargs: Argv) => {\n return yargs\n .option('startDate', {\n describe: 'Start date (ISO 8601 format). Default: 30 days ago',\n type: 'string',\n })\n .option('endDate', {\n describe: 'End date (ISO 8601 format). Default: 30 days from now',\n type: 'string',\n })\n .option('customer', {\n describe: 'Customer ID (optional)',\n type: 'string',\n })\n .example('$0 posts:list', 'List all posts (last 30 days to next 30 days)')\n .example(\n '$0 posts:list --startDate \"2024-01-01T00:00:00Z\" --endDate \"2024-12-31T23:59:59Z\"',\n 'List posts for a specific date range'\n )\n .example(\n '$0 posts:list --customer \"customer-id\"',\n 'List posts for a specific customer'\n );\n },\n listPosts as any\n )\n .command(\n 'posts:delete <id>',\n 'Delete a post',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Post ID to delete',\n type: 'string',\n })\n .example('$0 posts:delete abc123', 'Delete post with ID abc123');\n },\n deletePost as any\n )\n .command(\n 'posts:missing <id>',\n 'List available content from the provider for a post with missing release ID',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Post ID',\n type: 'string',\n })\n .example(\n '$0 posts:missing post-123',\n 'Get available content to connect to a post'\n );\n },\n getMissingContent as any\n )\n .command(\n 'posts:status <id>',\n 'Change a post status between draft and schedule',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Post ID',\n type: 'string',\n })\n .option('status', {\n alias: 's',\n describe: 'New status: \"draft\" or \"schedule\"',\n type: 'string',\n choices: ['draft', 'schedule'],\n demandOption: true,\n })\n .example(\n '$0 posts:status post-123 --status draft',\n 'Move a scheduled post back to draft (stops the running workflow)'\n )\n .example(\n '$0 posts:status post-123 --status schedule',\n 'Schedule a draft post so it is queued for publishing'\n );\n },\n changePostStatus as any\n )\n .command(\n 'posts:connect <id>',\n 'Connect a post to its published content by updating the release ID',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Post ID',\n type: 'string',\n })\n .option('release-id', {\n describe: 'The platform-specific content ID to connect',\n type: 'string',\n demandOption: true,\n })\n .example(\n '$0 posts:connect post-123 --release-id \"7321456789012345678\"',\n 'Connect a post to its published content'\n );\n },\n connectPost as any\n )\n .command(\n 'integrations:list',\n 'List all connected integrations',\n {},\n listIntegrations as any\n )\n .command(\n 'integrations:settings <id>',\n 'Get settings schema for a specific integration',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Integration ID',\n type: 'string',\n })\n .example(\n '$0 integrations:settings reddit-123',\n 'Get settings schema for Reddit integration'\n )\n .example(\n '$0 integrations:settings youtube-456',\n 'Get settings schema for YouTube integration'\n );\n },\n getIntegrationSettings as any\n )\n .command(\n 'integrations:trigger <id> <method>',\n 'Trigger an integration tool to fetch additional data',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Integration ID',\n type: 'string',\n })\n .positional('method', {\n describe: 'Method name from the integration tools',\n type: 'string',\n })\n .option('data', {\n alias: 'd',\n describe: 'Data to pass to the tool as JSON string',\n type: 'string',\n })\n .example(\n '$0 integrations:trigger reddit-123 getSubreddits',\n 'Get list of subreddits'\n )\n .example(\n '$0 integrations:trigger reddit-123 searchSubreddits -d \\'{\"query\":\"programming\"}\\'',\n 'Search for subreddits'\n )\n .example(\n '$0 integrations:trigger youtube-123 getPlaylists',\n 'Get YouTube playlists'\n );\n },\n triggerIntegrationTool as any\n )\n .command(\n 'analytics:platform <id>',\n 'Get analytics for a specific integration/channel',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Integration ID',\n type: 'string',\n })\n .option('date', {\n alias: 'd',\n describe: 'Number of days to look back (default: 7)',\n type: 'string',\n default: '7',\n })\n .example(\n '$0 analytics:platform integration-123',\n 'Get last 7 days of analytics'\n )\n .example(\n '$0 analytics:platform integration-123 -d 30',\n 'Get last 30 days of analytics'\n );\n },\n getAnalytics as any\n )\n .command(\n 'analytics:post <id>',\n 'Get analytics for a specific post',\n (yargs: Argv) => {\n return yargs\n .positional('id', {\n describe: 'Post ID',\n type: 'string',\n })\n .option('date', {\n alias: 'd',\n describe: 'Number of days to look back (default: 7)',\n type: 'string',\n default: '7',\n })\n .example(\n '$0 analytics:post post-123',\n 'Get last 7 days of post analytics'\n )\n .example(\n '$0 analytics:post post-123 -d 30',\n 'Get last 30 days of post analytics'\n );\n },\n getPostAnalytics as any\n )\n .command(\n 'upload <file>',\n 'Upload a file',\n (yargs: Argv) => {\n return yargs\n .positional('file', {\n describe: 'File path to upload',\n type: 'string',\n })\n .example('$0 upload ./image.png', 'Upload an image');\n },\n uploadFile as any\n )\n .command(\n 'auth:login',\n 'Authenticate using OAuth2 (device flow)',\n (yargs: Argv) => {\n return yargs\n .option('auth-server', {\n describe: 'Auth server URL (default: https://cli-auth.postiz.com)',\n type: 'string',\n })\n .example(\n '$0 auth:login',\n 'Login via OAuth2 device flow'\n );\n },\n authLogin as any\n )\n .command(\n 'auth:logout',\n 'Remove stored OAuth2 credentials',\n {},\n authLogout as any\n )\n .command(\n 'auth:status',\n 'Show current authentication status',\n {},\n authStatus as any\n )\n .demandCommand(1, 'You need at least one command')\n .help()\n .alias('h', 'help')\n .version()\n .alias('v', 'version')\n .epilogue(\n 'For more information, visit: https://postiz.com\\n\\nAuthentication:\\n OAuth2: postiz auth:login\\n API Key: export POSTIZ_API_KEY=your_api_key\\n\\n📽️ Recommendation: Use agent-media to generate AI videos & images (Kling, Veo, Sora, Seedance, Flux, Grok) and post them directly with Postiz.\\n Install: npm install -g agent-media-cli\\n Learn more: https://agent-media.ai'\n )\n .parse();\n","import fetch, { FormData } from 'node-fetch';\n\nexport interface PostizConfig {\n apiKey: string;\n apiUrl?: string;\n}\n\nexport class PostizAPI {\n private apiKey: string;\n private apiUrl: string;\n\n constructor(config: PostizConfig) {\n this.apiKey = config.apiKey;\n this.apiUrl = config.apiUrl || 'https://api.postiz.com';\n }\n\n private async request(endpoint: string, options: any = {}) {\n const url = `${this.apiUrl}${endpoint}`;\n const headers = {\n 'Content-Type': 'application/json',\n Authorization: this.apiKey,\n ...options.headers,\n };\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`API Error (${response.status}): ${error}`);\n }\n\n return await response.json();\n } catch (error: any) {\n throw new Error(`Request failed: ${error.message}`);\n }\n }\n\n async createPost(data: any) {\n return this.request('/public/v1/posts', {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async listPosts(filters: any = {}) {\n const queryString = new URLSearchParams(\n Object.entries(filters).reduce((acc, [key, value]) => {\n if (value !== undefined && value !== null) {\n acc[key] = String(value);\n }\n return acc;\n }, {} as Record<string, string>)\n ).toString();\n\n const endpoint = queryString\n ? `/public/v1/posts?${queryString}`\n : '/public/v1/posts';\n\n return this.request(endpoint, {\n method: 'GET',\n });\n }\n\n async deletePost(id: string) {\n return this.request(`/public/v1/posts/${id}`, {\n method: 'DELETE',\n });\n }\n\n async upload(file: Buffer, filename: string) {\n const formData = new FormData();\n const extension = filename.split('.').pop()?.toLowerCase() || '';\n\n // Determine MIME type based on file extension\n const mimeTypes: Record<string, string> = {\n // Images\n 'png': 'image/png',\n 'jpg': 'image/jpeg',\n 'jpeg': 'image/jpeg',\n 'gif': 'image/gif',\n 'webp': 'image/webp',\n 'svg': 'image/svg+xml',\n 'bmp': 'image/bmp',\n 'ico': 'image/x-icon',\n\n // Videos\n 'mp4': 'video/mp4',\n 'mov': 'video/quicktime',\n 'avi': 'video/x-msvideo',\n 'mkv': 'video/x-matroska',\n 'webm': 'video/webm',\n 'flv': 'video/x-flv',\n 'wmv': 'video/x-ms-wmv',\n 'm4v': 'video/x-m4v',\n 'mpeg': 'video/mpeg',\n 'mpg': 'video/mpeg',\n '3gp': 'video/3gpp',\n\n // Audio\n 'mp3': 'audio/mpeg',\n 'wav': 'audio/wav',\n 'ogg': 'audio/ogg',\n 'aac': 'audio/aac',\n 'flac': 'audio/flac',\n 'm4a': 'audio/mp4',\n\n // Documents\n 'pdf': 'application/pdf',\n 'doc': 'application/msword',\n 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n };\n\n const type = mimeTypes[extension] || 'application/octet-stream';\n\n const blob = new Blob([file], { type });\n formData.append('file', blob, filename);\n\n const url = `${this.apiUrl}/public/v1/upload`;\n const response = await fetch(url, {\n method: 'POST',\n // @ts-ignore\n body: formData,\n headers: {\n Authorization: this.apiKey,\n },\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Upload failed (${response.status}): ${error}`);\n }\n\n return await response.json();\n }\n\n async getMissingContent(postId: string) {\n return this.request(`/public/v1/posts/${postId}/missing`, {\n method: 'GET',\n });\n }\n\n async updateReleaseId(postId: string, releaseId: string) {\n return this.request(`/public/v1/posts/${postId}/release-id`, {\n method: 'PUT',\n body: JSON.stringify({ releaseId }),\n });\n }\n\n async changePostStatus(postId: string, status: 'draft' | 'schedule') {\n return this.request(`/public/v1/posts/${postId}/status`, {\n method: 'PUT',\n body: JSON.stringify({ status }),\n });\n }\n\n async getAnalytics(integrationId: string, date: string) {\n return this.request(`/public/v1/analytics/${integrationId}?date=${encodeURIComponent(date)}`, {\n method: 'GET',\n });\n }\n\n async getPostAnalytics(postId: string, date: string) {\n return this.request(`/public/v1/analytics/post/${postId}?date=${encodeURIComponent(date)}`, {\n method: 'GET',\n });\n }\n\n async listIntegrations() {\n return this.request('/public/v1/integrations', {\n method: 'GET',\n });\n }\n\n async getIntegrationSettings(integrationId: string) {\n return this.request(`/public/v1/integration-settings/${integrationId}`, {\n method: 'GET',\n });\n }\n\n async triggerIntegrationTool(\n integrationId: string,\n methodName: string,\n data: Record<string, string>\n ) {\n return this.request(`/public/v1/integration-trigger/${integrationId}`, {\n method: 'POST',\n body: JSON.stringify({ methodName, data }),\n });\n }\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync, chmodSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport fetch from 'node-fetch';\n\nconst CREDENTIALS_DIR = join(homedir(), '.postiz');\nconst CREDENTIALS_FILE = join(CREDENTIALS_DIR, 'credentials.json');\n\nconst DEFAULT_AUTH_SERVER = 'https://cli-auth.postiz.com';\n\ninterface StoredCredentials {\n accessToken: string;\n apiUrl: string;\n organizationId?: string;\n}\n\nexport function loadCredentials(): StoredCredentials | null {\n try {\n if (!existsSync(CREDENTIALS_FILE)) return null;\n const data = JSON.parse(readFileSync(CREDENTIALS_FILE, 'utf-8'));\n if (!data.accessToken) return null;\n return data;\n } catch {\n return null;\n }\n}\n\nfunction saveCredentials(credentials: StoredCredentials): void {\n if (!existsSync(CREDENTIALS_DIR)) {\n mkdirSync(CREDENTIALS_DIR, { recursive: true, mode: 0o700 });\n }\n writeFileSync(CREDENTIALS_FILE, JSON.stringify(credentials, null, 2), { encoding: 'utf-8', mode: 0o600 });\n // Ensure permissions even if file already existed\n chmodSync(CREDENTIALS_FILE, 0o600);\n}\n\nfunction deleteCredentials(): void {\n if (existsSync(CREDENTIALS_FILE)) {\n unlinkSync(CREDENTIALS_FILE);\n }\n}\n\nfunction openBrowser(url: string): void {\n const { exec } = require('child_process');\n const platform = process.platform;\n\n if (platform === 'darwin') {\n exec(`open \"${url}\"`);\n } else if (platform === 'win32') {\n exec(`start \"\" \"${url}\"`);\n } else {\n exec(`xdg-open \"${url}\"`);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function authLogin(argv: any) {\n const authServer = argv.authServer || process.env.POSTIZ_AUTH_SERVER || DEFAULT_AUTH_SERVER;\n\n console.log('🔐 Starting device authorization flow...\\n');\n\n // Step 1: Request a device code from the auth server\n let deviceCode: string;\n let userCode: string;\n let verificationUri: string;\n let expiresIn: number;\n let interval: number;\n\n try {\n const response = await fetch(`${authServer}/device/code`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const error = await response.text();\n console.error(`❌ Failed to start authorization (${response.status}): ${error}`);\n process.exit(1);\n }\n\n const data = (await response.json()) as any;\n deviceCode = data.device_code;\n userCode = data.user_code;\n verificationUri = data.verification_uri;\n expiresIn = data.expires_in;\n interval = data.interval || 5;\n } catch (error: any) {\n console.error(`❌ Could not reach auth server at ${authServer}: ${error.message}`);\n process.exit(1);\n }\n\n // Step 2: Show the user code and open browser\n console.log(' Your authorization code:\\n');\n console.log(` ┌─────────────────┐`);\n console.log(` │ ${userCode} │`);\n console.log(` └─────────────────┘\\n`);\n console.log(` Open this URL and enter the code above:`);\n console.log(` ${verificationUri}\\n`);\n\n openBrowser(`${verificationUri}?code=${encodeURIComponent(userCode)}`);\n\n console.log(' Waiting for authorization...\\n');\n\n // Step 3: Poll for the token\n const deadline = Date.now() + expiresIn * 1000;\n\n while (Date.now() < deadline) {\n await sleep(interval * 1000);\n\n try {\n const response = await fetch(`${authServer}/device/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ device_code: deviceCode }),\n });\n\n const data = (await response.json()) as any;\n\n if (response.ok && data.access_token) {\n saveCredentials({\n accessToken: data.access_token,\n apiUrl: data.api_url || 'https://api.postiz.com',\n organizationId: data.organization_id,\n });\n\n console.log('✅ Successfully authenticated!');\n console.log(`📁 Credentials saved to ${CREDENTIALS_FILE}`);\n if (data.organization_id) {\n console.log(`🏢 Organization ID: ${data.organization_id}`);\n }\n return;\n }\n\n if (data.error === 'authorization_pending') {\n continue;\n }\n\n if (data.error === 'expired_token') {\n console.error('❌ Authorization expired. Please try again.');\n process.exit(1);\n }\n\n // Unknown error\n console.error(`❌ Authorization failed: ${data.error}`);\n process.exit(1);\n } catch {\n // Network error during poll — keep trying\n continue;\n }\n }\n\n console.error('❌ Authorization timed out. Please try again.');\n process.exit(1);\n}\n\nexport async function authLogout() {\n const creds = loadCredentials();\n if (!creds) {\n console.log('ℹ️ No stored credentials found.');\n return;\n }\n\n deleteCredentials();\n console.log('✅ Credentials removed.');\n}\n\nexport async function authStatus() {\n const envKey = process.env.POSTIZ_API_KEY;\n const creds = loadCredentials();\n\n let apiKey: string | undefined;\n let apiUrl: string;\n\n if (creds) {\n console.log('🔐 Authentication method: OAuth2');\n console.log(`📡 API URL: ${creds.apiUrl}`);\n console.log(`🔑 Token: ${creds.accessToken.substring(0, 8)}...`);\n if (creds.organizationId) {\n console.log(`🏢 Organization: ${creds.organizationId}`);\n }\n console.log(`📁 Credentials file: ${CREDENTIALS_FILE}`);\n apiKey = creds.accessToken;\n apiUrl = creds.apiUrl;\n } else if (envKey) {\n console.log('🔑 Authentication method: API Key (environment variable)');\n console.log(`🔑 Key: ${envKey.substring(0, 8)}...`);\n apiKey = envKey;\n apiUrl = process.env.POSTIZ_API_URL || 'https://api.postiz.com';\n } else {\n console.log('❌ Not authenticated.');\n console.log('\\nOptions:');\n console.log(' 1. OAuth2: postiz auth:login');\n console.log(' 2. API Key: export POSTIZ_API_KEY=your_api_key');\n return;\n }\n\n // Verify credentials by calling the integrations endpoint\n console.log('\\n🔄 Verifying credentials...');\n try {\n const response = await fetch(`${apiUrl}/public/v1/integrations`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: apiKey,\n },\n });\n\n if (response.ok) {\n const integrations = (await response.json()) as any[];\n console.log(`✅ Credentials are valid. ${integrations.length} integration(s) connected.`);\n } else if (response.status === 401 || response.status === 403) {\n console.log('❌ Credentials are expired or invalid. Please re-authenticate.');\n if (creds) {\n console.log(' Run: postiz auth:login');\n } else {\n console.log(' Update your POSTIZ_API_KEY environment variable.');\n }\n } else {\n const error = await response.text();\n console.log(`⚠️ Could not verify credentials (HTTP ${response.status}): ${error}`);\n }\n } catch (error: any) {\n console.log(`⚠️ Could not reach API to verify credentials: ${error.message}`);\n }\n}\n","import { PostizConfig } from './api';\nimport { loadCredentials } from './commands/auth';\n\nexport function getConfig(): PostizConfig {\n // Check for stored OAuth credentials first\n const creds = loadCredentials();\n if (creds) {\n return {\n apiKey: creds.accessToken,\n apiUrl: creds.apiUrl,\n };\n }\n\n // Fall back to environment variable\n const apiKey = process.env.POSTIZ_API_KEY;\n const apiUrl = process.env.POSTIZ_API_URL;\n\n if (!apiKey) {\n console.error('❌ Error: No authentication found.');\n console.error('Options:');\n console.error(' 1. OAuth2: postiz auth:login --client-id <id> --client-secret <secret>');\n console.error(' 2. API Key: export POSTIZ_API_KEY=your_api_key');\n process.exit(1);\n }\n\n return {\n apiKey,\n apiUrl,\n };\n}\n","import { PostizAPI } from '../api';\nimport { getConfig } from '../config';\nimport { readFileSync, existsSync } from 'fs';\n\nexport async function getMissingContent(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Post ID is required');\n process.exit(1);\n }\n\n try {\n const result = await api.getMissingContent(args.id);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to get missing content:', error.message);\n process.exit(1);\n }\n}\n\nexport async function connectPost(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Post ID is required');\n process.exit(1);\n }\n\n if (!args.releaseId) {\n console.error('❌ --release-id is required');\n process.exit(1);\n }\n\n try {\n const result = await api.updateReleaseId(args.id, args.releaseId);\n console.log(`✅ Post ${args.id} connected to release ${args.releaseId}`);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to connect post:', error.message);\n process.exit(1);\n }\n}\n\nexport async function createPost(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n // Support both simple and complex post creation\n let postData: any;\n\n if (args.json) {\n // Load from JSON file for complex posts with comments and media\n try {\n const jsonPath = args.json;\n if (!existsSync(jsonPath)) {\n console.error(`❌ JSON file not found: ${jsonPath}`);\n process.exit(1);\n }\n const jsonContent = readFileSync(jsonPath, 'utf-8');\n postData = JSON.parse(jsonContent);\n } catch (error: any) {\n console.error('❌ Failed to parse JSON file:', error.message);\n process.exit(1);\n }\n } else {\n const integrations = args.integrations\n ? args.integrations.split(',').map((id: string) => id.trim())\n : [];\n\n if (integrations.length === 0) {\n console.error('❌ At least one integration ID is required');\n console.error('Use -i or --integrations to specify integration IDs');\n console.error('Run \"postiz integrations:list\" to see available integrations');\n process.exit(1);\n }\n\n // Support multiple -c and -m flags\n // Normalize to arrays\n const contents = Array.isArray(args.content) ? args.content : [args.content];\n const medias = Array.isArray(args.media) ? args.media : (args.media ? [args.media] : []);\n\n if (!contents[0]) {\n console.error('❌ At least one -c/--content is required');\n process.exit(1);\n }\n\n // Build value array by pairing contents with their media\n const values = contents.map((content: string, index: number) => {\n const mediaForThisContent = medias[index];\n const images = mediaForThisContent\n ? mediaForThisContent.split(',').map((img: string) => ({\n id: Math.random().toString(36).substring(7),\n path: img.trim(),\n }))\n : [];\n\n return {\n content: content,\n image: images,\n delay: args?.delay || 0,\n };\n });\n\n // Parse provider-specific settings if provided\n // Note: __type is automatically added by the backend based on integration ID\n let settings: any = undefined;\n\n if (args.settings) {\n try {\n settings = typeof args.settings === 'string'\n ? JSON.parse(args.settings)\n : args.settings;\n } catch (error: any) {\n console.error('❌ Failed to parse settings JSON:', error.message);\n process.exit(1);\n }\n }\n\n // Build the proper post structure\n postData = {\n type: args.type || 'schedule', // 'schedule' or 'draft'\n creationMethod: 'CLI',\n date: args.date, // Required date field\n shortLink: args.shortLink !== false,\n tags: [],\n posts: integrations.map((integrationId: string) => ({\n integration: { id: integrationId },\n value: values,\n settings: settings,\n })),\n };\n }\n\n try {\n const result = await api.createPost(postData);\n console.log('✅ Post created successfully!');\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to create post:', error.message);\n process.exit(1);\n }\n}\n\nexport async function listPosts(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n // Set default date range: last 30 days to 30 days in the future\n const defaultStartDate = new Date();\n defaultStartDate.setDate(defaultStartDate.getDate() - 30);\n\n const defaultEndDate = new Date();\n defaultEndDate.setDate(defaultEndDate.getDate() + 30);\n\n // Only send fields that are in GetPostsDto\n const filters: any = {\n startDate: args.startDate || defaultStartDate.toISOString(),\n endDate: args.endDate || defaultEndDate.toISOString(),\n };\n\n // customer is optional in the DTO\n if (args.customer) {\n filters.customer = args.customer;\n }\n\n try {\n const result = await api.listPosts(filters);\n console.log('📋 Posts:');\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to list posts:', error.message);\n process.exit(1);\n }\n}\n\nexport async function changePostStatus(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Post ID is required');\n process.exit(1);\n }\n\n if (args.status !== 'draft' && args.status !== 'schedule') {\n console.error('❌ --status must be either \"draft\" or \"schedule\"');\n process.exit(1);\n }\n\n try {\n const result = await api.changePostStatus(args.id, args.status);\n console.log(`✅ Post ${args.id} status changed to ${args.status}`);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to change post status:', error.message);\n process.exit(1);\n }\n}\n\nexport async function deletePost(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Post ID is required');\n process.exit(1);\n }\n\n try {\n await api.deletePost(args.id);\n console.log(`✅ Post ${args.id} deleted successfully!`);\n } catch (error: any) {\n console.error('❌ Failed to delete post:', error.message);\n process.exit(1);\n }\n}\n","import { PostizAPI } from '../api';\nimport { getConfig } from '../config';\n\nexport async function listIntegrations() {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n try {\n const result = await api.listIntegrations();\n console.log('🔌 Connected Integrations:');\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to list integrations:', error.message);\n process.exit(1);\n }\n}\n\nexport async function getIntegrationSettings(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Integration ID is required');\n process.exit(1);\n }\n\n try {\n const result = await api.getIntegrationSettings(args.id);\n console.log(`⚙️ Settings for integration: ${args.id}`);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to get integration settings:', error.message);\n process.exit(1);\n }\n}\n\nexport async function triggerIntegrationTool(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Integration ID is required');\n process.exit(1);\n }\n\n if (!args.method) {\n console.error('❌ Method name is required');\n process.exit(1);\n }\n\n // Parse data from JSON string or use empty object\n let data: Record<string, string> = {};\n if (args.data) {\n try {\n data = JSON.parse(args.data);\n } catch (error: any) {\n console.error('❌ Failed to parse data JSON:', error.message);\n process.exit(1);\n }\n }\n\n try {\n const result = await api.triggerIntegrationTool(args.id, args.method, data);\n console.log(`🔧 Tool result for ${args.method}:`);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to trigger tool:', error.message);\n process.exit(1);\n }\n}\n","import { PostizAPI } from '../api';\nimport { getConfig } from '../config';\n\nexport async function getAnalytics(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Integration ID is required');\n process.exit(1);\n }\n\n const date = args.date || '7';\n\n try {\n const result = await api.getAnalytics(args.id, date);\n console.log(`📊 Analytics for integration: ${args.id}`);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to get analytics:', error.message);\n process.exit(1);\n }\n}\n\nexport async function getPostAnalytics(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.id) {\n console.error('❌ Post ID is required');\n process.exit(1);\n }\n\n const date = args.date || '7';\n\n try {\n const result = await api.getPostAnalytics(args.id, date);\n console.log(`📊 Analytics for post: ${args.id}`);\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to get post analytics:', error.message);\n process.exit(1);\n }\n}\n","import { PostizAPI } from '../api';\nimport { getConfig } from '../config';\nimport { readFileSync } from 'fs';\n\nexport async function uploadFile(args: any) {\n const config = getConfig();\n const api = new PostizAPI(config);\n\n if (!args.file) {\n console.error('❌ File path is required');\n process.exit(1);\n }\n\n try {\n const fileBuffer = readFileSync(args.file);\n const filename = args.file.split('/').pop() || 'file';\n\n const result = await api.upload(fileBuffer, filename);\n console.log('✅ File uploaded successfully!');\n console.log(JSON.stringify(result, null, 2));\n return result;\n } catch (error: any) {\n console.error('❌ Failed to upload file:', error.message);\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["fetch","import_node_fetch","fetch","import_fs","import_fs","yargs"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "postiz",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.14",
|
|
4
4
|
"description": "Postiz CLI - Command line interface for the Postiz social media scheduling API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"node": ">=18.0.0"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
+
"@types/pg": "^8.20.0",
|
|
46
47
|
"node-fetch": "^3.3.2",
|
|
47
48
|
"yargs": "^17.7.2"
|
|
48
49
|
},
|