← back to Designer Wallcoverings
DW-Agents/dw-agents/fetch-real-amazon-orders.ts
310 lines
/**
* Real Amazon Order Fetcher using Puppeteer
* Logs into Amazon accounts and fetches actual order history
*/
import puppeteer from 'puppeteer';
import * as fs from 'fs';
interface Order {
id: string;
item: string;
vendor: string;
price: number;
status: string;
timestamp: Date;
orderUrl?: string;
tracking?: string;
}
interface AmazonAccount {
email: string;
password: string;
type: 'Personal' | 'Business';
}
const PERSONAL_ACCOUNT: AmazonAccount = {
email: 'nataliaabrams@gmail.com',
password: 'Urbanon341',
type: 'Personal'
};
const BUSINESS_ACCOUNT: AmazonAccount = {
email: 'info@designerwallcoverings.com',
password: '*Amazonaccess911*',
type: 'Business'
};
/**
* Fetch orders from Amazon account using Puppeteer
*/
async function fetchOrdersFromAccount(account: AmazonAccount): Promise<Order[]> {
const orders: Order[] = [];
console.log(`\n🔐 Logging into Amazon ${account.type} account: ${account.email}`);
const browser = await puppeteer.launch({
headless: true,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--disable-gpu',
'--window-size=1920x1080'
]
});
try {
const page = await browser.newPage();
// Set user agent to avoid bot detection
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36');
// Set viewport
await page.setViewport({ width: 1920, height: 1080 });
console.log('📄 Navigating to Amazon sign-in page...');
// Go to Amazon sign-in page
await page.goto('https://www.amazon.com/ap/signin?openid.pape.max_auth_age=0&openid.return_to=https%3A%2F%2Fwww.amazon.com%2F%3Fref_%3Dnav_ya_signin&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.assoc_handle=usflex&openid.mode=checkid_setup&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0', {
waitUntil: 'networkidle2',
timeout: 30000
});
console.log('✍️ Entering credentials...');
// Wait for email input
await page.waitForSelector('#ap_email', { timeout: 10000 });
await page.type('#ap_email', account.email);
await page.click('#continue');
// Wait for password input
await page.waitForSelector('#ap_password', { timeout: 10000 });
await page.type('#ap_password', account.password);
// Click sign in button
await page.click('#signInSubmit');
console.log('⏳ Waiting for login to complete...');
// Wait for navigation after login (or CAPTCHA)
try {
await page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 15000 });
} catch (e) {
console.log('⚠️ Navigation timeout - checking page state...');
}
// Check if we hit a CAPTCHA or 2FA
const url = page.url();
if (url.includes('ap/challenge') || url.includes('ap/cvf')) {
console.log('⚠️ Amazon requires additional verification (CAPTCHA/2FA)');
console.log('📝 Manual intervention needed. Please:');
console.log(' 1. Run this script in non-headless mode (headless: false)');
console.log(' 2. Complete CAPTCHA/2FA manually');
console.log(' 3. Or save browser cookies for reuse');
// Take a screenshot for debugging
await page.screenshot({ path: '/root/Projects/Designer-Wallcoverings/DW-Agents/data/amazon-login-captcha.png' });
console.log('📸 Screenshot saved: /root/Projects/Designer-Wallcoverings/DW-Agents/data/amazon-login-captcha.png');
return orders;
}
console.log('✅ Login successful! Navigating to order history...');
// Go to order history page
await page.goto('https://www.amazon.com/gp/your-account/order-history', {
waitUntil: 'networkidle2',
timeout: 30000
});
console.log('📦 Parsing order history...');
// Take screenshot for debugging
await page.screenshot({ path: `/root/Projects/Designer-Wallcoverings/DW-Agents/data/amazon-orders-${account.type}.png`, fullPage: true });
console.log(`📸 Screenshot saved: /root/Projects/Designer-Wallcoverings/DW-Agents/data/amazon-orders-${account.type}.png`);
// Save HTML for debugging
const html = await page.content();
fs.writeFileSync(`/root/Projects/Designer-Wallcoverings/DW-Agents/data/amazon-orders-${account.type}.html`, html);
console.log(`💾 HTML saved: /root/Projects/Designer-Wallcoverings/DW-Agents/data/amazon-orders-${account.type}.html`);
// Wait for page to load completely
await page.waitForTimeout(3000);
// Try multiple selectors for orders
const hasOrders = await page.evaluate(() => {
return document.querySelector('.order') !== null ||
document.querySelector('[data-order-id]') !== null ||
document.querySelector('.order-card') !== null;
});
console.log(`📦 Orders found on page: ${hasOrders}`);
// Extract order data with multiple fallback selectors
const orderData = await page.evaluate(() => {
const orders: any[] = [];
// Try modern Amazon layout first
const orderCards = document.querySelectorAll('[data-order-id], .order-card, .order');
orderCards.forEach((orderEl) => {
try {
// Get order ID - try multiple selectors
let orderId = orderEl.getAttribute('data-order-id') || '';
if (!orderId) {
const orderIdEl = orderEl.querySelector('.yohtmlc-order-id span:last-child, .order-info-value, bdi');
orderId = orderIdEl?.textContent?.trim() || '';
}
// Get all text content and look for order ID pattern
if (!orderId) {
const text = orderEl.textContent || '';
const orderMatch = text.match(/\d{3}-\d{7}-\d{7}/);
if (orderMatch) orderId = orderMatch[0];
}
// Get order date
let orderDateText = '';
const orderDateEl = orderEl.querySelector('.order-info .a-color-secondary.value, .a-span3 .a-color-secondary, [class*="date"]');
orderDateText = orderDateEl?.textContent?.trim() || '';
// Get order total
let orderTotalText = '';
const orderTotalEl = orderEl.querySelector('.yohtmlc-order-total .value, .grand-total-price, [class*="total"]');
orderTotalText = orderTotalEl?.textContent?.trim() || '';
// Get items in this order - try multiple selectors
const itemElements = orderEl.querySelectorAll('.a-fixed-left-grid-inner, .shipment-item, [class*="product"], .item-view-left-col-inner');
if (itemElements.length === 0) {
// Try getting product titles directly
const titleEls = orderEl.querySelectorAll('a[class*="title"], .product-title, [class*="product-link"]');
titleEls.forEach((titleEl) => {
const itemName = titleEl.textContent?.trim() || '';
if (itemName && orderId) {
orders.push({
id: orderId,
item: itemName,
orderDate: orderDateText,
total: orderTotalText
});
}
});
} else {
itemElements.forEach((itemEl) => {
const itemNameEl = itemEl.querySelector('.yohtmlc-product-title, .product-title, a[class*="title"]');
const itemName = itemNameEl?.textContent?.trim() || '';
if (itemName && orderId) {
orders.push({
id: orderId,
item: itemName,
orderDate: orderDateText,
total: orderTotalText
});
}
});
}
} catch (e) {
console.error('Error parsing order:', e);
}
});
return orders;
});
console.log(`✅ Found ${orderData.length} items from orders`);
// Convert to Order format
orderData.forEach((data) => {
try {
const priceMatch = data.total.match(/[\d.]+/);
const price = priceMatch ? parseFloat(priceMatch[0]) : 0;
orders.push({
id: data.id,
item: data.item,
vendor: account.type === 'Business' ? 'Amazon Business' : 'Amazon.com',
price: price,
status: 'Delivered',
timestamp: new Date(data.orderDate || Date.now()),
orderUrl: `https://www.amazon.com/gp/your-account/order-details?orderID=${data.id}`
});
} catch (e) {
console.error('Error converting order:', e);
}
});
} catch (error) {
console.error(`❌ Error fetching orders from ${account.type} account:`, error);
// Take screenshot for debugging
try {
const page = (await browser.pages())[0];
await page.screenshot({ path: `/root/Projects/Designer-Wallcoverings/DW-Agents/data/amazon-error-${account.type}.png` });
console.log(`📸 Error screenshot saved: /root/Projects/Designer-Wallcoverings/DW-Agents/data/amazon-error-${account.type}.png`);
} catch (e) {}
} finally {
await browser.close();
}
return orders;
}
/**
* Fetch orders from all accounts
*/
async function fetchAllAmazonOrders(): Promise<void> {
console.log('🚀 Starting Amazon Order Fetcher with Puppeteer\n');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
const allOrders: Order[] = [];
// Fetch from Personal account
console.log('📱 Fetching Personal Account Orders...');
const personalOrders = await fetchOrdersFromAccount(PERSONAL_ACCOUNT);
allOrders.push(...personalOrders);
console.log(`\n✅ Personal Account: ${personalOrders.length} orders\n`);
// Wait a bit between accounts to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 5000));
// Fetch from Business account
console.log('🏢 Fetching Business Account Orders...');
const businessOrders = await fetchOrdersFromAccount(BUSINESS_ACCOUNT);
allOrders.push(...businessOrders);
console.log(`\n✅ Business Account: ${businessOrders.length} orders\n`);
// Save to file
const outputPath = '/root/Projects/Designer-Wallcoverings/DW-Agents/data/amazon-orders.json';
if (allOrders.length > 0) {
// Sort by date (newest first)
allOrders.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
fs.writeFileSync(outputPath, JSON.stringify(allOrders, null, 2));
console.log(`\n✅ Saved ${allOrders.length} orders to: ${outputPath}`);
console.log('\n📊 Sample Orders:');
allOrders.slice(0, 5).forEach((order, idx) => {
console.log(` ${idx + 1}. ${order.item} - $${order.price.toFixed(2)} (${order.vendor})`);
});
} else {
console.log('\n⚠️ No orders fetched. Check screenshots in /root/Projects/Designer-Wallcoverings/DW-Agents/data/ for debugging');
}
console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('✅ Amazon order fetch complete!');
}
// Run if called directly
if (require.main === module) {
fetchAllAmazonOrders().catch(console.error);
}
export { fetchAllAmazonOrders, fetchOrdersFromAccount };