import { BasePlatform, type ActorConfig } from './base.js';
import type { UnifiedPost } from '../types.js';
export class FacebookPlatform extends BasePlatform {
readonly config: ActorConfig = {
actorId: 'apify/facebook-posts-scraper',
platform: 'facebook',
defaultMaxResults: 50,
};
buildInput(params: Record<string, unknown>): Record<string, unknown> {
const input: Record<string, unknown> = {
resultsLimit: params.max_results ?? this.config.defaultMaxResults,
};
if (params.page_urls) {
input.startUrls = (params.page_urls as string[]).map(url => ({ url }));
}
if (params.search) {
input.searchQuery = params.search;
}
return input;
}
normalize(raw: Record<string, unknown>[]): UnifiedPost[] {
return raw.map(item => {
const text = this.safeString(item.text ?? item.message ?? item.postText ?? '');
return {
id: this.makeId(this.safeString(item.postId ?? item.id ?? '')),
platform: 'facebook' as const,
author: {
username: this.safeString(item.pageName ?? item.userName ?? ''),
displayName: this.safeString(item.pageName ?? item.userDisplayName ?? ''),
followers: this.safeNumber(item.pageFollowers ?? item.pageLikes),
verified: Boolean(item.isVerified),
},
content: text,
url: this.safeString(item.postUrl ?? item.url ?? ''),
timestamp: this.safeDate(item.time ?? item.timestamp ?? item.date),
engagement: {
likes: this.safeNumber(item.likes ?? item.reactionsCount),
comments: this.safeNumber(item.comments ?? item.commentsCount),
shares: this.safeNumber(item.shares ?? item.sharesCount),
views: this.safeNumber(item.viewsCount ?? item.views),
},
media: this.extractMedia(item),
hashtags: this.extractHashtags(text),
metadata: {
type: item.type,
pageCategory: item.pageCategory,
isSponsored: item.isSponsored,
},
};
});
}
private extractMedia(item: Record<string, unknown>): { type: 'image' | 'video' | 'text'; urls: string[] } | undefined {
const imageUrl = this.safeString(item.imageUrl ?? item.image ?? '');
const videoUrl = this.safeString(item.videoUrl ?? '');
if (videoUrl) return { type: 'video', urls: [videoUrl, imageUrl].filter(Boolean) };
if (imageUrl) return { type: 'image', urls: [imageUrl] };
return undefined;
}
}