feat: LinkedIn video upload working + static file serving

- Add /public static route to serve files from /vaults/public
- Fix LinkedIn API version: 202501 → 202603 (active version)
- OpenAPI schema already included POST /api/linkedin/video
- Successfully posted Remotion video to LinkedIn
This commit is contained in:
Garfield
2026-05-11 13:14:42 -04:00
parent c2eabd8e66
commit de9d74bb2b
3 changed files with 29 additions and 2 deletions

View File

@@ -133,7 +133,7 @@ async function linkedinRestRequest(
headers: { headers: {
'Authorization': `Bearer ${accessToken}`, 'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'LinkedIn-Version': '202501', 'LinkedIn-Version': '202603',
'X-Restli-Protocol-Version': '2.0.0', 'X-Restli-Protocol-Version': '2.0.0',
}, },
body: body ? JSON.stringify(body) : undefined, body: body ? JSON.stringify(body) : undefined,
@@ -224,7 +224,7 @@ export async function createVideoPost(
headers: { headers: {
'Authorization': `Bearer ${accessToken}`, 'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'LinkedIn-Version': '202501', 'LinkedIn-Version': '202603',
'X-Restli-Protocol-Version': '2.0.0', 'X-Restli-Protocol-Version': '2.0.0',
}, },
body: JSON.stringify({ body: JSON.stringify({

View File

@@ -35,6 +35,9 @@ app.use(cors({
app.use(express.json()); app.use(express.json());
app.use(express.urlencoded({ extended: true })); app.use(express.urlencoded({ extended: true }));
// ── Static files (videos, assets) ──────────────────────────────────────────
app.use('/public', express.static('/vaults/public'));
// ── Config ───────────────────────────────────────────────────────────────── // ── Config ─────────────────────────────────────────────────────────────────
const PORT = process.env.PORT ?? 3456; const PORT = process.env.PORT ?? 3456;
const SERVER_URL = process.env.SERVER_URL ?? `http://localhost:${PORT}`; const SERVER_URL = process.env.SERVER_URL ?? `http://localhost:${PORT}`;

View File

@@ -342,6 +342,30 @@ export function getOpenApiSpec(serverUrl: string) {
responses: { '200': { description: 'Post created' } }, responses: { '200': { description: 'Post created' } },
}, },
}, },
'/api/linkedin/video': {
post: {
operationId: 'linkedin_upload_video',
summary: 'Upload video and create LinkedIn post',
requestBody: {
required: true,
content: {
'application/json': {
schema: {
type: 'object',
required: ['video_url', 'text'],
properties: {
video_url: { type: 'string', description: 'Publicly accessible URL of the MP4 video' },
text: { type: 'string' },
visibility: { type: 'string', enum: ['PUBLIC', 'CONNECTIONS'] },
account: { type: 'string' },
},
},
},
},
},
responses: { '200': { description: 'Video uploaded and posted' } },
},
},
// ── Telegram ──────────────────────────────────────────────── // ── Telegram ────────────────────────────────────────────────
'/api/telegram/message': { '/api/telegram/message': {