Add ability to post videos to Facebook feeds and stories

Adds support for publishing video content to Facebook feeds and stories via new API endpoints and service methods, addressing issues with video previews and direct video uploads.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: ae4037a0-2a6f-4530-9bac-79b543286bda
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/397bca8c-984f-43ff-841a-10897aeb8140/ae4037a0-2a6f-4530-9bac-79b543286bda/s8IyLQK
This commit is contained in:
michaelschal committed 2025-10-13 12:05:51 +00:00
1 parent 68ed5d52d4
commit b1dc815954
1 file changed
+63 -6
+63 -6
View File
@@ -10,6 +10,11 @@ interface FacebookFeedResponse {
id: string;
}
interface FacebookVideoResponse {
id: string;
post_id?: string;
}
interface FacebookError {
error: {
message: string;
@@ -54,8 +59,8 @@ export class FacebookService {
return storyIds.join(',');
} else {
// Default to feed
// Count images only (videos not supported in multi-photo carousel)
const imageMedia = mediaList.filter(m => m.type === 'image');
const videoMedia = mediaList.filter(m => m.type === 'video');
if (imageMedia.length > 1) {
// Multi-photo carousel (images only)
@@ -63,11 +68,9 @@ export class FacebookService {
} else if (imageMedia.length === 1) {
// Single image (even if mixed with videos, prioritize the image)
return await this.publishPhotoPost(post, page, imageMedia[0]);
} else if (mediaList.length >= 1) {
// No images, but has media (likely video) - publish first media
// Note: Facebook /photos endpoint doesn't support videos well, this may fail
console.warn(`Publishing non-image media to Facebook feed - this may fail`);
return await this.publishPhotoPost(post, page, mediaList[0]);
} else if (videoMedia.length >= 1) {
// Video post - use video endpoint
return await this.publishVideoPost(post, page, videoMedia[0]);
} else {
// Text only
return await this.publishTextPost(post, page);
@@ -122,6 +125,32 @@ export class FacebookService {
return data.post_id || data.id;
}
private async publishVideoPost(post: Post, page: SocialPage, media: Media): Promise<string> {
// Use original URL for video
const videoUrl = media.originalUrl;
const params = new URLSearchParams({
access_token: page.accessToken!,
description: post.content,
file_url: videoUrl,
});
const url = `${this.baseUrl}/${page.pageId}/videos?${params.toString()}`;
const response = await fetch(url, {
method: 'POST',
});
if (!response.ok) {
const error = await response.json() as FacebookError;
throw new Error(`Facebook API error publishing video: ${error.error.message} (code: ${error.error.code})`);
}
const data = await response.json() as FacebookVideoResponse;
// Return the post_id or id
return data.post_id || data.id;
}
private async publishMultiPhotoPost(post: Post, page: SocialPage, mediaList: Media[]): Promise<string> {
// Validate that all media are images
const imageMedia = mediaList.filter(m => m.type === 'image');
@@ -279,6 +308,10 @@ export class FacebookService {
}
private async publishStory(post: Post, page: SocialPage, media: Media): Promise<string> {
if (media.type === 'video') {
return this.publishVideoStory(post, page, media);
}
// Stories require a 2-step process:
// Step 1: Upload photo as unpublished to get photo_id
// Step 2: Publish the photo as a story using the photo_id
@@ -326,6 +359,30 @@ export class FacebookService {
const storyData = await storyResponse.json() as { success: boolean; post_id: string };
return storyData.post_id;
}
private async publishVideoStory(post: Post, page: SocialPage, media: Media): Promise<string> {
// Video stories can be published directly to the video_stories endpoint
const videoUrl = media.originalUrl;
const params = new URLSearchParams({
access_token: page.accessToken!,
file_url: videoUrl,
});
const url = `${this.baseUrl}/${page.pageId}/video_stories?${params.toString()}`;
const response = await fetch(url, {
method: 'POST',
});
if (!response.ok) {
const error = await response.json() as FacebookError;
throw new Error(`Facebook API error publishing video story: ${error.error.message} (code: ${error.error.code})`);
}
const data = await response.json() as { success: boolean; post_id: string };
return data.post_id;
}
}
export const facebookService = new FacebookService();