ReviewOS

also looking at this

stacks/postline

feat: crossposting — media (LinkedIn/IG/Threads), OAuth token refresh, and X/Twitter

#30
Merged glennmichael123 wants to merge feat/crosspost-media-and-token-refresh into main
28 files +1810 -109
app/Actions/Postline/CrosspostPublishAction.tsmodified+14-3
Changes to app/Actions/Postline/CrosspostPublishAction.ts
@@ -3,7 +3,7 @@ import type { RequestInstance } from '@stacksjs/types'
33import { Action } from '@stacksjs/actions'
44import { response } from '@stacksjs/router'
55import { crosspost, crosspostProviders } from '../../Services/Social/CrosspostService'
6import { readUploadedImage } from '../../Support/Social/uploads'
6import { persistTempMedia, readUploadedImage, removeTempMedia } from '../../Support/Social/uploads'
77
88export default new Action({
99 name: 'Postline Crosspost Publish',
@@ -35,9 +35,17 @@ export default new Action({
3535 const imageAlt = String(request.get('image_alt') || '').trim()
3636
3737 const media: NonNullable<Parameters<typeof crosspost.publish>[2]>['media'] = []
38 let tempMediaFile: string | null = null
3839 const uploadedImage = await readUploadedImage(request.file?.('image'))
39 if (uploadedImage)
40 media.push({ ...uploadedImage, altText: imageAlt || undefined })
40 if (uploadedImage) {
41 // Persist briefly so URL-only providers (Instagram/Threads) can fetch the
42 // upload server-side; byte-upload providers use the bytes. Removed once
43 // publishing finishes (Meta downloads during container creation, so the
44 // file is safe to delete by then).
45 const temp = await persistTempMedia(uploadedImage.bytes, uploadedImage.mimeType)
46 tempMediaFile = temp?.filename ?? null
47 media.push({ ...uploadedImage, url: temp?.url, altText: imageAlt || undefined })
48 }
4149 if (imageUrl)
4250 media.push({ url: imageUrl, altText: imageAlt || undefined })
4351
@@ -66,5 +74,8 @@ export default new Action({
6674 error: error instanceof Error ? error.message : String(error),
6775 }, { status: 422 })
6876 }
77 finally {
78 if (tempMediaFile) await removeTempMedia(tempMediaFile)
79 }
6980 },
7081})