How Affiliate Marketing Pitches Are Generated in MoneyPrinterV2's AFM.py

MoneyPrinterV2 generates affiliate marketing pitches by scraping product data with headless Firefox, then prompting an LLM to write persuasive copy based on the extracted title and features, finally appending the affiliate URL.

The AffiliateMarketing class in src/classes/AFM.py orchestrates this entire pipeline. When initialized, it validates the affiliate link, launches a browser session to extract product metadata, and exposes a generate_pitch method that transforms raw scraped data into ready-to-publish marketing content using your configured LLM provider.

The AffiliateMarketing Class Architecture

The core logic resides in the AffiliateMarketing class defined in src/classes/AFM.py (lines 18-150). The constructor performs three critical setup operations:

  1. URL Validation (lines 73-77): Validates the provided affiliate link structure before attempting to scrape.
  2. Browser Initialization: Starts a headless Firefox session using Selenium to render JavaScript-heavy product pages.
  3. State Preparation: Initializes empty attributes for product_title, features, and pitch that will be populated during the workflow.
from src.classes.AFM import AffiliateMarketing

# Initialize with your affiliate link and Firefox profile

afm = AffiliateMarketing(
    affiliate_link="https://www.amazon.com/dp/example",
    fp_profile_path="/path/to/firefox/profile",
    twitter_account_uuid="123e4567-e89b-12d3-a456-426614174000",
    account_nickname="mybot",
    topic="tech-gadgets"
)

How the Pitch Generation Pipeline Works

The generate_pitch method (lines 31-50 of the method body in src/classes/AFM.py) executes a three-stage pipeline: product scraping, LLM prompt engineering, and final assembly.

Scraping Product Information

Before generating copy, the system must extract structured data from the target page. The scrape_product_information method (lines 96-118) navigates to the affiliate URL and extracts:

  • Product Title: Located using the AMAZON_PRODUCT_TITLE_ID constant defined in src/constants.py
  • Feature Bullets: Extracted as a list of strings describing key product attributes

# This happens automatically inside generate_pitch()

afm.scrape_product_information()

# Now afm.product_title and afm.features are populated

LLM Integration and Prompt Engineering

The generate_response method serves as a thin wrapper around the LLM provider. It calls generate_text from src/llm_provider.py (lines 41-63), which interfaces with your configured backend (typically Ollama for local models).

Critical requirement: You must select a model before generating pitches using select_model from src/llm_provider.py (lines 23-32).

from src.llm_provider import select_model

# Select your LLM (must be pulled locally if using Ollama)

select_model("llama2")

# Generate the pitch (this triggers the LLM call)

pitch_text = afm.generate_pitch()

The prompt engineered inside generate_pitch follows this exact template:

f'I want to promote this product on my website. Generate a brief pitch about this product, return nothing else except the pitch. '
f'Information:\nTitle: "{self.product_title}"\nFeatures: "{str(self.features)}"'

Assembling the Final Pitch

After receiving the LLM-generated copy, the method concatenates the marketing text with a call-to-action and the affiliate URL:

pitch = (
    self.generate_response(prompt_string)
    + "\nYou can buy the product here: "
    + self.affiliate_link
)

The resulting string is stored in self.pitch and returned to the caller.

Complete Implementation Example

Here is a complete, runnable workflow that demonstrates the entire pipeline from initialization to cleanup:

from src.classes.AFM import AffiliateMarketing
from src.llm_provider import select_model

# 1. Configure the LLM backend

select_model("llama2")  # Assumes Ollama is running with llama2 pulled

# 2. Initialize the affiliate marketing handler

afm = AffiliateMarketing(
    affiliate_link="https://www.amazon.com/dp/example",
    fp_profile_path="/path/to/firefox/profile",
    twitter_account_uuid="123e4567-e89b-12d3-a456-426614174000",
    account_nickname="mybot",
    topic="tech-gadgets"
)

# 3. Generate the marketing pitch (scrapes + LLM call)

pitch_text = afm.generate_pitch()
print(pitch_text)

# Output: [LLM-generated persuasive text]

# You can buy the product here: https://www.amazon.com/dp/example

# 4. Optional: Share to Twitter

afm.share_pitch("twitter")

# 5. Cleanup

afm.quit()

Key Files and Dependencies

File Role
src/classes/AFM.py AffiliateMarketing class, product scraping, pitch assembly【/src/classes/AFM.py#L18-L150】
src/llm_provider.py generate_text wrapper around Ollama, model selection logic【/src/llm_provider.py#L41-L63】
src/constants.py IDs for Amazon page elements (e.g., AMAZON_PRODUCT_TITLE_ID) used during scraping【/src/constants.py#L1-L30】
src/config.py Configuration helpers (e.g., get_ollama_base_url) for the LLM client【/src/config.py#L1-L20】

Summary

  • AFM.py contains the AffiliateMarketing class that automates affiliate marketing pitch generation through a structured pipeline.
  • The system uses headless Firefox to scrape product titles and feature bullets from affiliate URLs before generating content.
  • Prompt engineering combines scraped product data with a strict instruction template to induce the LLM to return only marketing copy.
  • The LLM provider (configured via src/llm_provider.py) must be initialized with select_model() before calling generate_pitch().
  • Final output concatenates the LLM-generated text with a hardcoded call-to-action and the original affiliate link.

Frequently Asked Questions

What LLM providers does MoneyPrinterV2 support for generating affiliate pitches?

MoneyPrinterV2 supports Ollama for local LLM inference according to the src/llm_provider.py implementation. The generate_text function (lines 41-63) wraps Ollama's API, and you must run select_model() (lines 23-32) to specify which locally-pulled model to use (e.g., "llama2" or "mistral") before generating pitches.

How does the system extract product information before generating the pitch?

The scrape_product_information method in src/classes/AFM.py (lines 96-118) handles extraction. It navigates the headless Firefox browser to the affiliate URL and scrapes the product title using the AMAZON_PRODUCT_TITLE_ID constant from src/constants.py, along with feature bullet points. This data populates self.product_title and self.features used in the LLM prompt.

Can I customize the pitch generation prompt in AFM.py?

Yes, the prompt template is defined within the generate_pitch method (lines 31-50) in src/classes/AFM.py. You can modify the f-string that constructs the prompt variable to change instructions, tone, or output format. However, you must maintain the self.product_title and self.features variables in the prompt to ensure the LLM receives the scraped product context.

What happens after the pitch is generated?

The generate_pitch method stores the final text in self.pitch and returns it to the caller. The pitch consists of the LLM-generated marketing copy concatenated with the string "\nYou can buy the product here: " and the original self.affiliate_link. You can then call share_pitch("twitter") (lines 59-70) to automatically post the content via the integrated Twitter class, or handle the string manually for other platforms.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →