← back to Designer Wallcoverings
DW-Agents/dw-agents/agent-new-client-signup/shopify-customers.ts
213 lines
/**
* Shopify Customer Data Fetcher
* Fetches real customer data from Shopify store
*/
import fetch from 'node-fetch';
const SHOPIFY_STORE_DOMAIN = process.env.SHOPIFY_STORE_DOMAIN || 'designer-laboratory-sandbox.myshopify.com';
const SHOPIFY_ACCESS_TOKEN = process.env.SHOPIFY_ACCESS_TOKEN || '';
export interface ShopifyCustomer {
id: number;
email: string;
first_name: string;
last_name: string;
created_at: string;
updated_at: string;
orders_count: number;
total_spent: string;
phone?: string;
company?: string;
city?: string;
province?: string;
country?: string;
tags?: string;
note?: string;
}
export interface CustomerSignup {
timestamp: Date;
customerName: string;
email: string;
company: string;
interest: string;
source: string;
phone?: string;
location?: string;
ordersCount: number;
totalSpent: string;
tags?: string;
}
/**
* Fetch customers from Shopify Orders API (since customer API requires different permissions)
*/
export async function fetchShopifyCustomers(limit: number = 50): Promise<ShopifyCustomer[]> {
try {
const url = `https://${SHOPIFY_STORE_DOMAIN}/admin/api/2024-01/orders.json?limit=${limit}&status=any&order=created_at desc`;
console.log('🛍️ Fetching customers from Shopify orders...');
const response = await fetch(url, {
method: 'GET',
headers: {
'X-Shopify-Access-Token': SHOPIFY_ACCESS_TOKEN,
'Content-Type': 'application/json',
},
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Shopify API error: ${response.status} ${response.statusText} - ${errorText}`);
}
const data = await response.json() as { orders: any[] };
console.log(`✅ Fetched ${data.orders.length} orders from Shopify`);
// Extract unique customers from orders
const customerMap = new Map<number, ShopifyCustomer>();
for (const order of data.orders) {
if (order.customer && order.customer.id) {
const customer = order.customer;
if (!customerMap.has(customer.id) || new Date(order.created_at) > new Date(customerMap.get(customer.id)!.created_at)) {
customerMap.set(customer.id, {
id: customer.id,
email: customer.email,
first_name: customer.first_name,
last_name: customer.last_name,
created_at: customer.created_at || order.created_at,
updated_at: customer.updated_at || order.updated_at,
orders_count: customer.orders_count || 1,
total_spent: customer.total_spent || order.total_price,
phone: customer.phone || order.billing_address?.phone,
company: order.billing_address?.company || order.shipping_address?.company,
city: order.billing_address?.city || order.shipping_address?.city,
province: order.billing_address?.province || order.shipping_address?.province,
country: order.billing_address?.country || order.shipping_address?.country,
tags: customer.tags,
note: customer.note
});
}
}
}
const customers = Array.from(customerMap.values());
console.log(`✅ Extracted ${customers.length} unique customers from orders`);
return customers;
} catch (error) {
console.error('❌ Error fetching Shopify customers:', error);
return [];
}
}
/**
* Fetch recent customer signups (last 30 days)
*/
export async function fetchRecentSignups(days: number = 30): Promise<CustomerSignup[]> {
try {
const customers = await fetchShopifyCustomers(250);
// Filter for recent signups
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - days);
const recentCustomers = customers.filter(customer => {
const createdDate = new Date(customer.created_at);
return createdDate >= cutoffDate;
});
// Convert to signup format
const signups: CustomerSignup[] = recentCustomers.map(customer => {
const name = `${customer.first_name || ''} ${customer.last_name || ''}`.trim() || 'Anonymous';
const location = [customer.city, customer.province, customer.country]
.filter(Boolean)
.join(', ');
// Determine interest based on tags or note
let interest = 'General wallpaper inquiry';
if (customer.tags) {
if (customer.tags.includes('grasscloth')) interest = 'Grasscloth wallpaper';
else if (customer.tags.includes('flocked')) interest = 'Flocked wallpaper';
else if (customer.tags.includes('beaded')) interest = 'Glass beaded wallpaper';
else if (customer.tags.includes('suede')) interest = 'Novasuede wallpaper';
}
// Determine source
let source = 'Website Form';
if (customer.note?.includes('phone')) source = 'Phone Inquiry';
else if (customer.note?.includes('email')) source = 'Email Inquiry';
else if (customer.tags?.includes('wholesale')) source = 'Wholesale';
return {
id: customer.id,
timestamp: new Date(customer.created_at),
customerName: name,
email: customer.email || 'N/A',
company: customer.company || 'Individual',
interest,
source,
phone: customer.phone,
location: location || 'N/A',
ordersCount: customer.orders_count,
totalSpent: customer.total_spent,
tags: customer.tags,
};
});
// Sort by timestamp, newest first
signups.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
console.log(`✅ Converted ${signups.length} recent signups`);
return signups;
} catch (error) {
console.error('❌ Error fetching recent signups:', error);
return [];
}
}
/**
* Get signup statistics
*/
export function getSignupStats(signups: CustomerSignup[]) {
const now = new Date();
const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const weekStart = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
return {
today: signups.filter(s => s.timestamp >= todayStart).length,
thisWeek: signups.filter(s => s.timestamp >= weekStart).length,
thisMonth: signups.filter(s => s.timestamp >= monthStart).length,
total: signups.length,
};
}
// Test function
if (require.main === module) {
(async () => {
console.log('🧪 Testing Shopify customer fetcher...\n');
const signups = await fetchRecentSignups(30);
console.log(`\n📊 Found ${signups.length} signups in last 30 days`);
const stats = getSignupStats(signups);
console.log('\n📈 Stats:');
console.log(` Today: ${stats.today}`);
console.log(` This Week: ${stats.thisWeek}`);
console.log(` This Month: ${stats.thisMonth}`);
console.log(` Total: ${stats.total}`);
if (signups.length > 0) {
console.log('\n👤 Most Recent Signup:');
const recent = signups[0];
console.log(` Name: ${recent.customerName}`);
console.log(` Email: ${recent.email}`);
console.log(` Company: ${recent.company}`);
console.log(` Date: ${recent.timestamp.toLocaleString()}`);
}
})();
}