← back to Handbag Auth Nextjs

AFFILIATE_RSS_SETUP.md

412 lines

# Handbag Affiliate & RSS Feed System

Complete guide for managing affiliate programs and RSS feeds for luxury handbag marketplace data.

## Overview

This system provides:
1. **RSS Feed Polling** - Automated monitoring of new handbag listings from resellers, auctions, and news
2. **Affiliate Management** - Track and manage affiliate partnerships with handbag merchants
3. **Price Comparison UI** - React component for displaying offers across multiple merchants
4. **Affiliate Signup Automation** - Puppeteer-based form filling for affiliate applications

---

## Quick Start

### 1. Install Dependencies

```bash
npm install
```

Required packages:
- `rss-parser` - Parse RSS/Atom feeds
- `puppeteer` - Browser automation for affiliate signups

### 2. Import Affiliate Programs

```bash
npm run affiliates:import
```

This imports merchant data from `data/handbag_merchants.csv` into your affiliate registry.

### 3. Poll RSS Feeds

```bash
npm run poll-rss
```

This checks all active RSS feeds and saves new items to `data/handbag_rss_items.json`.

---

## RSS Feed Management

### Configuration

RSS sources are configured in `data/handbag_rss_sources.json`:

```json
{
  "id": "fashionphile-new",
  "name": "Fashionphile – New Arrivals",
  "siteDomain": "fashionphile.com",
  "feedUrl": "https://fashionphile.com/rss",
  "category": "resale",
  "active": true
}
```

### Categories

- `new-arrivals` - New luxury handbag listings from retailers
- `resale` - Pre-owned listings from resale marketplaces
- `auction` - Upcoming luxury handbag auctions
- `news` - Industry news, trends, authentication guides
- `other` - Uncategorized feeds

### Finding RSS Feeds

Most sites don't advertise their RSS feeds. To find them:

1. **Check page source** for `<link rel="alternate" type="application/rss+xml">`
2. **Try common URLs**: `/feed`, `/rss`, `/atom.xml`, `/blog/feed`
3. **Use browser extensions** like "RSS Feed Finder"
4. **Check sitemap.xml** for feed references

Example script to detect feeds:

```bash
curl -s https://fashionphile.com | grep -i 'rss\|atom\|feed'
```

### Automated Polling

Set up a cron job to poll feeds every 15 minutes:

```bash
crontab -e
```

Add this line:

```
*/15 * * * * cd /root/Projects/handbag-auth-nextjs && /usr/bin/npm run poll-rss >> /var/log/handbag-rss-poll.log 2>&1
```

Or use PM2 for scheduled tasks:

```bash
pm2 start scripts/pollHandbagRss.ts --name handbag-rss-poller --cron "*/15 * * * *" --interpreter ts-node --no-autorestart
```

### Data Structure

Polled items are saved in `data/handbag_rss_items.json`:

```json
{
  "id": "fashionphile-new-abc123",
  "sourceId": "fashionphile-new",
  "title": "Hermès Birkin 30 Togo Leather Gold",
  "link": "https://fashionphile.com/item/...",
  "publishedAt": "2025-11-15T10:30:00Z",
  "summary": "Excellent condition...",
  "brand": "hermes",
  "condition": "used",
  "price": 12500,
  "currency": "USD"
}
```

---

## Affiliate Program Management

### List All Affiliates

```bash
npm run affiliates:list
```

Output:
```
=== Handbag Affiliate Programs (27) ===

RESELLER (10):
  - Fashionphile (fashionphile.com)
    Commission: 5% commission
  - Rebag (rebag.com)
  ...
```

### Query by Type

```bash
npm run affiliates:list by-type reseller
```

### Add Custom Affiliate

Edit `scripts/manageHandbagAffiliates.ts` and modify the sample:

```typescript
const myAffiliate: HandbagAffiliateProgram = {
  id: "my-merchant",
  name: "My Merchant",
  website: "https://mymerchant.com",
  domain: "mymerchant.com",
  merchantType: "reseller",
  affiliateNetwork: "Impact",
  commissionStructure: "8% commission + bonuses",
  cookieDurationDays: 30,
  signupUrl: "https://mymerchant.com/affiliates",
  notes: "Premium pre-owned handbags"
};

addOrUpdateAffiliate(myAffiliate);
```

Then run:
```bash
ts-node scripts/manageHandbagAffiliates.ts add
```

---

## Affiliate Signup Automation

### Using Puppeteer to Pre-fill Forms

The signup automation opens a browser, navigates to the affiliate signup page, and pre-fills your information:

```bash
npm run affiliates:signup fashionphile
```

Available merchants:
- `fashionphile`
- `rebag`
- `therealreal`

### Adding New Merchant Configs

Edit `scripts/handbagAffiliateSignup.ts`:

```typescript
const merchantConfigs: Record<string, SignupConfig> = {
  mynewmerchant: {
    signupUrl: "https://mynewmerchant.com/affiliate-signup",
    selectors: {
      name: 'input[name="full_name"]',
      email: 'input[id="email"]',
      company: 'input[name="company_name"]',
      website: 'input[name="website_url"]',
      description: 'textarea[name="about"]',
      submitButton: 'button[type="submit"]',
    },
  },
};
```

To find CSS selectors:
1. Open the signup page in Chrome
2. Right-click the field → Inspect
3. Note the `name`, `id`, or unique class
4. Use browser console to test: `document.querySelector('input[name="email"]')`

### Your Business Profile

Edit the profile in `scripts/handbagAffiliateSignup.ts`:

```typescript
const profile: AffiliateSignupProfile = {
  contactName: "Your Name",
  company: "Your Company",
  email: "your@email.com",
  websites: ["https://your-handbag-app.com"],
  description: "Your business description...",
};
```

---

## Price Comparison UI Component

### Usage

```tsx
import { HandbagCompareOffers } from "@/components/HandbagCompareOffers";

const offers: HandbagOffer[] = [
  {
    id: "1",
    merchantName: "Fashionphile",
    condition: "used",
    price: 12500,
    currency: "USD",
    url: "https://fashionphile.com/item/123?aff=yourcode",
    label: "Certified Authentic",
    logoUrl: "/logos/fashionphile.png",
  },
  // ... more offers
];

<HandbagCompareOffers
  modelName="Birkin 30"
  brand="Hermès"
  offers={offers}
  onOfferClick={(offer) => {
    console.log("User clicked:", offer);
  }}
/>
```

### Features

- Sorts by price (lowest first)
- Highlights best offer
- Condition badges (new, used, auction)
- Affiliate link tracking
- Mobile-responsive
- Tailwind CSS styling

---

## Arbitrage Detection (Future)

To detect potential arbitrage opportunities, you can compare RSS feed items against your price database:

```typescript
// In scripts/pollHandbagRss.ts

function detectArbitrage(item: HandbagFeedItem) {
  // 1. Match item to known handbag model
  const model = matchToDatabase(item.brand, item.title);

  // 2. Get recent median price
  const medianPrice = getMedianPrice(model.id);

  // 3. Compare
  if (item.price && item.price < medianPrice * 0.85) {
    console.log(`🚨 ARBITRAGE OPPORTUNITY: ${item.title}`);
    console.log(`   Listed: $${item.price}, Median: $${medianPrice}`);
    // Send alert, save to special list, etc.
  }
}
```

---

## File Structure

```
/root/Projects/handbag-auth-nextjs/
├── data/
│   ├── handbag_rss_sources.json      # RSS feed configurations
│   ├── handbag_rss_items.json        # Polled feed items
│   ├── handbag_affiliates.json       # Affiliate program registry
│   └── handbag_merchants.csv         # Merchant master list
├── scripts/
│   ├── pollHandbagRss.ts             # RSS polling script
│   ├── manageHandbagAffiliates.ts    # Affiliate management CLI
│   └── handbagAffiliateSignup.ts     # Puppeteer automation
├── src/
│   ├── types/
│   │   └── handbagRss.ts             # TypeScript definitions
│   └── components/
│       └── HandbagCompareOffers.tsx  # Price comparison UI
└── package.json                       # npm scripts
```

---

## npm Scripts Reference

| Command | Description |
|---------|-------------|
| `npm run poll-rss` | Poll all active RSS feeds |
| `npm run affiliates:list` | List all affiliate programs |
| `npm run affiliates:import` | Import from CSV |
| `npm run affiliates:signup <merchant>` | Launch Puppeteer signup automation |

---

## Next Steps

1. **Verify RSS Feed URLs**
   - Many feed URLs in the config are placeholders
   - Visit each merchant site and find their actual RSS feeds
   - Update `data/handbag_rss_sources.json`

2. **Set Up Cron Job**
   - Add polling to crontab or PM2
   - Monitor logs for errors

3. **Build Matching Logic**
   - Connect RSS items to your handbag database
   - Extract model names, brands, colors from titles
   - Use Claude/Gemini for intelligent parsing

4. **Implement Affiliate Links**
   - Sign up for affiliate programs
   - Add link decoration logic
   - Track conversions

5. **Create Dashboard**
   - Display recent RSS items
   - Show arbitrage opportunities
   - Monitor affiliate performance

---

## Troubleshooting

### RSS Parsing Errors

If a feed fails to parse:
```
Error polling Fashionphile: Error: Invalid XML
```

Check:
1. Is the feed URL correct? (test in browser)
2. Does the site require authentication?
3. Is it actually RSS/Atom (not JSON)?

### Puppeteer Issues

If browser doesn't launch:
```bash
# Install Chrome dependencies
sudo apt-get update
sudo apt-get install -y chromium-browser chromium-chromedriver
```

### TypeScript Errors

```bash
# Ensure ts-node is installed globally
npm install -g ts-node

# Or use npx
npx ts-node scripts/pollHandbagRss.ts
```

---

## Support

For issues or questions about this system, refer to:
- Main project README
- TypeScript type definitions in `src/types/handbagRss.ts`
- Individual script comments

---

## License

Part of the Handbag Auth Next.js project.