diff --git a/modules/rsocials/lib/postiz-client.ts b/modules/rsocials/lib/postiz-client.ts index 4d83907c..18b6b22f 100644 --- a/modules/rsocials/lib/postiz-client.ts +++ b/modules/rsocials/lib/postiz-client.ts @@ -60,7 +60,7 @@ export async function getIntegrations(config: PostizConfig) { /** POST /public/v1/posts — create a single post (draft, schedule, or now). * * Postiz expects a nested shape: - * { type, date, shortLink, tags, posts: [{ integration: {id}, value: [{content}], settings: {__type} }] } + * { type, date, shortLink, tags, posts: [{ integration: {id}, value: [{content}], settings: {__type, ...} }] } * * Callers pass integrations as {id, identifier} tuples; identifier populates * settings.__type which Postiz uses to route to the correct provider handler. @@ -70,6 +70,32 @@ export interface PostizIntegrationRef { identifier: string; // e.g. 'x', 'linkedin', 'bluesky' } +// Platform-specific settings Postiz validates on POST /posts. Keys that are +// required-non-empty for each provider live here. We merge defaults when the +// caller doesn't supply overrides. +function defaultSettingsFor(identifier: string): Record { + const base: Record = { __type: identifier }; + switch (identifier) { + case 'x': + base.who_can_reply_post = 'everyone'; + break; + case 'linkedin': + base.post_to_company = false; + break; + case 'instagram': + base.post_type = 'post'; + break; + case 'youtube': + base.type = 'public'; + base.title = ''; + base.category = '22'; + break; + // Others (bluesky, threads, mastodon, reddit, ...) don't require settings + // beyond __type as of Postiz 5.x. + } + return base; +} + export async function createPost( config: PostizConfig, payload: { @@ -89,7 +115,7 @@ export async function createPost( integration: { id: integ.id }, value: [{ content: payload.content, image: [] as unknown[] }], ...(payload.group ? { group: payload.group } : {}), - settings: { __type: integ.identifier }, + settings: defaultSettingsFor(integ.identifier), })), }; const res = await postizFetch(config, "/public/v1/posts", { @@ -153,7 +179,7 @@ export async function createThread( posts: opts.integrations.map(integ => ({ integration: { id: integ.id }, value: tweets.map(t => ({ content: t, image: [] as unknown[] })), - settings: { __type: integ.identifier }, + settings: defaultSettingsFor(integ.identifier), })), }; const res = await postizFetch(config, "/public/v1/posts", {