fix: prevent ENOENT on scheduled reel publishing when local file deleted early

- facebook.ts: use resolvePublicUrl + getMediaBuffer for reels so missing local files fall back to HTTP fetch.
- scheduler.ts: only delete local video files after the last pending scheduled post for that postId is published.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Opus 4.7 committed 2026-05-04 14:08:15 +02:00
1 parent 37aba33425
commit d763be6322
2 files changed
+12 -8

No files matched your search

+3 -5
View File
@@ -72,11 +72,9 @@ export class FacebookService {
throw new Error('Reels require a video media'); throw new Error('Reels require a video media');
} }
// Upload video bytes directly — Facebook cannot fetch local/Docker URLs // Use public URL so getMediaBuffer can fetch via HTTP if local file is missing
const localPath = videoMedia.originalUrl.startsWith('/') const publicUrl = resolvePublicUrl(videoMedia.originalUrl);
? path.join(process.cwd(), videoMedia.originalUrl) const nodeBuffer = await this.getMediaBuffer(publicUrl);
: videoMedia.originalUrl;
const nodeBuffer = await fs.promises.readFile(localPath);
return await this.publishVideoFromBuffer(page, nodeBuffer, post.content); return await this.publishVideoFromBuffer(page, nodeBuffer, post.content);
} else { } else {
// Default to feed // Default to feed
+9 -3
View File
@@ -125,12 +125,18 @@ export class SchedulerService {
status: "published", status: "published",
}); });
// Delete local video files immediately after successful publishing // Delete local video files only when no other unpublished scheduled posts reference them
for (const mediaItem of mediaList) { for (const mediaItem of mediaList) {
if (mediaItem.type === 'video' && mediaItem.cloudinaryPublicId) { if (mediaItem.type === 'video' && mediaItem.cloudinaryPublicId) {
try { try {
await storageService.deleteMedia(mediaItem.cloudinaryPublicId, mediaItem.userId, 'video'); const remainingScheduled = await storage.getScheduledPostsByPost(post.id);
console.log(`[Scheduler] Deleted local video file for media ${mediaItem.id}`); const hasPending = remainingScheduled.some(sp => !sp.publishedAt);
if (!hasPending) {
await storageService.deleteMedia(mediaItem.cloudinaryPublicId, mediaItem.userId, 'video');
console.log(`[Scheduler] Deleted local video file for media ${mediaItem.id}`);
} else {
console.log(`[Scheduler] Kept local video file for media ${mediaItem.id} (pending scheduled posts still exist)`);
}
} catch (err) { } catch (err) {
console.warn(`[Scheduler] Failed to delete local video file for media ${mediaItem.id}:`, err); console.warn(`[Scheduler] Failed to delete local video file for media ${mediaItem.id}:`, err);
} }