import { ApifyClient } from 'apify-client';
import type { Platform, UnifiedPost } from '../types.js';
import { getConfig } from '../config.js';
export interface ActorConfig {
actorId: string;
platform: Platform;
defaultMaxResults: number;
}
export abstract class BasePlatform {
protected client: ApifyClient;
abstract readonly config: ActorConfig;
constructor() {
this.client = new ApifyClient({ token: getConfig().apifyToken });
}
async scrape(input: Record<string, unknown>): Promise<UnifiedPost[]> {
const run = await this.client.actor(this.config.actorId).call(input);
const { items } = await this.client.dataset(run.defaultDatasetId).listItems();
return this.normalize(items);
}
abstract buildInput(params: Record<string, unknown>): Record<string, unknown>;
abstract normalize(raw: Record<string, unknown>[]): UnifiedPost[];
protected makeId(originalId: string): string {
return `${this.config.platform}:${originalId}`;
}
protected extractHashtags(text: string): string[] {
const matches = text.match(/#[\w\u00C0-\u024F]+/g);
return matches ? matches.map(h => h.toLowerCase()) : [];
}
protected safeNumber(val: unknown): number {
const n = Number(val);
return isNaN(n) ? 0 : n;
}
protected safeString(val: unknown): string {
return typeof val === 'string' ? val : String(val ?? '');
}
protected safeDate(val: unknown): Date {
if (val instanceof Date) return val;
const d = new Date(val as string);
return isNaN(d.getTime()) ? new Date() : d;
}
}