Build an AI Holiday Card Maker - Complete Tutorial
Build an AI Holiday Card Maker - Complete Tutorial
Learn how to build an AI-powered holiday card maker that creates beautiful, personalized cards for any occasion. This comprehensive guide covers setup, implementation, and deployment using the AI Pass platform.
Prerequisites
- Node.js 18+ installed
- Basic JavaScript knowledge
- AI Pass account (signup with $1 free credit)
Step 1: Sign Up and Get Your Client ID
- Go to AI Pass Developer Dashboard
- Sign up for an account ($1 free credit on signup)
- Navigate to OAuth2 Clients section
- Click Create New Client
- Name your app (e.g., "Holiday Card Maker")
- Copy your Client ID - you'll need this for the SDK
Step 2: Initialize the SDK
Include the AI Pass SDK in your HTML:
<script src="https://aipass.one/aipass-sdk.js"></script>
Initialize with OAuth2 and requireLogin:
const aipass = new AIPassSDK({
clientId: 'YOUR_CLIENT_ID', // Replace with your actual Client ID
requireLogin: true,
onSuccess: (token) => {
console.log('User authenticated:', token);
}
});
Step 3: Create the Holiday Card Maker
Here's the complete implementation:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AI Holiday Card Maker</title>
<script src="https://aipass.one/aipass-sdk.js"></script>
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; max-width: 1000px; margin: 50px auto; padding: 20px; background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); }
.container { background: white; padding: 40px; border-radius: 20px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); }
h1 { text-align: center; color: #333; margin-bottom: 40px; font-size: 2.5em; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px; }
.form-group { margin-bottom: 20px; }
label { display: block; margin-bottom: 8px; font-weight: bold; color: #555; }
input, textarea, select { width: 100%; padding: 12px; border: 2px solid #e0e0e0; border-radius: 8px; font-size: 14px; transition: all 0.3s; }
input:focus, textarea:focus, select:focus { border-color: #667eea; outline: none; }
textarea { height: 120px; resize: vertical; }
button { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 18px 40px; border: none; border-radius: 8px; cursor: pointer; font-size: 18px; font-weight: bold; width: 100%; transition: all 0.3s; }
button:hover { transform: translateY(-3px); box-shadow: 0 8px 25px rgba(0,0,0,0.2); }
button:disabled { background: #ccc; cursor: not-allowed; transform: none; }
#output { margin-top: 40px; padding: 30px; background: #f8f9fa; border-radius: 15px; min-height: 200px; }
.loading { text-align: center; color: #666; font-size: 18px; }
.error { color: #d32f2f; }
.success { color: #388e3c; }
.card-preview { background: white; padding: 40px; border-radius: 15px; margin-top: 20px; box-shadow: 0 5px 20px rgba(0,0,0,0.1); }
.card-image { max-width: 100%; border-radius: 10px; margin-bottom: 20px; }
.download-btn { background: #4CAF50; color: white; padding: 10px 25px; border: none; border-radius: 5px; cursor: pointer; font-size: 14px; margin: 5px; }
.download-btn:hover { background: #45a049; }
</style>
</head>
<body>
<div class="container">
<h1>AI Holiday Card Maker</h1>
<div class="form-row">
<div class="form-group">
<label>Holiday Type:</label>
<select id="holidayType">
<option value="christmas">Christmas</option>
<option value="newyear">New Year</option>
<option value="thanksgiving">Thanksgiving</option>
<option value="hanukkah">Hanukkah</option>
<option value="diwali">Diwali</option>
<option value="valentine">Valentine's Day</option>
<option value="easter">Easter</option>
<option value="birthday">Birthday</option>
</select>
</div>
<div class="form-group">
<label>Card Style:</label>
<select id="cardStyle">
<option value="traditional">Traditional</option>
<option value="modern">Modern</option>
<option value="whimsical">Whimsical</option>
<option value="elegant">Elegant</option>
<option value="minimalist">Minimalist</option>
<option value="retro">Retro</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>Recipient Name:</label>
<input type="text" id="recipientName" placeholder="e.g., Sarah">
</div>
<div class="form-group">
<label>Your Name:</label>
<input type="text" id="senderName" placeholder="e.g., The Smith Family">
</div>
</div>
<div class="form-group">
<label>Personal Message:</label>
<textarea id="message" placeholder="Write your heartfelt greeting here..."></textarea>
</div>
<div class="form-group">
<label>Color Scheme:</label>
<select id="colorScheme">
<option value="auto">Let AI Choose</option>
<option value="red-gold">Red and Gold</option>
<option value="blue-silver">Blue and Silver</option>
<option value="green-red">Green and Red</option>
<option value="purple-gold">Purple and Gold</option>
<option value="pastel">Pastel Colors</option>
<option value="monochrome">Black and White</option>
</select>
</div>
<div class="form-group">
<label>Upload Photo (Optional):</label>
<input type="file" id="photoUpload" accept="image/*">
</div>
<button onclick="generateCard()" id="generateBtn">Generate Holiday Card</button>
<div id="output"></div>
</div>
<script>
const aipass = new AIPassSDK({
clientId: 'YOUR_CLIENT_ID', // Replace with your actual Client ID
requireLogin: true,
onSuccess: (token) => {
console.log('Ready to generate cards!');
}
});
async function generateCard() {
const holidayType = document.getElementById('holidayType').value;
const cardStyle = document.getElementById('cardStyle').value;
const recipientName = document.getElementById('recipientName').value;
const senderName = document.getElementById('senderName').value;
const message = document.getElementById('message').value;
const colorScheme = document.getElementById('colorScheme').value;
const photoUpload = document.getElementById('photoUpload').files[0];
if (!message.trim()) {
alert('Please enter a personal message');
return;
}
const btn = document.getElementById('generateBtn');
const output = document.getElementById('output');
btn.disabled = true;
btn.textContent = 'Generating card...';
output.innerHTML = '<div class="loading">Creating your beautiful holiday card. Please wait...</div>';
try {
// Generate the card design prompt using GPT-5
const prompt = `Create a detailed image generation prompt for a ${holidayType} holiday card with these specifications:
Recipient: ${recipientName}
Sender: ${senderName}
Message: ${message}
Style: ${cardStyle}
Color Scheme: ${colorScheme}
${photoUpload ? 'Include photo integration space' : ''}
Provide a detailed prompt that includes:
- Overall visual style and composition
- Color palette and mood
- Typography placement and style
- Decorative elements and imagery
- Layout and spacing
- Any text placement guidelines`;
const promptResult = await aipass.generateText({
model: 'gpt-5-mini',
prompt: prompt,
temperature: 1,
max_tokens: 16000
});
// Generate the card image using the AI image API
const imageResult = await aipass.generateImage({
model: 'flux-pro/v1.1',
prompt: promptResult.text,
style: cardStyle
});
// Display the result
output.innerHTML = `
<div class="success">
<h3>Your Holiday Card is Ready!</h3>
<div class="card-preview">
<img src="${imageResult.url}" class="card-image" alt="Holiday Card">
<p><strong>Recipient:</strong> ${recipientName || 'Special Someone'}</p>
<p><strong>Holiday:</strong> ${holidayType.charAt(0).toUpperCase() + holidayType.slice(1)}</p>
<p><strong>Style:</strong> ${cardStyle.charAt(0).toUpperCase() + cardStyle.slice(1)}</p>
<p><strong>Message:</strong></p>
<p style="font-style: italic; color: #666;">${message}</p>
<div style="margin-top: 20px;">
<button class="download-btn" onclick="downloadCard('${imageResult.url}', 'png')">Download PNG</button>
<button class="download-btn" onclick="downloadCard('${imageResult.url}', 'jpg')">Download JPG</button>
</div>
</div>
<p><strong>Design Prompt:</strong></p>
<pre style="white-space: pre-wrap; background: white; padding: 15px; border-radius: 8px; max-height: 150px; overflow-y: auto; border: 1px solid #ddd;">${promptResult.text}</pre>
</div>
`;
} catch (error) {
console.error('Error:', error);
output.innerHTML = `<div class="error">Error: ${error.message}</div>`;
} finally {
btn.disabled = false;
btn.textContent = 'Generate Holiday Card';
}
}
async function downloadCard(url, format) {
try {
const response = await fetch(url);
const blob = await response.blob();
const downloadUrl = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = downloadUrl;
a.download = `holiday-card.${format}`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(downloadUrl);
} catch (error) {
alert('Download failed. Please right-click and save the image.');
}
}
</script>
</body>
</html>
Step 4: Deploy Your App
You have two deployment options:
Option A: Self-Host Anywhere
- Vercel: Drag and drop your HTML file
- Netlify: Connect your GitHub repo
- Any web server: Upload to nginx, Apache, or any hosting
- Local testing: Just open the HTML file in a browser
Option B: Publish on AI Pass Catalog
- Go to AI Pass Apps Dashboard
- Click Create New App
- Fill in app details:
- Name: "AI Holiday Card Maker"
- Description: "Create beautiful personalized holiday cards with AI"
- Category: Design
- Content: Paste your HTML code
- Click Publish
- Your app is now live on the AI Pass catalog!
Earn 50% commission on every transaction when users interact with your published app.
Key Features Explained
temperature:1
- Maximum creativity and variation
- Perfect for unique, personalized card designs
- Generates fresh designs every time
max_tokens:16000
- Generous length for detailed design prompts
- Allows for comprehensive card specifications
- No need to truncate output
requireLogin:true
- Ensures authenticated users only
- Tracks usage per user
- Enables personalized experiences
Advanced Features
Photo Integration
// Handle photo uploads
async function handlePhotoUpload(file) {
const formData = new FormData();
formData.append('image', file);
const response = await fetch('/upload', {
method: 'POST',
body: formData
});
return await response.json(); // Returns image URL
}
Batch Card Generation
// Generate multiple cards at once
async function generateBatchCards(recipients) {
const cards = await Promise.all(
recipients.map(r => generateCard(r))
);
return cards;
}
Custom Color Palettes
const customPalettes = {
brand: { primary: '#FF5733', secondary: '#33FF57' },
pastel: { primary: '#FFE5E5', secondary: '#E5E5FF' },
vintage: { primary: '#8B4513', secondary: '#DAA520' }
};
Next Steps
- Add template gallery for quick starts
- Implement photo editing tools
- Create custom branding options
- Add social media sharing integration
- Build card library for saved designs
Get Started Today
Sign up now and get $1 free credit to start building your AI holiday card maker!
Need help? Check out the SDK documentation and developer guides.