// SHOPIFY SURVEY DATA COLLECTION & ANALYSIS SYSTEM
// 1. FORM SUBMISSION HANDLER (Add to your HTML form)
document.getElementById('customerSurvey').addEventListener('submit', function(e) {
e.preventDefault();
// Collect all form data
const formData = new FormData(this);
const surveyData = {
timestamp: new Date().toISOString(),
customer_id: formData.get('customer_id'),
order_id: formData.get('order_id'),
responses: {}
};
// Process all form fields
for (let [key, value] of formData.entries()) {
if (key.includes('[]')) {
// Handle checkbox arrays
const cleanKey = key.replace('[]', '');
if (!surveyData.responses[cleanKey]) {
surveyData.responses[cleanKey] = [];
}
surveyData.responses[cleanKey].push(value);
} else {
surveyData.responses[key] = value;
}
}
// Send to your backend/webhook
sendSurveyData(surveyData);
});
function sendSurveyData(data) {
fetch('/apps/survey-collector/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
// Show thank you message and discount code
showThankYouMessage();
})
.catch(error => {
console.error('Error:', error);
});
}
// 2. DATA PROCESSING & SEGMENTATION FUNCTIONS
class CustomerSegmentAnalyzer {
constructor(surveyResponses) {
this.responses = surveyResponses;
this.segments = {};
}
// Create customer segments based on survey data
createSegments() {
this.segments = {
experience_segments: this.segmentByExperience(),
budget_segments: this.segmentByBudget(),
setup_segments: this.segmentBySetupType(),
engagement_segments: this.segmentByEngagement(),
challenge_segments: this.segmentByChallenges()
};
return this.segments;
}
segmentByExperience() {
const segments = {
beginners: [], // complete_beginner + beginner
intermediate: [],
advanced: [], // advanced + professional
};
this.responses.forEach(response => {
const level = response.responses.experience_level;
if (['complete_beginner', 'beginner'].includes(level)) {
segments.beginners.push(response);
} else if (level === 'intermediate') {
segments.intermediate.push(response);
} else if (['advanced', 'professional'].includes(level)) {
segments.advanced.push(response);
}
});
return segments;
}
segmentByBudget() {
const segments = {
budget_conscious: [], // under_25, 25_50
mid_range: [], // 50_100, 100_200
premium: [], // 200_plus
irregular: [] // seasonal
};
this.responses.forEach(response => {
const budget = response.responses.monthly_budget;
if (['under_25', '25_50'].includes(budget)) {
segments.budget_conscious.push(response);
} else if (['50_100', '100_200'].includes(budget)) {
segments.mid_range.push(response);
} else if (budget === '200_plus') {
segments.premium.push(response);
} else if (budget === 'seasonal') {
segments.irregular.push(response);
}
});
return segments;
}
segmentBySetupType() {
const segments = {
freshwater_specialists: [],
planted_enthusiasts: [],
marine_keepers: [],
terrarium_lovers: [],
multi_setup_experts: []
};
this.responses.forEach(response => {
const setups = response.responses.setup_types || [];
if (setups.length > 2) {
segments.multi_setup_experts.push(response);
} else if (setups.includes('planted')) {
segments.planted_enthusiasts.push(response);
} else if (setups.includes('saltwater')) {
segments.marine_keepers.push(response);
} else if (setups.includes('terrarium_closed') || setups.includes('terrarium_open')) {
segments.terrarium_lovers.push(response);
} else if (setups.includes('freshwater')) {
segments.freshwater_specialists.push(response);
}
});
return segments;
}
// Generate actionable insights
generateInsights() {
const insights = {
content_priorities: this.analyzeContentPreferences(),
marketing_channels: this.analyzeDiscoveryMethods(),
pain_points: this.analyzeChallenges(),
optimization_opportunities: this.analyzeImprovements(),
communication_strategy: this.analyzeCommunicationPrefs()
};
return insights;
}
analyzeContentPreferences() {
const contentScores = {
care_guides: 0,
announcements: 0,
inspiration: 0,
troubleshooting: 0,
species_profiles: 0
};
this.responses.forEach(response => {
const rankings = response.responses.content_ranking || {};
Object.keys(rankings).forEach(contentType => {
const rank = parseInt(rankings[contentType]);
if (rank) {
// Higher priority for lower rank numbers (1 = most important)
contentScores[contentType] += (6 - rank);
}
});
});
// Sort by priority score
return Object.entries(contentScores)
.sort(([,a], [,b]) => b - a)
.map(([type, score]) => ({ type, priority_score: score }));
}
analyzeChallenges() {
const challengeCounts = {};
this.responses.forEach(response => {
const challenge = response.responses.biggest_challenge;
if (challenge) {
challengeCounts[challenge] = (challengeCounts[challenge] || 0) + 1;
}
});
return Object.entries(challengeCounts)
.sort(([,a], [,b]) => b - a)
.map(([challenge, count]) => ({
challenge,
customer_count: count,
percentage: (count / this.responses.length * 100).toFixed(1)
}));
}
// Generate personalized recommendations for each customer
generatePersonalizedRecommendations(customerId) {
const customerResponse = this.responses.find(r => r.customer_id === customerId);
if (!customerResponse) return null;
const recommendations = {
product_categories: [],
content_suggestions: [],
communication_preferences: {},
timing_optimization: {}
};
// Product recommendations based on setup types and challenges
const setups = customerResponse.responses.setup_types || [];
const challenge = customerResponse.responses.biggest_challenge;
if (setups.includes('planted') && challenge === 'plant_health') {
recommendations.product_categories.push('fertilizers', 'plant_care_tools', 'substrate');
recommendations.content_suggestions.push('plant_nutrition_guide', 'troubleshooting_plant_issues');
}
if (setups.includes('freshwater') && challenge === 'water_quality') {
recommendations.product_categories.push('water_testing_kits', 'filtration', 'water_conditioners');
recommendations.content_suggestions.push('water_chemistry_basics', 'filtration_guide');
}
// Communication preferences
const commPrefs = customerResponse.responses.communication_prefs || [];
recommendations.communication_preferences = {
email: commPrefs.includes('email'),
social_media: commPrefs.includes('social_media'),
blog_notifications: commPrefs.includes('blog_notifications'),
frequency: customerResponse.responses.email_frequency || 'weekly'
};
// Shopping timing optimization
const shoppingTimes = customerResponse.responses.shopping_times || [];
recommendations.timing_optimization = {
preferred_times: shoppingTimes,
email_send_time: this.getOptimalEmailTime(shoppingTimes),
ad_schedule: this.getOptimalAdSchedule(shoppingTimes)
};
return recommendations;
}
getOptimalEmailTime(shoppingTimes) {
if (shoppingTimes.includes('weekday_evening')) return '18:00';
if (shoppingTimes.includes('weekend_morning')) return '09:00';
if (shoppingTimes.includes('lunch_breaks')) return '12:00';
return '18:00'; // default
}
getOptimalAdSchedule(shoppingTimes) {
const schedule = [];
if (shoppingTimes.includes('weekday_morning')) schedule.push('mon-fri 8-11');
if (shoppingTimes.includes('weekday_evening')) schedule.push('mon-fri 17-21');
if (shoppingTimes.includes('weekend_morning')) schedule.push('sat-sun 9-12');
if (shoppingTimes.includes('weekend_evening')) schedule.push('sat-sun 18-21');
return schedule;
}
}
// 3. AUTOMATED ACTIONS BASED ON SURVEY DATA
class AutomatedCustomerActions {
constructor(segmentAnalyzer) {
this.analyzer = segmentAnalyzer;
}
// Automatically tag customers in Shopify based on survey responses
async tagCustomers() {
const segments = this.analyzer.createSegments();
for (const [segmentType, customers] of Object.entries(segments)) {
for (const [segmentName, customerList] of Object.entries(customers)) {
await this.batchTagCustomers(customerList, `survey_${segmentName}`);
}
}
}
async batchTagCustomers(customers, tag) {
const customerIds = customers.map(c => c.customer_id);
// Shopify Admin API call to add tags
await fetch('/admin/api/2023-07/customers/batch.json', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'your-access-token'
},
body: JSON.stringify({
customers: customerIds.map(id => ({
id: id,
tags: tag
}))
})
});
}
// Create automated email sequences based on customer segments
setupEmailAutomation() {
const segments = this.analyzer.createSegments();
// Beginner sequence
this.createEmailSequence('beginners', [
{ delay: 1, subject: 'Welcome to Your Aquarium Journey!', template: 'beginner_welcome' },
{ delay: 3, subject: 'Essential Care Tips for New Aquarists', template: 'beginner_care' },
{ delay: 7, subject: 'Troubleshooting Common Issues', template: 'beginner_troubleshoot' }
]);
// Advanced sequence
this.createEmailSequence('advanced', [
{ delay: 1, subject: 'Advanced Techniques You\'ll Love', template: 'advanced_welcome' },
{ delay: 5, subject: 'New Rare Species Available', template: 'rare_species_alert' }
]);
}
async createEmailSequence(segment, emails) {
// Integration with email platform (Klaviyo, Mailchimp, etc.)
for (const email of emails) {
await this.scheduleEmail(segment, email);
}
}
}
// 4. USAGE EXAMPLE
// Initialize the system with survey responses
const responses = []; // Your collected survey data
const analyzer = new CustomerSegmentAnalyzer(responses);
const automator = new AutomatedCustomerActions(analyzer);
// Generate insights
const insights = analyzer.generateInsights();
console.log('Content Priorities:', insights.content_priorities);
console.log('Top Pain Points:', insights.pain_points);
// Get personalized recommendations for a specific customer
const customerRecs = analyzer.generatePersonalizedRecommendations('customer_123');
console.log('Personalized Recommendations:', customerRecs);
// Set up automated actions
automator.tagCustomers();
automator.setupEmailAutomation();
// 5. SHOPIFY INTEGRATION WEBHOOK HANDLER
// This would be your server-side endpoint to receive survey data
/*
POST /apps/survey-collector/submit
{
"timestamp": "2025-06-19T10:30:00Z",
"customer_id": "123456",
"order_id": "789012",
"responses": {
"experience_level": "intermediate",
"setup_types": ["freshwater", "planted"],
"biggest_challenge": "plant_health",
"monthly_budget": "50_100",
// ... all other responses
}
}
*/
function handleSurveySubmission(req, res) {
const surveyData = req.body;
// Store in database
saveSurveyResponse(surveyData);
// Trigger immediate actions
const analyzer = new CustomerSegmentAnalyzer([surveyData]);
const recommendations = analyzer.generatePersonalizedRecommendations(surveyData.customer_id);
// Update customer profile in Shopify
updateShopifyCustomer(surveyData.customer_id, {
tags: generateCustomerTags(surveyData.responses),
note: `Survey completed: ${surveyData.timestamp}`
});
// Trigger personalized email sequence
triggerEmailSequence(surveyData.customer_id, recommendations);
res.json({ success: true, discount_code: 'SURVEY10' });
}