Build an Automated AI Sales Offer System with CrewAI and n8n
Build an AI sales system that works while you sleep with this CrewAI n8n tutorial. Create personalized offers that boost conversions using multi-agents.
Last updated: May 3, 2025
19 mins read
Author
Tobias Wupperfeld
Tobias is a seasoned software engineer and the founder of Made By Agents.
Listen to this AI-generated podcast summarizing the article content for easier digestion
Introduction: The Evolution of Sales and the Rise of AI Automation
Tired of sending the same sales pitches to all of your customers? Want to increase your conversion rates and revenue without spending hours crafting personalized offers?
Today we'll be building a multi-agent AI sales system that sends personalized sales offers to customers automatically. The system works while you sleep, increasing conversion and revenue through tailored messaging.
This CrewAI n8n tutorial will show you how to build an automated sales system that can analyze customer data, create detailed profiles, generate custom offers, and deliver them directly to customers - all without human intervention.
We'll be using the CrewAI framework combined with an n8n workflow to create this powerful AI sales automation system. Our approach uses multiple specialized AI agents working together to create truly personalized sales experiences.
The system consists of:
Four specialized AI agents:
Customer Data Analyst
Customer Profiling Specialist
Sales Offer Strategist
Technical Offer Formatter
Four different tasks:
Fetch customer data
Create customer profiles
Generate personalized offers
Format offers for delivery
Two essential tools:
Brave Search Tool (for real-time information gathering)
This tutorial is perfect for developers, tech entrepreneurs, and business owners looking to leverage AI for personalized sales outreach. The finished system will be fully automated, allowing you to scale your sales efforts without increasing your workload.
Welcome to the future of sales - let's get started!
Understanding the Core Technologies: CrewAI and n8n
Deep Dive into CrewAI
CrewAI is a powerful framework for building multi-agent AI systems. Unlike single-agent approaches, CrewAI lets you create specialized AI agents that work together, each with specific roles, goals, and backstories.
In our AI sales agent tutorial, we'll be using CrewAI to create a team of four specialized agents:
Customer Data Analyst: This agent extracts and analyzes customer data from our Airtable database. It identifies patterns and key information that will be useful for creating personalized offers.
Customer Profiling Specialist: Taking the raw data from the analyst, this agent creates comprehensive customer profiles. It considers demographics, purchase history, browsing behavior, and preferences to build a complete picture of each customer.
Sales Offer Strategist: Using the customer profiles, this agent develops personalized sales offers. It determines the most appealing products, appropriate discount levels, and compelling messaging for each customer.
Technical Offer Formatter: This agent takes the personalized offers and formats them for delivery. It structures the data in a way that can be easily processed by our automation workflow.
Each agent in the CrewAI framework has three key components:
Role: What the agent does (e.g., "Customer Data Analyst")
Goal: What the agent is trying to achieve (e.g., "Extract valuable customer insights from raw data")
Backstory: Context that guides the agent's behavior (e.g., "You are an experienced data analyst with expertise in identifying customer patterns")
These components help the agents understand their responsibilities and how they should interact with each other.
The agents work through a series of tasks:
Fetch Customer Data Task: Retrieves customer information from our Airtable database
Create Customer Profiles Task: Analyzes the data to build detailed customer profiles
Generate Personalized Offers Task: Creates tailored offers based on customer profiles
Format Offers Task: Structures the offers for delivery via email
To accomplish these tasks, our agents need access to tools. In this CrewAI tutorial, we'll implement:
Brave Search Tool: This allows our agents to search the web for up-to-date information that might be relevant to creating personalized offers. For example, the Sales Offer Strategist might look up current trends related to a customer's interests.
Custom Airtable Tool: We'll create a custom tool that allows our agents to fetch customer data stored in Airtable. This gives the system access to customer information like names, email addresses, age, gender, location, and preferences.
Leveraging n8n for Automation
While CrewAI handles the intelligence behind our system, we need a way to trigger the process and deliver the results. That's where n8n comes in.
n8n is a workflow automation platform that lets you connect different applications and services without writing code. In our case, we'll use n8n to:
Trigger our CrewAI system to generate personalized offers
Check when the process is complete
Process the results
Send personalized emails to customers
When we deploy our CrewAI system (which we'll do later using CrewAI Enterprise), it creates API endpoints that n8n can interact with. These endpoints allow n8n to:
Start the CrewAI process
Check the status of the process
Retrieve the results once the process is complete
This integration creates a fully automated pipeline: n8n triggers CrewAI, CrewAI generates personalized offers, and then n8n delivers those offers to customers via email.
Building the AI Sales System: A High-Level Walkthrough
Setting Up the CrewAI Environment
Before we build our AI sales system, we need to set up our CrewAI environment. The process is straightforward but requires attention to a few important details.
First, CrewAI has specific Python version requirements. You need Python version between 3.10 and above and below 3.13. This is crucial - if you're using Python 3.13 or higher (like I was initially), you'll need to downgrade.
To check your Python version, run this command in your terminal:
1python --version
Next, we need to install UV, a package manager for Python:
Once UV is installed, we can install the CrewAI CLI:
1uv tool install crewai
With the CLI installed, we can create a new CrewAI project:
1crewai create crew sales-offer-crew
This command creates a new folder with the basic structure for our CrewAI project. The CLI will ask a few questions to configure your project:
Which LLM provider you want to use (we'll select OpenAI)
Which model to use (we'll select GPT-4o mini, though you can change this later)
Your API key (you can hit enter for now and add it later)
After the project is created, you'll have a folder structure that includes:
A source directory
A config folder with agent and task definitions
A tools folder for custom tools
A crew.py file for constructing your crew
A main.py file with the run function that starts your system
This structure gives us a solid foundation to build our AI sales system.
Defining Agents, Tasks, and Tools for Personalized Sales
Now that we have our basic project structure, we need to define our agents, tasks, and tools. For this tutorial, I'll be using Claude 3.7 Sonnet with agent mode prompted to help us create the code. This AI assistant will help us generate the boilerplate code we need.
Let's start by defining our data model. We'll create a Pydantic model to structure the sales offers our system will generate:
1# models/sales_offer.py
2from pydantic import BaseModel, Field
3from typing import List, Dict, Any
4from datetime import datetime
5
6
7classSalesOffer(BaseModel):
8"""Individual sales offer for a customer"""
9
10 customer_id:str= Field(..., description="Customer ID from Airtable")
21..., description="Personalized message for the customer"
22)
23 offer_code:str= Field(..., description="Unique code for this offer")
24 reason:str= Field(..., description="Reasoning behind this offer selection")
25
26
27classSalesOfferCollection(BaseModel):
28"""Collection of sales offers for multiple customers"""
29
30 offers: List[SalesOffer]= Field(
31..., description="List of personalized sales offers"
32)
33 generated_at: datetime = Field(
34 default_factory=datetime.now, description="When these offers were generated"
35)
36 total_customers:int= Field(..., description="Total number of customers processed")
37 metadata: Dict[str, Any]= Field(
38 default_factory=dict,
39 description="Additional metadata about this batch of offers",
40)
This model captures all the information we need for a personalized sales offer: customer details, offer specifics, recommended products, and personalization elements.
Next, let's define our four agents in the agents.yaml file:
1data_analyst:
2role:>
3 Customer Data Analyst
4goal:>
5 Extract and organize customer data to identify valuable insights and patterns
6backstory:>
7 You're a meticulous data analyst with a keen eye for patterns in customer behavior.
8 You can spot trends in purchasing habits and customer preferences that others might miss.
9 Your insights drive business decisions and help create personalized customer experiences.
10
11customer_profiler:
12role:>
13 Customer Profiling Specialist
14goal:>
15 Create detailed customer profiles based on their data and identify personalization opportunities
16backstory:>
17 You're an expert in customer segmentation and personalization. Your specialty is
18 transforming raw customer data into actionable profiles that highlight individual
19 preferences, needs, and buying patterns. Your profiles are known for capturing the
20 essence of what makes each customer unique.
21
22offer_creator:
23role:>
24 Sales Offer Strategist
25goal:>
26 Design highly personalized offers that maximize conversion rates and customer satisfaction
27backstory:>
28 You're a creative strategist with years of experience in sales and marketing. You understand
29 what motivates customers to make purchases and how to craft irresistible offers tailored
30 to individual preferences. Your offers consistently achieve high conversion rates and customer satisfaction.
31
32offer_formatter:
33role:>
34 Technical Offer Formatter
35goal:>
36 Format sales offers into structured data objects ready for API integration
37backstory:>
38 You excel at transforming business content into structured technical formats. With a background
39 in both business and technology, you bridge the gap between marketing content and technical requirements.
40 You ensure that all sales offers are properly formatted as valid JSON data with all required fields
41 properly filled out and validated.
Each agent has a clear role, goal, and backstory.
Now, let's define the tasks for our agents in the tasks.yaml file:
1fetch_customer_data:
2description:>
3 Use the Airtable tool to fetch all customer data from the database.
4 Organize the data in a clear format and provide a summary of the customer base.
5expected_output:>
6 A structured dataset of all customers with their attributes, along with a brief
7 summary of key statistics about the customer base (number of customers, average
8 spend, demographics breakdown, etc.).
9agent: data_analyst
10
11create_customer_profiles:
12description:>
13 Analyze the customer data provided and create detailed customer profiles.
14 For each customer, identify their preferences, buying patterns, and opportunities
15 for personalization. Group similar customers into segments if appropriate.
16expected_output:>
17 Detailed profiles for each customer that highlight their unique characteristics,
18 preferences, and potential opportunities for personalized offers.
19agent: customer_profiler
20
21generate_personalized_offers:
22description:>
23 For each customer profile, create a highly personalized sales offer that
24 addresses their specific needs, preferences, and purchase history. Each offer
25 should include a compelling title, description, discount percentage, recommended
26 products, expiration date, and a personal message.
27expected_output:>
28 A collection of personalized sales offers, with one detailed offer per customer.
29 Each offer should be tailored to the customer's profile and include all required elements.
30agent: offer_creator
31
32format_offers_for_api:
33description:>
34 Take the collection of personalized sales offers and format them according to the
35 SalesOfferCollection Pydantic model specification. Ensure all required fields are
36 present and properly formatted. Generate appropriate offer codes for each customer.
37 The output must be valid JSON that conforms to the SalesOfferCollection schema.
38expected_output:>
39 A valid JSON object conforming to the SalesOfferCollection schema, containing all
40 personalized offers properly formatted for API integration.
41agent: offer_formatter
Each task has a clear description, an assigned agent, and an expected output.
Connecting to Customer Data: The Airtable Integration
For our AI sales system to work, it needs access to customer data. We'll use Airtable as our database because it's easy to set up and integrate.
First, create an Airtable base with a table named "Customers" that includes these fields:
ID (text)
Customer Name (text)
Email (text)
Age (number)
Gender (single select)
Location (text)
Purchase History (text)
Preferred Category (single select)
Recently Viewed Items (multiple select)
Add some sample customer data to test the system. Include a variety of demographics, interests, and behaviors to see how the system creates different personalized offers.
Next, we need to create a custom Airtable tool for our CrewAI agents. Here's the code for our airtable_tool.py:
1# tools/airtable_tool.py
2import os
3import requests
4from typing import Dict, List
5from crewai import Tool
6from dotenv import load_dotenv
7
8load_dotenv()
9
10classAirtableTool(Tool):
11 name ="Airtable Customer Data Tool"
12 description ="Fetches customer data from Airtable"
For the Airtable Base ID, look at the URL of your Airtable base. It's the part that starts with "app" after "airtable.com/" - copy that and paste it in your .env file.
Building the Crew and Run Function
Lastly, let's update our crew.py and main.py files:
26raise Exception(f"An error occurred while running the crew: {e}")
Deployment (Using CrewAI Enterprise as an Example)
Now let's deploy our CrewAI system so n8n can interact with it. We'll use CrewAI Enterprise for this, as it provides a simple way to deploy our system and create API endpoints.
First, make sure your code is in a GitHub repository. CrewAI Enterprise can connect directly to GitHub to deploy your code.
Create a new repository on GitHub
Push your code to the repository
Log in to CrewAI Enterprise
Create a new project
Connect to your GitHub repository
Configure your deployment settings: Select the repository; Select the branch (usually main); Enable automatic deployment for new commits
Add your environment variables: OPENAI_API_KEY, AIRTABLE_BASE_ID, AIRTABLE_TABLE_NAME, AIRTABLE_API_KEY, BRAVE_API_KEY
Deploy your project
CrewAI Enterprise will automatically deploy your code and create API endpoints for you. It typically takes about 10 minutes for the deployment to complete.
Once the deployment is complete, you'll have three endpoints:
/inputs - Get information about the inputs your crew expects
/kickoff - Start the CrewAI process
/status/{kickoff_id} - Check the status of a running process
You can test these endpoints directly in the CrewAI Enterprise interface before connecting them to n8n.
To test the /kickoff endpoint, send a POST request with an empty JSON object {}. This will return a kickoff ID.
To test the /status endpoint, send a GET request with the kickoff ID in the URL. This will return the status of the process and the result if it's complete.
Once you've verified that everything is working, you can update your n8n workflow with the actual endpoint URLs provided by CrewAI Enterprise.
Automating the Workflow with n8n
Now that we have our CrewAI system set up, we need to create an n8n workflow to automate the process and deliver our personalized offers to customers via email. In this section, I'll walk you through building a complete n8n workflow step by step.
With our backend ready, let's build the n8n workflow. You can access n8n by either:
Self-hosting it on your own server
Using n8n.io, their hosted service (offers a free trial)
Step 1: Setting Up the Initial HTTP Request
Start with an HTTP Request node to trigger our CrewAI system:
Create a new workflow in n8n
Add an HTTP Request node
Configure it: Method: POST; URL: Your CrewAI Enterprise kickoff endpoint; Authentication: Bearer Token (paste your CrewAI Enterprise API key); Request; Body: {"inputs": {}}; Content Type: application/json
Name this node "Kickoff Crew"
Test it by clicking "Test step"
If successful, you'll get a response like:
1{
2"kickoff_id":"abc123def456"
3}
This kickoff ID is what we'll use to check the status of our CrewAI process.
Step 2: Creating a Status-Checking Loop
Next, we need to check if our CrewAI process has completed. Since this can take 30-60 seconds, we'll create a loop:
Add another HTTP Request node
Configure it: Method: GET; URL: Your CrewAI Enterprise status endpoint + the kickoff ID from the previous step (For example: https://sales-offer-crew-123.crewai.com/status/{{ $('Kickoff Crew').item.json.kickoff_id }}); Authentication: Bearer Token (same as before)
Name this node "Get Status"
Connect it to the "Kickoff Crew" node
Now we need to create a conditional loop that checks if the process is complete:
Add an IF node
Connect it to the "Get Status" node
Configure the condition: Value 1: {{$json.state}}; Operation: is equal to; Value 2: SUCCESS
Name this node "Check If Complete"
This node has two paths:
The "true" path (when status = "SUCCESS")
The "false" path (when status = "RUNNING" or "FAILED")
Let's handle the "false" path first:
Add a Wait node
Connect it to the "false" output of the "Check If Complete" node
Configure it to wait for 15 seconds
Name this node "Wait 15 Seconds"
Connect this node back to the "Get Status" node to create a loop
This creates a polling loop that checks the status every 15 seconds until it succeeds.
Step 3: Processing the Results
Once the status is "SUCCESS", we need to extract and process the offers:
Add a Set node
Connect it to the "true" output of the "Check If Complete" node
Configure it to extract the offers array: Name: offers; Data type: Array; Value: {{ $('Get Status').item.json.result.parseJson().offers }}
Name this node "Extract Offers"
Now we need to split the offers array so we can send an email for each offer:
Add a Split In Batches node
Connect it to the "Extract Offers" node
Configure it: Input Field: offers; Batch Size: 1
Name this node "Split Offers"
This will output each offer individually, allowing us to send personalized emails to each customer.
Step 4: Sending Personalized Emails
Finally, we'll send personalized emails to each customer:
Add an Email node
Connect it to the "Split Offers" node
Configure your SMTP settings (server, port, username, password)
Configure the email content: From: Your email address; To: {{ $json.customer_email}}; Subject: {{ $json.offer_title }}; Content Type: HTML; HTML: Generate a template (see example template below)
Name this node "Send Personalized Email"
Here's an HTML email template you can use:
1<!DOCTYPE html>
2<html>
3<head>
4 <style>
5 body {
6font-family: Arial, sans-serif;
7line-height: 1.6;
8color:#333;
9}
10 .container {
11width: 80%;
12margin: 0 auto;
13padding: 20px;
14}
15 .header {
16background-color:#4CAF50;
17color: white;
18padding: 10px;
19text-align: center;
20}
21 .content {
22padding: 20px;
23background-color:#f9f9f9;
24}
25 .footer {
26text-align: center;
27padding: 10px;
28font-size: 0.8em;
29color:#666;
30}
31 .promo-code {
32background-color:#f1f1f1;
33padding: 10px;
34text-align: center;
35font-weight: bold;
36letter-spacing: 2px;
37margin: 20px 0;
38}
39 .button {
40display: inline-block;
41background-color:#4CAF50;
42color: white;
43padding: 10px 20px;
44text-decoration: none;
45border-radius: 5px;
46margin-top: 20px;
47}
48 </style>
49</head>
50<body>
51 <div class="container">
52 <div class="header">
53 <h1>Special Offer Just for You,{{ $json.customer_name }}!</h1>
54 </div>
55 <div class="content">
56 <p>Hi {{ $json.customer_name }},</p>
57
58 <h2>{{ $json.offer_title }}</h2>
59
60 <p>{{ $json.offer_description }}</p>
61
62 <p>We're offering you a special <strong>{{ $json.discount_percentage }}% discount</strong> on these recommended products:</p>
63
64 <ul>
65{{ $json.recommended_products.map(item => `
66 <li>${item}</li>
67`).join('') }}
68 </ul>
69
70 <div class="promo-code">
71Your Promo Code:{{ $json.promo_code }}
72 </div>
73
74 <p>{{ $json.personalized_message }}</p>
75
76 <p><strong>Why we think you'll love this:</strong>{{ $json.reason_for_recommendation }}</p>
83 <p>This email was sent to {{ $json.customer_email }}. If you no longer wish to receive these emails, you can unsubscribe <a href="#">here</a>.</p>
84 </div>
85 </div>
86</body>
87</html>
Step 5: Testing the Workflow
Now that our workflow is complete, it's time to test it:
Click "Test workflow" at the bottom of the n8n interface
Watch the execution progress through each node
The workflow will: Kick off the CrewAI process; Check the status repeatedly until it's complete; Extract the offers; Split them into individual items; Send personalized emails to each customer
The first time you run this workflow, it might take several minutes for the CrewAI process to complete. Be patient and watch the execution progress.
Step 6: Automating the Workflow
To make this system truly automated, you can add a trigger node at the beginning of your workflow:
Add a Schedule Trigger node at the start of your workflow
Configure it to run on your desired schedule (e.g., once a week)
Connect it to the "Kickoff Crew" node
Now your workflow will run automatically according to your schedule, generating and sending personalized offers without any manual intervention.
Let's check one of the emails the system sent in our test. For example, here's the email Isabella Kim received:
Notice how the system recommended beauty products specifically for Isabella, based on her preferences and browsing history from the Airtable data. The system recognized that her preferred category is beauty and that she recently viewed Korean skin care and hair products, so it tailored the recommendations accordingly.
This is the power of our AI sales system – each customer receives highly personalized offers based on their unique profile, all generated and delivered automatically.
Key Benefits and Takeaways
Building an AI-powered sales automation system with CrewAI and n8n offers several key benefits:
Personalization at Scale: The system can analyze customer data and create highly personalized sales offers for each customer. This level of personalization would be impossible to achieve manually for a large customer base.
24/7 Operation: Once set up, the system works continuously, generating and sending offers even when you're not actively working.
Improved Conversion Rates: Personalized offers are more likely to resonate with customers, leading to higher conversion rates and increased revenue.
Reduced Workload: Automating the sales offer process frees up your time to focus on other aspects of your business.
Scalability: As your customer base grows, the system can easily scale to handle more customers without requiring additional manual work.
Data-Driven Insights: The Customer Data Analyst agent can identify patterns and trends in your customer data, providing valuable insights for your marketing strategy.
Real-Time Information: The Brave Search tool allows the system to incorporate current trends and information into the offers, making them more relevant and timely.
Professional Presentation: The HTML email template ensures that the offers are presented in a professional and visually appealing way.
Getting Started with Your Own AI-Powered Sales Automation
If you want to build your own AI-powered sales automation system, here's a checklist to get started:
Set Up Your Environment: Install Python (version between 3.10 and 3.13). Install the UV package manager. Install the CrewAI CLI. Create a new CrewAI project.
Gather Your API Keys: OpenAI API key; Airtable API key; Brave Search API key
Set Up or Connect Your Customer and Product Database: Use your existing database or create an Airtable base with customer and product data. Note your Airtable Base IDs and table names.
Implement the Code: Define your agents with roles, goals, and backstories. Create tasks for each step of the process. Implement custom tools to fetch customer and product data (e.g., Airtable tool). Set up the crew to orchestrate the agents and tasks
Deploy Your System: Push your code to GitHub. Deploy using CrewAI Enterprise. Note the API endpoints.
Create Your n8n Workflow: Set up the HTTP Request nodes to interact with your CrewAI system. Implement the looping logic to check when the process completes. Create the email template for delivering offers. Configure the email sending settings.
Test and Refine: Start with a small batch of customers. Review the offers generated by the system. Adjust the agent prompts and tasks as needed. Monitor conversion rates and make further refinements.
Conclusion: The Future of Sales is Intelligent and Automated
The AI sales system we've built in this tutorial represents the future of sales automation - intelligent, personalized, and always working. By combining the power of CrewAI's multi-agent framework with n8n's workflow automation, we've created a system that can:
Analyze customer data to identify patterns and trends
Create detailed customer profiles
Generate highly personalized sales offers
Deliver those offers through professional, branded emails
As AI technology continues to evolve, we can expect these systems to become even more sophisticated, with deeper personalization and better targeting.
Practical frameworks for process optimization: From workflow automation to predictive analytics. Learn how peer organizations achieve efficiency gains through ROI-focused tech adoption.