feat: parse Facebook marketplace item details and test exports

This commit is contained in:
2026-01-22 19:54:44 -05:00
parent 0a114cf323
commit d8542eb8f7

View File

@@ -830,6 +830,110 @@ function parseFacebookAds(ads: FacebookAdNode[]): ListingDetails[] {
return results;
}
/**
Parse Facebook marketplace item details into ListingDetails format
Updated for 2026 GroupCommerceProductItem structure
*/
function parseFacebookItem(item: FacebookMarketplaceItem): ListingDetails | null {
try {
const title = item.marketplace_listing_title || item.custom_title;
if (!title) return null;
const url = `https://www.facebook.com/marketplace/item/${item.id}`;
// Extract price information
let cents = 0;
let currency = "CAD"; // Default
let amountFormatted = item.formatted_price?.text || "FREE";
if (item.listing_price) {
currency = item.listing_price.currency || "CAD";
if (item.listing_price.amount && item.listing_price.amount !== "0.00") {
const amount = parseFloat(item.listing_price.amount);
if (!isNaN(amount)) {
cents = Math.round(amount * 100);
amountFormatted = item.formatted_price?.text || formatCentsToCurrency(cents);
}
}
}
// Extract description
const description = item.redacted_description?.text;
// Extract location
const address = item.location_text?.text || null;
// Extract seller information
const seller = item.marketplace_listing_seller ? {
name: item.marketplace_listing_seller.name,
id: item.marketplace_listing_seller.id
} : undefined;
// Determine listing status
let listingStatus: string | undefined;
if (item.is_sold) {
listingStatus = "SOLD";
} else if (item.is_pending) {
listingStatus = "PENDING";
} else if (item.is_live) {
listingStatus = "ACTIVE";
} else if (item.is_hidden) {
listingStatus = "HIDDEN";
}
// Format creation date
const creationDate = item.creation_time
? new Date(item.creation_time * 1000).toISOString()
: undefined;
// Determine listing type based on category or vehicle data
let listingType = "item";
if (item.vehicle_make_display_name || item.vehicle_odometer_data) {
listingType = "vehicle";
} else if (item.marketplace_listing_category_id) {
// Could map category IDs to types, but keeping simple for now
listingType = "item";
}
const listingDetails: ListingDetails = {
url,
title,
description,
listingPrice: {
amountFormatted,
cents,
currency,
},
address,
creationDate,
listingType,
listingStatus,
categoryId: item.marketplace_listing_category_id,
seller,
deliveryTypes: item.delivery_types,
};
return listingDetails;
} catch (error) {
console.warn(`Failed to parse Facebook item ${item.id}:`, error);
return null;
}
}
// ----------------------------- Exports for Testing -----------------------------
// Export internal functions for comprehensive testing
export {
extractFacebookItemData,
extractFacebookMarketplaceData,
parseFacebookItem,
parseFacebookAds,
formatCentsToCurrency,
loadFacebookCookies,
formatCookiesForHeader,
parseFacebookCookieString,
ensureFacebookCookies,
};
// ----------------------------- Main -----------------------------
export default async function fetchFacebookItems(