From da31d47061c34f5a1eca640295115d546d00e923 Mon Sep 17 00:00:00 2001 From: billisdead Date: Sat, 16 May 2026 21:09:28 +0200 Subject: [PATCH] fix: align POST /posts payload with Postiz public API v1 format Switch from deprecated content/integrations structure to posts[] array with integration.id and value[] fields. Add required shortLink and tags fields. Use globalThis.fetch instead of axios for the POST request. Co-Authored-By: Claude Sonnet 4.6 --- .../postiz-mobile/app/(tabs)/compose.tsx | 51 +++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/artifacts/postiz-mobile/app/(tabs)/compose.tsx b/artifacts/postiz-mobile/app/(tabs)/compose.tsx index c020418..2ddc091 100644 --- a/artifacts/postiz-mobile/app/(tabs)/compose.tsx +++ b/artifacts/postiz-mobile/app/(tabs)/compose.tsx @@ -1,6 +1,5 @@ import { Feather } from "@expo/vector-icons"; import { useQuery, useQueryClient } from "@tanstack/react-query"; -import axios from "axios"; import DateTimePicker from "@react-native-community/datetimepicker"; import * as Haptics from "expo-haptics"; import { Image } from "expo-image"; @@ -111,7 +110,7 @@ export default function ComposeScreen() { }; const handleSubmit = async () => { - if (!client) return; + if (!isConfigured) return; if (!content.trim()) { Alert.alert("Empty post", "Please write something before posting."); return; @@ -130,18 +129,39 @@ export default function ComposeScreen() { media = [{ id: uploaded.id, path: uploaded.path }]; } } - const contentItem: { content: string; image?: Array<{ id: string; path: string }> } = { - content: content.trim(), - }; - if (media.length > 0) contentItem.image = media; - const payload = { type: postNow ? "now" : "schedule", date: postNow ? new Date().toISOString() : scheduleDate.toISOString(), - content: [contentItem], - integrations: selectedChannels, + shortLink: false, + tags: [] as string[], + posts: selectedChannels.map((integrationId) => ({ + integration: { id: integrationId }, + value: [{ content: content.trim(), id: "", image: media }], + })), }; - await client.post("posts", payload); + const body = JSON.stringify(payload); + + // eslint-disable-next-line no-undef + const res = await globalThis.fetch(`${baseUrl}/posts`, { + method: "POST", + headers: { + Authorization: apiKey, + "Content-Type": "application/json", + }, + body, + }); + + if (!res.ok) { + let detail = ""; + try { + const raw = await res.text(); + detail = raw.slice(0, 300); + } catch { + detail = res.statusText; + } + throw new Error(`HTTP ${res.status}: ${detail}`); + } + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); Alert.alert( "Posted!", @@ -152,16 +172,7 @@ export default function ComposeScreen() { queryClient.invalidateQueries({ queryKey: ["posts-list"] }); } catch (e: unknown) { Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error); - let msg = "Could not submit post."; - if (axios.isAxiosError(e)) { - const data = e.response?.data; - const detail = data - ? (typeof data === "string" ? data : (data?.message ?? data?.error ?? JSON.stringify(data))).toString().slice(0, 300) - : e.message; - msg = `HTTP ${e.response?.status ?? "?"}: ${detail}`; - } else if (e instanceof Error) { - msg += `\n${e.message}`; - } + const msg = e instanceof Error ? e.message : "Could not submit post."; Alert.alert("Failed", msg); } finally { setSubmitting(false);