chirpie 1.0.49 → 1.0.51
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 +3 -3
- package/dist/index.js +52 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -30,14 +30,14 @@ export CHIRPIE_API_KEY=chirpie_sk_...
|
|
|
30
30
|
| Command | What it does |
|
|
31
31
|
|---------|--------------|
|
|
32
32
|
| `chirpie login` / `logout` / `auth` / `whoami` | Manage credentials |
|
|
33
|
-
| `chirpie post <text>` | Create a post. `-a` account (repeat it for several accounts), `-m` media files or URLs, `--alt` descriptions, `--config` per-account overrides, `--first-comment` a comment published under the post as soon as it goes out, `-s` schedule, `--timezone` the IANA zone a `-s` with no offset is read in, `--idempotency-key` to make a retry safe, `--draft` save without sending |
|
|
33
|
+
| `chirpie post <text>` | Create a post. `-a` account (repeat it for several accounts), `-m` media files or URLs, `--alt` descriptions, `--config` per-account overrides, `--first-comment` a comment published under the post as soon as it goes out, `--instagram-placement` and `--facebook-placement` to publish it as a story or a reel instead of a feed post, `-s` schedule, `--timezone` the IANA zone a `-s` with no offset is read in, `--idempotency-key` to make a retry safe, `--draft` save without sending |
|
|
34
34
|
| `chirpie thread <post> <post> ...` | Create a 2 to 25 post thread, or 1 to 25 with `--draft`. `-a` is repeatable, `--config` takes per-account posts, `--first-comment` posts a comment under the last part, `--timezone` and `--idempotency-key` work as they do on a post, `-f` takes a JSON payload file |
|
|
35
35
|
| `chirpie posts` | List posts. `--status`, `--account`, `--group`, `--limit`, `--include-hidden` |
|
|
36
36
|
| `chirpie posts get <id>` | Fetch one post |
|
|
37
|
-
| `chirpie posts update <id>` | Edit a post that has not published yet, or finish a draft. `--text`, `--media`, `--alt`, `--clear-media`, `--first-comment` (`""` removes it), `--schedule-at`, `--timezone`, `--keep-draft`. Leaving `--schedule-at` out keeps the time it already has |
|
|
37
|
+
| `chirpie posts update <id>` | Edit a post that has not published yet, or finish a draft. `--text`, `--media`, `--alt`, `--clear-media`, `--first-comment` (`""` removes it), `--instagram-placement`, `--facebook-placement`, `--clear-placement`, `--schedule-at`, `--timezone`, `--keep-draft`. Leaving `--schedule-at` out keeps the time it already has |
|
|
38
38
|
| `chirpie posts publish <id>` | Send a saved draft now. `-t` sets the final text first |
|
|
39
39
|
| `chirpie posts first-comment <id>` | Post a first comment that failed, again. It re-sends the text the post already carries. `--idempotency-key` makes a retry safe |
|
|
40
|
-
| `chirpie posts delete <id>` | Take a post down from the platform. Chirpie keeps it, marked deleted. Deleting any post of a scheduled thread cancels the thread. Instagram
|
|
40
|
+
| `chirpie posts delete <id>` | Take a post down from the platform. Chirpie keeps it, marked deleted. Deleting any post of a scheduled thread cancels the thread. A published Instagram or TikTok post cannot be deleted and refuses with `delete_unsupported` |
|
|
41
41
|
| `chirpie posts hide <id>` / `unhide <id>` | Hide a post from your Chirpie listings, or show it again. Nothing reaches the platform |
|
|
42
42
|
| `chirpie accounts` | List connected accounts, active and inactive |
|
|
43
43
|
| `chirpie accounts activate <id>` / `deactivate <id>` | Choose which accounts publish. Deactivating cancels that account's scheduled posts |
|
package/dist/index.js
CHANGED
|
@@ -278,14 +278,41 @@ function printFanOut(groupId, lines) {
|
|
|
278
278
|
return failed.length;
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
+
// src/lib/placement.ts
|
|
282
|
+
var INSTAGRAM_PLACEMENT_HELP = 'Where the post goes on Instagram: feed (the default), story or reel. A story takes exactly one image or video, no caption (pass "" as the text) and no first comment. A reel takes exactly one video. Only pass this when the post is going to an Instagram account';
|
|
283
|
+
var FACEBOOK_PLACEMENT_HELP = "Where the post goes on a Facebook Page: feed (the default) or story. A story takes exactly one image or video, no text and no first comment. Only pass this when the post is going to a Facebook Page";
|
|
284
|
+
var INSTAGRAM_PLACEMENTS = ["feed", "story", "reel"];
|
|
285
|
+
var FACEBOOK_PLACEMENTS = ["feed", "story"];
|
|
286
|
+
function placementConfiguration(opts) {
|
|
287
|
+
const instagram = opts.instagramPlacement;
|
|
288
|
+
const facebook = opts.facebookPlacement;
|
|
289
|
+
if (instagram !== void 0 && !INSTAGRAM_PLACEMENTS.includes(instagram)) {
|
|
290
|
+
error(
|
|
291
|
+
`--instagram-placement takes ${INSTAGRAM_PLACEMENTS.join(", ")}, not "${instagram}"`
|
|
292
|
+
);
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}
|
|
295
|
+
if (facebook !== void 0 && !FACEBOOK_PLACEMENTS.includes(facebook)) {
|
|
296
|
+
error(
|
|
297
|
+
`--facebook-placement takes ${FACEBOOK_PLACEMENTS.join(", ")}, not "${facebook}"`
|
|
298
|
+
);
|
|
299
|
+
process.exit(1);
|
|
300
|
+
}
|
|
301
|
+
if (instagram === void 0 && facebook === void 0) return void 0;
|
|
302
|
+
return {
|
|
303
|
+
...instagram !== void 0 ? { instagram: { placement: instagram } } : {},
|
|
304
|
+
...facebook !== void 0 ? { facebook: { placement: facebook } } : {}
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
281
308
|
// src/commands/post.ts
|
|
282
309
|
var postCommand = new Command3("post").description("Create a post").argument("<text>", "Post text").option(
|
|
283
310
|
"-a, --account <id>",
|
|
284
311
|
"Account ID. Repeat it to publish the same post to several accounts at once (up to 25)",
|
|
285
312
|
collect
|
|
286
|
-
).option("-m, --media <files...>", MEDIA_OPTION_HELP).option("--first-comment <text>", "Post this as a comment under the post, as soon as it goes out. X, Threads, Instagram and Facebook only. It counts as one post against your monthly quota").option("--alt <text...>", ALT_OPTION_HELP).option(
|
|
313
|
+
).option("-m, --media <files...>", MEDIA_OPTION_HELP).option("--first-comment <text>", "Post this as a comment under the post, as soon as it goes out. X, Threads, Instagram and Facebook only. It counts as one post against your monthly quota").option("--alt <text...>", ALT_OPTION_HELP).option("--instagram-placement <placement>", INSTAGRAM_PLACEMENT_HELP).option("--facebook-placement <placement>", FACEBOOK_PLACEMENT_HELP).option(
|
|
287
314
|
"--config <json-or-file>",
|
|
288
|
-
'Per-account overrides as JSON, or a path to a JSON file holding them: { "<account id>": { "text": "...", "media_urls": ["..."], "first_comment": "..." } }. Every key must be an account named with --account,
|
|
315
|
+
'Per-account overrides as JSON, or a path to a JSON file holding them: { "<account id>": { "text": "...", "media_urls": ["..."], "first_comment": "...", "configuration": { "instagram": { "placement": "reel" } } } }. Every key must be an account named with --account, "first_comment": "" publishes that account without the first comment the call is sending, and "configuration" replaces the placement flags for that account and is where the options a placement carries go (collaborators, user_tags, cover, video_cover_timestamp_ms, share_to_feed, trial_reel on Instagram, link on a Facebook Page)'
|
|
289
316
|
).option("-s, --schedule <datetime>", "Schedule for later. An ISO 8601 timestamp carrying a timezone (2026-04-01T14:00:00Z or 2026-04-01T16:00:00+02:00), or a local time with no offset (2026-11-01T09:30) read in --timezone or the timezone saved on your account. Posts publish within ~5 minutes of the scheduled time.").option(
|
|
290
317
|
"--draft",
|
|
291
318
|
"Save without publishing. Nothing is sent, nothing counts against your quota, and any problems are listed back"
|
|
@@ -304,6 +331,7 @@ var postCommand = new Command3("post").description("Create a post").argument("<t
|
|
|
304
331
|
}
|
|
305
332
|
const accountIds = named.length > 0 ? named : [await resolveSingleAccountId(client)];
|
|
306
333
|
const fanOut = named.length > 1 || Boolean(opts.config);
|
|
334
|
+
const configuration = placementConfiguration(opts);
|
|
307
335
|
try {
|
|
308
336
|
const media = await resolveMediaArgs(client, opts.media, opts.alt);
|
|
309
337
|
if (fanOut) {
|
|
@@ -312,6 +340,7 @@ var postCommand = new Command3("post").description("Create a post").argument("<t
|
|
|
312
340
|
text,
|
|
313
341
|
...media ? { media } : {},
|
|
314
342
|
...opts.firstComment ? { first_comment: opts.firstComment } : {},
|
|
343
|
+
...configuration ? { configuration } : {},
|
|
315
344
|
...opts.config ? {
|
|
316
345
|
account_configurations: parseAccountConfigurations(
|
|
317
346
|
opts.config
|
|
@@ -347,6 +376,7 @@ var postCommand = new Command3("post").description("Create a post").argument("<t
|
|
|
347
376
|
text,
|
|
348
377
|
...media ? { media } : {},
|
|
349
378
|
...opts.firstComment ? { first_comment: opts.firstComment } : {},
|
|
379
|
+
...configuration ? { configuration } : {},
|
|
350
380
|
schedule_at: opts.schedule,
|
|
351
381
|
...opts.timezone ? { timezone: opts.timezone } : {},
|
|
352
382
|
...opts.draft ? { draft: true } : {}
|
|
@@ -400,7 +430,7 @@ var threadCommand = new Command4("thread").description("Create a thread").argume
|
|
|
400
430
|
"JSON file with a full thread payload: { posts: [{ text, media_urls? }, ...], schedule_at?: string }. It may also carry account_ids and account_configurations."
|
|
401
431
|
).option(
|
|
402
432
|
"--config <json-or-file>",
|
|
403
|
-
`Per-account overrides as JSON, or a path to a JSON file holding them: { "<account id>": { "posts": [{ "text": "one" }, { "text": "two" }], "first_comment": "..." } }. An account's posts replace the whole thread for that account,
|
|
433
|
+
`Per-account overrides as JSON, or a path to a JSON file holding them: { "<account id>": { "posts": [{ "text": "one" }, { "text": "two" }], "first_comment": "...", "configuration": { "facebook": { "link": "https://example.com" } } } }. An account's posts replace the whole thread for that account, "first_comment": "" publishes that account without the first comment the call is sending, and "configuration" carries the publishing options for that account. A thread publishes to the feed: an Instagram story or reel, and a Facebook Page story, are each a single post, so a thread asking for one of those placements is refused`
|
|
404
434
|
).option("-s, --schedule <datetime>", "Schedule for later. An ISO 8601 timestamp carrying a timezone (2026-04-01T14:00:00Z or 2026-04-01T16:00:00+02:00), or a local time with no offset (2026-11-01T09:30) read in --timezone or the timezone saved on your account. Threads publish within ~5 minutes of the scheduled time.").option(
|
|
405
435
|
"--draft",
|
|
406
436
|
"Save without publishing. Nothing is sent, nothing counts against your quota, and any problems are listed back"
|
|
@@ -611,6 +641,15 @@ postsCommand.command("update <id>").description(
|
|
|
611
641
|
).option(
|
|
612
642
|
"--first-comment <text>",
|
|
613
643
|
'The comment to post under this one once it publishes. Pass "" to remove the one it has'
|
|
644
|
+
).option(
|
|
645
|
+
"--instagram-placement <placement>",
|
|
646
|
+
`${INSTAGRAM_PLACEMENT_HELP}. On an update this replaces every publishing option the post carries, so a queued reel loses its collaborators, cover and trial-reel setting unless you send them again with --config`
|
|
647
|
+
).option(
|
|
648
|
+
"--facebook-placement <placement>",
|
|
649
|
+
`${FACEBOOK_PLACEMENT_HELP}. On an update this replaces every publishing option the post carries`
|
|
650
|
+
).option(
|
|
651
|
+
"--clear-placement",
|
|
652
|
+
"Put the post back to a plain feed post, dropping every publishing option it carries"
|
|
614
653
|
).option(
|
|
615
654
|
"--keep-draft",
|
|
616
655
|
"Keep a draft a draft, so --schedule-at only changes the time it remembers"
|
|
@@ -619,12 +658,19 @@ postsCommand.command("update <id>").description(
|
|
|
619
658
|
error("Pass either --media or --clear-media, not both");
|
|
620
659
|
process.exit(1);
|
|
621
660
|
}
|
|
622
|
-
if (
|
|
661
|
+
if (opts.clearPlacement && (opts.instagramPlacement !== void 0 || opts.facebookPlacement !== void 0)) {
|
|
662
|
+
error(
|
|
663
|
+
"Pass either --clear-placement or a placement flag, not both"
|
|
664
|
+
);
|
|
665
|
+
process.exit(1);
|
|
666
|
+
}
|
|
667
|
+
if (!opts.text && !opts.media && !opts.clearMedia && opts.firstComment === void 0 && opts.instagramPlacement === void 0 && opts.facebookPlacement === void 0 && !opts.clearPlacement && !opts.scheduleAt && !opts.keepDraft) {
|
|
623
668
|
error(
|
|
624
|
-
"Nothing to change. Pass --text, --media, --clear-media, --first-comment, --schedule-at or --keep-draft"
|
|
669
|
+
"Nothing to change. Pass --text, --media, --clear-media, --first-comment, --instagram-placement, --facebook-placement, --clear-placement, --schedule-at or --keep-draft"
|
|
625
670
|
);
|
|
626
671
|
process.exit(1);
|
|
627
672
|
}
|
|
673
|
+
const configuration = opts.clearPlacement ? {} : placementConfiguration(opts);
|
|
628
674
|
const client = getClient();
|
|
629
675
|
try {
|
|
630
676
|
const media = await resolveMediaArgs(client, opts.media, opts.alt);
|
|
@@ -633,6 +679,7 @@ postsCommand.command("update <id>").description(
|
|
|
633
679
|
...opts.clearMedia ? { media: [] } : {},
|
|
634
680
|
...media ? { media } : {},
|
|
635
681
|
...opts.firstComment !== void 0 ? { first_comment: opts.firstComment } : {},
|
|
682
|
+
...configuration ? { configuration } : {},
|
|
636
683
|
...opts.scheduleAt ? { schedule_at: opts.scheduleAt } : {},
|
|
637
684
|
...opts.timezone ? { timezone: opts.timezone } : {},
|
|
638
685
|
...opts.keepDraft ? { draft: true } : {}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chirpie",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.51",
|
|
4
4
|
"description": "Chirpie CLI: post to social media from the command line",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
],
|
|
45
45
|
"license": "MIT",
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@chirpie/sdk": "^1.0.
|
|
47
|
+
"@chirpie/sdk": "^1.0.48",
|
|
48
48
|
"commander": "^13"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|