mirror of
https://github.com/gitroomhq/postiz-agent.git
synced 2026-09-14 13:46:24 +08:00
feat: add posts:settings command to patch a post's provider settings
Add `postiz posts:settings <id> --settings '<json>'` calling PUT /public/v1/posts/:id/settings to patch a post's provider-specific settings without recreating it. Modeled on the existing posts:status command. Settings are merged server-side (only passed keys change); only DRAFT/QUEUE posts can be updated. Also document that posts:list responses now include each post's current `settings` (returned as a JSON string). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,14 @@ All notable changes to the Postiz CLI will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- `posts:settings` - Update a post's provider settings via `PUT /public/v1/posts/:id/settings` (merged — only the keys you pass change; unpublished DRAFT/QUEUE posts only).
|
||||
|
||||
### Changed
|
||||
- `posts:list` responses now include each post's current `settings`.
|
||||
|
||||
## [1.0.0] - 2026-02-13
|
||||
|
||||
### Added
|
||||
|
||||
@@ -183,7 +183,7 @@ postiz posts:list --startDate "2024-01-01T00:00:00Z" --endDate "2024-12-31T23:59
|
||||
postiz posts:list --customer "customer-id"
|
||||
```
|
||||
|
||||
Defaults to last 30 days to next 30 days if dates not specified.
|
||||
Defaults to last 30 days to next 30 days if dates not specified. Each returned post includes its current `settings` (returned as a JSON string — `JSON.parse` it). The intended workflow is `posts:list` (read current settings) → `posts:settings` (patch them).
|
||||
|
||||
**Delete post**
|
||||
```bash
|
||||
@@ -198,6 +198,14 @@ postiz posts:status <post-id> --status schedule
|
||||
|
||||
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.
|
||||
|
||||
**Update a post's provider-specific settings**
|
||||
```bash
|
||||
postiz posts:settings <post-id> --settings '{"content_posting_method":"DIRECT_POST"}'
|
||||
postiz posts:settings <post-id> --settings '{"subreddit":[{"value":{"subreddit":"/r/selfhosted","title":"My title","type":"self","is_flair_required":true}}]}'
|
||||
```
|
||||
|
||||
Patches a post's settings server-side. The backend **merges** the object — only the keys you pass change, everything else is preserved — so pass a partial object, not the full settings blob. Only **DRAFT/QUEUE** (unpublished) posts can be updated; published posts are rejected. Pass the **main post id**, not a comment id. Do **not** include `__type` — the backend adds it automatically from the integration.
|
||||
|
||||
---
|
||||
|
||||
### Analytics
|
||||
@@ -560,6 +568,7 @@ The CLI interacts with these Postiz API endpoints:
|
||||
| `/public/v1/posts` | POST | Create a post |
|
||||
| `/public/v1/posts` | GET | List posts |
|
||||
| `/public/v1/posts/:id` | DELETE | Delete a post |
|
||||
| `/public/v1/posts/:id/settings` | PUT | Update a post's provider settings (merged; unpublished only) |
|
||||
| `/public/v1/posts/:id/missing` | GET | Get missing content from provider |
|
||||
| `/public/v1/posts/:id/release-id` | PUT | Update release ID for a post |
|
||||
| `/public/v1/integrations` | GET | List integrations (optional `?group=` filter) |
|
||||
@@ -679,6 +688,7 @@ postiz posts:list # List posts
|
||||
postiz posts:delete <id> # Delete post
|
||||
postiz posts:status <id> --status draft # Move to draft (stops workflow)
|
||||
postiz posts:status <id> --status schedule # Queue draft for publishing
|
||||
postiz posts:settings <id> --settings '{}' # Patch a post's settings (merged; DRAFT/QUEUE only)
|
||||
postiz upload <file> # Upload media
|
||||
|
||||
# Analytics
|
||||
|
||||
@@ -194,6 +194,8 @@ postiz posts:create --json post.json
|
||||
|
||||
```bash
|
||||
# List posts (defaults to last 30 days to next 30 days)
|
||||
# Each returned post includes its current `settings` (as a JSON string — JSON.parse it).
|
||||
# Workflow: run posts:list to read a post's current settings, then posts:settings to patch them.
|
||||
postiz posts:list
|
||||
|
||||
# List posts in date range
|
||||
@@ -205,6 +207,12 @@ postiz posts:delete <post-id>
|
||||
# Change post status (draft ↔ schedule)
|
||||
postiz posts:status <post-id> --status draft # Move back to draft, terminates any running publish workflow
|
||||
postiz posts:status <post-id> --status schedule # Promote a draft into the publishing queue (uses the post's stored date)
|
||||
|
||||
# Update a post's provider-specific settings (merged — only the keys you pass change)
|
||||
# Only DRAFT/QUEUE (unpublished) posts can be updated. Pass the MAIN post id, not a comment id.
|
||||
# Do NOT include __type — the backend adds it automatically from the integration.
|
||||
postiz posts:settings <post-id> --settings '{"content_posting_method":"DIRECT_POST"}' # Switch a TikTok draft to direct publishing
|
||||
postiz posts:settings <post-id> --settings '{"subreddit":[{"value":{"subreddit":"/r/selfhosted","title":"My title","type":"self","is_flair_required":true}}]}' # Set a Reddit post's subreddit
|
||||
```
|
||||
|
||||
### Analytics
|
||||
@@ -749,6 +757,7 @@ https://clawhub.ai/nevo-david/agent-media
|
||||
9. **Required settings** - Some platforms require specific settings (Reddit needs title, YouTube needs title)
|
||||
10. **Media MIME types** - CLI auto-detects from file extension, ensure correct extension
|
||||
11. **Analytics returns `{"missing": true}`** - The post was published but the platform didn't return a post ID. Run `posts:missing <post-id>` to get available content, then `posts:connect <post-id> --release-id "<id>"` to link it. Analytics will work after connecting.
|
||||
12. **`posts:settings` merges** - Only the keys you pass change; everything else on the post is preserved, so pass a partial object, not the full settings blob. Only **DRAFT/QUEUE** (unpublished) posts can be updated — published posts are rejected. Pass the **main post id**, not a comment id. Never include `__type` — the backend adds it automatically from the integration.
|
||||
|
||||
---
|
||||
|
||||
@@ -781,6 +790,7 @@ postiz posts:list # List posts
|
||||
postiz posts:delete <id> # Delete post
|
||||
postiz posts:status <id> --status draft # Move to draft (stops workflow)
|
||||
postiz posts:status <id> --status schedule # Queue draft for publishing
|
||||
postiz posts:settings <id> --settings '{}' # Patch a post's settings (merged; DRAFT/QUEUE only)
|
||||
postiz upload <file> # Upload media
|
||||
|
||||
# Analytics
|
||||
|
||||
@@ -157,6 +157,13 @@ export class PostizAPI {
|
||||
});
|
||||
}
|
||||
|
||||
async updatePostSettings(postId: string, settings: Record<string, any>) {
|
||||
return this.request(`/public/v1/posts/${postId}/settings`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ settings }),
|
||||
});
|
||||
}
|
||||
|
||||
async getAnalytics(integrationId: string, date: string) {
|
||||
return this.request(`/public/v1/analytics/${integrationId}?date=${encodeURIComponent(date)}`, {
|
||||
method: 'GET',
|
||||
|
||||
@@ -205,6 +205,39 @@ export async function changePostStatus(args: any) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function updatePostSettings(args: any) {
|
||||
const config = getConfig();
|
||||
const api = new PostizAPI(config);
|
||||
|
||||
if (!args.id) {
|
||||
console.error('❌ Post ID is required');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!args.settings) {
|
||||
console.error('❌ --settings is required');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let settings: any;
|
||||
try {
|
||||
settings = JSON.parse(args.settings);
|
||||
} catch (error: any) {
|
||||
console.error('❌ Failed to parse settings JSON:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await api.updatePostSettings(args.id, settings);
|
||||
console.log(`✅ Post ${args.id} settings updated`);
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
return result;
|
||||
} catch (error: any) {
|
||||
console.error('❌ Failed to update post settings:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
export async function deletePost(args: any) {
|
||||
const config = getConfig();
|
||||
const api = new PostizAPI(config);
|
||||
|
||||
+26
-1
@@ -1,6 +1,6 @@
|
||||
import yargs from 'yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
import { createPost, listPosts, deletePost, getMissingContent, connectPost, changePostStatus } from './commands/posts';
|
||||
import { createPost, listPosts, deletePost, getMissingContent, connectPost, changePostStatus, updatePostSettings } from './commands/posts';
|
||||
import { listIntegrations, listGroups, getIntegrationSettings, triggerIntegrationTool } from './commands/integrations';
|
||||
import { getAnalytics, getPostAnalytics } from './commands/analytics';
|
||||
import { uploadFile } from './commands/upload';
|
||||
@@ -202,6 +202,31 @@ yargs(hideBin(process.argv))
|
||||
},
|
||||
changePostStatus as any
|
||||
)
|
||||
.command(
|
||||
'posts:settings <id>',
|
||||
'Update a post\'s provider-specific settings (merged; only unpublished draft/scheduled posts)',
|
||||
(yargs: Argv) => {
|
||||
return yargs
|
||||
.positional('id', {
|
||||
describe: 'Post ID',
|
||||
type: 'string',
|
||||
})
|
||||
.option('settings', {
|
||||
describe: 'Partial settings as a JSON string — only the keys you pass change; do not include __type',
|
||||
type: 'string',
|
||||
demandOption: true,
|
||||
})
|
||||
.example(
|
||||
'$0 posts:settings post-123 --settings \'{"content_posting_method":"DIRECT_POST"}\'',
|
||||
'Switch a TikTok draft to direct publishing'
|
||||
)
|
||||
.example(
|
||||
'$0 posts:settings post-123 --settings \'{"subreddit":[{"value":{"subreddit":"/r/selfhosted","title":"My title","type":"self","is_flair_required":true}}]}\'',
|
||||
'Set a Reddit post\'s subreddit'
|
||||
);
|
||||
},
|
||||
updatePostSettings as any
|
||||
)
|
||||
.command(
|
||||
'posts:connect <id>',
|
||||
'Connect a post to its published content by updating the release ID',
|
||||
|
||||
Reference in New Issue
Block a user