feat: parse Facebook marketplace item details and test exports
This commit is contained in:
104
src/facebook.ts
104
src/facebook.ts
@@ -830,6 +830,110 @@ function parseFacebookAds(ads: FacebookAdNode[]): ListingDetails[] {
|
|||||||
return results;
|
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 -----------------------------
|
// ----------------------------- Main -----------------------------
|
||||||
|
|
||||||
export default async function fetchFacebookItems(
|
export default async function fetchFacebookItems(
|
||||||
|
|||||||
Reference in New Issue
Block a user