805 lines
No EOL
26 KiB
Markdown
805 lines
No EOL
26 KiB
Markdown
# Automation Workflows & Integration Scripts
|
|
|
|
## Rust Meetup 2025 - Complete Automation Setup
|
|
|
|
This document provides ready-to-use automation workflows, integration scripts, and configuration for seamless event management.
|
|
|
|
---
|
|
|
|
## 🔗 Zapier Workflow Configurations
|
|
|
|
### Workflow 1: Pre-Event Registration Automation
|
|
|
|
**Trigger**: New Typeform submission (Pre-event survey)
|
|
|
|
**Steps**:
|
|
|
|
1. **Typeform** → New entry in pre-event survey
|
|
2. **Airtable** → Create record in "Attendees" table
|
|
3. **Airtable** → Create record in "Pre-Event Responses" table
|
|
4. **Gmail** → Send confirmation email
|
|
5. **Mailchimp** → Add to event mailing list
|
|
6. **Slack** → Notify team of new registration
|
|
|
|
**Zapier Configuration JSON**:
|
|
|
|
```toml
|
|
json
|
|
{
|
|
"name": "Pre-Event Registration Flow",
|
|
"steps": [
|
|
{
|
|
"app": "Typeform",
|
|
"trigger": "New Entry",
|
|
"form_id": "your_pre_event_form_id"
|
|
},
|
|
{
|
|
"app": "Airtable",
|
|
"action": "Create Record",
|
|
"base_id": "your_base_id",
|
|
"table": "Attendees",
|
|
"fields": {
|
|
"email": "{{1.email}}",
|
|
"name": "{{1.name}}",
|
|
"role": "{{1.role}}",
|
|
"experience_years": "{{1.experience}}",
|
|
"rust_level": "{{1.rust_level}}",
|
|
"company_size": "{{1.company_size}}",
|
|
"registration_date": "{{1.submitted_at}}",
|
|
"attendance_status": "Registered",
|
|
"pre_survey_completed": true
|
|
}
|
|
},
|
|
{
|
|
"app": "Airtable",
|
|
"action": "Create Record",
|
|
"base_id": "your_base_id",
|
|
"table": "Pre-Event Responses",
|
|
"fields": {
|
|
"attendee": "{{2.id}}",
|
|
"current_tools": "{{1.current_tools}}",
|
|
"deployment_contexts": "{{1.deployment_contexts}}",
|
|
"top_challenges": "{{1.challenges}}",
|
|
"learning_expectations": "{{1.learning_expectations}}",
|
|
"implementation_likelihood": "{{1.implementation_likelihood}}",
|
|
"specific_questions": "{{1.specific_questions}}",
|
|
"manual_tasks_time": "{{1.manual_time}}",
|
|
"infrastructure_budget": "{{1.budget}}",
|
|
"submission_timestamp": "{{1.submitted_at}}"
|
|
}
|
|
},
|
|
{
|
|
"app": "Gmail",
|
|
"action": "Send Email",
|
|
"to": "{{1.email}}",
|
|
"subject": "🦀 Welcome to Rust Meetup 2025!",
|
|
"body": "see email_templates.md"
|
|
},
|
|
{
|
|
"app": "Mailchimp",
|
|
"action": "Add/Update Subscriber",
|
|
"list_id": "your_mailchimp_list_id",
|
|
"email": "{{1.email}}",
|
|
"merge_fields": {
|
|
"FNAME": "{{1.name}}",
|
|
"ROLE": "{{1.role}}",
|
|
"RUST_LVL": "{{1.rust_level}}"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Workflow 2: Live Event Engagement Tracking
|
|
|
|
**Trigger**: New Mentimeter poll response
|
|
|
|
**Steps**:
|
|
|
|
1. **Mentimeter** → Poll response received
|
|
2. **Airtable** → Update Live Event Engagement
|
|
3. **Filter** → High engagement score (≥8)
|
|
4. **Airtable** → Create follow-up action
|
|
5. **Slack** → Alert team about high-engagement attendee
|
|
|
|
### Workflow 3: Post-Event Follow-up Automation
|
|
|
|
**Trigger**: Attendance status changed to "Attended"
|
|
|
|
**Steps**:
|
|
|
|
1. **Airtable** → Attendance status = "Attended"
|
|
2. **Delay** → Wait 1 day
|
|
3. **Filter** → Post survey not completed
|
|
4. **Gmail** → Send post-event survey
|
|
5. **Airtable** → Create follow-up action
|
|
6. **Delay** → Wait 3 days
|
|
7. **Filter** → Still no survey response
|
|
8. **Gmail** → Send reminder email
|
|
|
|
---
|
|
|
|
## 📧 Email Templates
|
|
|
|
### Pre-Event Confirmation Email
|
|
|
|
**Subject**: 🦀 Welcome to Rust Meetup 2025!
|
|
|
|
```rust
|
|
html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<style>
|
|
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
|
|
.header { background: linear-gradient(135deg, #CE422B, #1a1a1a); color: white; padding: 20px; text-align: center; }
|
|
.content { padding: 20px; }
|
|
.event-details { background: #f8f9fa; padding: 15px; border-radius: 8px; margin: 20px 0; }
|
|
.cta-button { background: #CE422B; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block; margin: 10px 0; }
|
|
.footer { background: #f8f9fa; padding: 20px; text-align: center; font-size: 0.9em; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<h1>🦀 Welcome to Rust Meetup 2025!</h1>
|
|
<p>Provisioning: Infrastructure Automation with Rust, Nushell & KCL</p>
|
|
</div>
|
|
|
|
<div class="content">
|
|
<p>Hi {{attendee_name}},</p>
|
|
|
|
<p>Thank you for registering! We're excited to have you join us for an exciting deep dive into modern infrastructure automation.</p>
|
|
|
|
<div class="event-details">
|
|
<h3>📅 Event Details</h3>
|
|
<ul>
|
|
<li><strong>Date:</strong> [Event Date]</li>
|
|
<li><strong>Time:</strong> [Event Time]</li>
|
|
<li><strong>Location:</strong> [Venue/Virtual Link]</li>
|
|
<li><strong>Duration:</strong> 90 minutes + Q&A</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<h3>🎯 What to Expect</h3>
|
|
<p>Based on your survey responses, we'll cover:</p>
|
|
<ul>
|
|
<li>✅ Solutions for your top challenge: <strong>{{top_challenge}}</strong></li>
|
|
<li>🚀 {{rust_level}} friendly explanations and examples</li>
|
|
<li>💰 Cost optimization strategies for {{company_size}} organizations</li>
|
|
<li>⚡ Live demos and interactive Q&A</li>
|
|
</ul>
|
|
|
|
<h3>📱 Interactive Participation</h3>
|
|
<p>We'll be using live polls during the presentation. Save this QR code or link:</p>
|
|
<p><a href="https://www.menti.com/your-code" class="cta-button">Join Live Polls</a></p>
|
|
|
|
<h3>📚 Pre-Event Resources</h3>
|
|
<p>Optional reading to get the most out of the session:</p>
|
|
<ul>
|
|
<li><a href="#">Rust for Infrastructure: Getting Started Guide</a></li>
|
|
<li><a href="#">Nushell Quick Reference</a></li>
|
|
<li><a href="#">KCL Configuration Language Overview</a></li>
|
|
</ul>
|
|
|
|
<a href="[calendar_link]" class="cta-button">📅 Add to Calendar</a>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
<p>Questions? Reply to this email or reach out on our Discord: <a href="#">rust-infrastructure</a></p>
|
|
<p>See you there! 🚀</p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
### Post-Event Follow-up Email
|
|
|
|
**Subject**: 🙏 Thank you for joining Rust Meetup 2025!
|
|
|
|
```rust
|
|
html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<style>
|
|
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
|
|
.header { background: linear-gradient(135deg, #CE422B, #1a1a1a); color: white; padding: 20px; text-align: center; }
|
|
.content { padding: 20px; }
|
|
.resource-box { background: #f8f9fa; padding: 15px; border-radius: 8px; margin: 15px 0; }
|
|
.cta-button { background: #CE422B; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block; margin: 10px 0; }
|
|
.footer { background: #f8f9fa; padding: 20px; text-align: center; font-size: 0.9em; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<h1>🙏 Thank you for joining us!</h1>
|
|
<p>Your feedback shapes our community</p>
|
|
</div>
|
|
|
|
<div class="content">
|
|
<p>Hi {{attendee_name}},</p>
|
|
|
|
<p>Thank you for attending Rust Meetup 2025! It was great having you as part of our community exploring the future of infrastructure automation.</p>
|
|
|
|
<div class="resource-box">
|
|
<h3>📊 Quick Feedback Survey</h3>
|
|
<p>Help us improve future events (takes 3 minutes):</p>
|
|
<a href="{{post_survey_link}}" class="cta-button">Share Your Feedback</a>
|
|
</div>
|
|
|
|
<div class="resource-box">
|
|
<h3>📚 Session Resources</h3>
|
|
<ul>
|
|
<li><a href="#">Complete slide deck with speaker notes</a></li>
|
|
<li><a href="#">Demo code repository</a></li>
|
|
<li><a href="#">Getting started templates</a></li>
|
|
<li><a href="#">Implementation checklist</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="resource-box">
|
|
<h3>🚀 Next Steps</h3>
|
|
<p>Ready to get started? Here's how:</p>
|
|
<ul>
|
|
<li>🔧 <a href="#">Installation guide</a></li>
|
|
<li>💬 <a href="#">Join our Discord community</a></li>
|
|
<li>📖 <a href="#">Follow our GitHub organization</a></li>
|
|
<li>📰 <a href="#">Subscribe to updates</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="resource-box">
|
|
<h3>🎯 Personalized for You</h3>
|
|
<p>Based on your interests in <strong>{{learning_focus}}</strong>:</p>
|
|
<ul>
|
|
<li><a href="#">Recommended starter project</a></li>
|
|
<li><a href="#">Relevant documentation section</a></li>
|
|
<li><a href="#">Community discussion channel</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<p><strong>Have questions?</strong> Our community is here to help! Join the discussion or reach out directly.</p>
|
|
|
|
<a href="{{discord_link}}" class="cta-button">💬 Join Community</a>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
<p>Keep building awesome infrastructure! 🦀⚙️</p>
|
|
<p>Follow us: <a href="#">GitHub</a> | <a href="#">Discord</a> | <a href="#">Twitter</a></p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
---
|
|
|
|
## 🔧 Integration Scripts
|
|
|
|
### Mentimeter Data Export Script
|
|
|
|
```rust
|
|
python
|
|
#!/usr/bin/env python3
|
|
"""
|
|
Mentimeter to Airtable Integration Script
|
|
Exports poll data and calculates engagement scores
|
|
"""
|
|
|
|
import requests
|
|
import json
|
|
from datetime import datetime
|
|
import os
|
|
from typing import Dict, List
|
|
|
|
class MentimeterAirtableSync:
|
|
def __init__(self):
|
|
self.mentimeter_api_key = os.getenv('MENTIMETER_API_KEY')
|
|
self.airtable_api_key = os.getenv('AIRTABLE_API_KEY')
|
|
self.airtable_base_id = os.getenv('AIRTABLE_BASE_ID')
|
|
self.airtable_table = 'Live Event Engagement'
|
|
|
|
def get_mentimeter_data(self, presentation_id: str) -> List[Dict]:
|
|
"""Fetch poll responses from Mentimeter"""
|
|
url = f"https://api.mentimeter.com/v1/presentations/{presentation_id}/responses"
|
|
headers = {
|
|
'Authorization': f'Bearer {self.mentimeter_api_key}',
|
|
'Content-Type': 'application/json'
|
|
}
|
|
|
|
response = requests.get(url, headers=headers)
|
|
response.raise_for_status()
|
|
return response.json()
|
|
|
|
def calculate_engagement_score(self, participant_data: Dict) -> float:
|
|
"""Calculate engagement score based on participation metrics"""
|
|
polls_participated = len(participant_data.get('poll_responses', []))
|
|
questions_asked = len(participant_data.get('questions', []))
|
|
session_duration = participant_data.get('session_duration_minutes', 0)
|
|
|
|
# Weighted scoring: polls * 2 + questions * 3 + duration_factor
|
|
duration_factor = min(session_duration / 60, 1.5) # Cap at 1.5 hours
|
|
score = (polls_participated * 2 + questions_asked * 3 + duration_factor) / 3
|
|
|
|
return round(min(score, 10), 1) # Cap at 10
|
|
|
|
def sync_to_airtable(self, engagement_data: List[Dict]):
|
|
"""Upload engagement data to Airtable"""
|
|
url = f"https://api.airtable.com/v0/{self.airtable_base_id}/{self.airtable_table}"
|
|
headers = {
|
|
'Authorization': f'Bearer {self.airtable_api_key}',
|
|
'Content-Type': 'application/json'
|
|
}
|
|
|
|
# Batch create records
|
|
records = []
|
|
for data in engagement_data:
|
|
record = {
|
|
"fields": {
|
|
"attendee": [data.get('attendee_id')], # Link to attendee record
|
|
"session_start": data.get('session_start'),
|
|
"session_duration": data.get('session_duration_minutes'),
|
|
"polls_participated": len(data.get('poll_responses', [])),
|
|
"questions_asked": len(data.get('questions', [])),
|
|
"engagement_score": self.calculate_engagement_score(data),
|
|
"poll_responses": json.dumps(data.get('poll_responses', [])),
|
|
"questions_submitted": '\n'.join(data.get('questions', []))
|
|
}
|
|
}
|
|
records.append(record)
|
|
|
|
# Airtable batch limit is 10 records
|
|
for i in range(0, len(records), 10):
|
|
batch = records[i:i+10]
|
|
payload = {"records": batch}
|
|
response = requests.post(url, headers=headers, json=payload)
|
|
response.raise_for_status()
|
|
print(f"Synced batch {i//10 + 1}: {len(batch)} records")
|
|
|
|
def main():
|
|
"""Main execution function"""
|
|
sync = MentimeterAirtableSync()
|
|
presentation_id = os.getenv('MENTIMETER_PRESENTATION_ID')
|
|
|
|
try:
|
|
# Fetch data from Mentimeter
|
|
mentimeter_data = sync.get_mentimeter_data(presentation_id)
|
|
print(f"Fetched {len(mentimeter_data)} participant records")
|
|
|
|
# Process and sync to Airtable
|
|
sync.sync_to_airtable(mentimeter_data)
|
|
print("Sync completed successfully!")
|
|
|
|
except Exception as e:
|
|
print(f"Error during sync: {e}")
|
|
raise
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
```
|
|
|
|
### Automated Follow-up Script
|
|
|
|
```rust
|
|
python
|
|
#!/usr/bin/env python3
|
|
"""
|
|
Automated Follow-up Management Script
|
|
Manages post-event follow-up actions based on attendee data
|
|
"""
|
|
|
|
import requests
|
|
import json
|
|
from datetime import datetime, timedelta
|
|
import smtplib
|
|
from email.mime.text import MIMEText
|
|
from email.mime.multipart import MIMEMultipart
|
|
import os
|
|
|
|
class FollowUpManager:
|
|
def __init__(self):
|
|
self.airtable_api_key = os.getenv('AIRTABLE_API_KEY')
|
|
self.airtable_base_id = os.getenv('AIRTABLE_BASE_ID')
|
|
self.smtp_server = os.getenv('SMTP_SERVER', 'smtp.gmail.com')
|
|
self.smtp_port = int(os.getenv('SMTP_PORT', '587'))
|
|
self.smtp_username = os.getenv('SMTP_USERNAME')
|
|
self.smtp_password = os.getenv('SMTP_PASSWORD')
|
|
|
|
def get_attendees_needing_followup(self) -> List[Dict]:
|
|
"""Get attendees who need post-event follow-up"""
|
|
url = f"https://api.airtable.com/v0/{self.airtable_base_id}/Attendees"
|
|
headers = {'Authorization': f'Bearer {self.airtable_api_key}'}
|
|
|
|
# Filter for attended but no post-survey after 3 days
|
|
three_days_ago = (datetime.now() - timedelta(days=3)).isoformat()
|
|
filter_formula = f"AND({{attendance_status}} = 'Attended', {{post_survey_completed}} = FALSE(), {{registration_date}} < '{three_days_ago}')"
|
|
|
|
params = {
|
|
'filterByFormula': filter_formula,
|
|
'fields': ['email', 'name', 'role', 'rust_level', 'learning_expectations']
|
|
}
|
|
|
|
response = requests.get(url, headers=headers, params=params)
|
|
response.raise_for_status()
|
|
return response.json()['records']
|
|
|
|
def get_high_engagement_attendees(self) -> List[Dict]:
|
|
"""Get attendees with high engagement scores for priority follow-up"""
|
|
url = f"https://api.airtable.com/v0/{self.airtable_base_id}/Live Event Engagement"
|
|
headers = {'Authorization': f'Bearer {self.airtable_api_key}'}
|
|
|
|
params = {
|
|
'filterByFormula': '{engagement_score} >= 8',
|
|
'fields': ['attendee', 'engagement_score', 'questions_asked']
|
|
}
|
|
|
|
response = requests.get(url, headers=headers, params=params)
|
|
response.raise_for_status()
|
|
return response.json()['records']
|
|
|
|
def send_personalized_email(self, attendee: Dict, email_type: str):
|
|
"""Send personalized follow-up email"""
|
|
templates = {
|
|
'post_survey_reminder': {
|
|
'subject': '🦀 Quick feedback: How was Rust Meetup 2025?',
|
|
'template': 'post_survey_reminder.html'
|
|
},
|
|
'high_engagement_personal': {
|
|
'subject': '🚀 Thank you for your amazing engagement!',
|
|
'template': 'high_engagement_followup.html'
|
|
},
|
|
'community_invitation': {
|
|
'subject': '💬 Join the Rust Infrastructure Community',
|
|
'template': 'community_invitation.html'
|
|
}
|
|
}
|
|
|
|
template_info = templates[email_type]
|
|
|
|
# Load email template
|
|
with open(f"email_templates/{template_info['template']}", 'r') as f:
|
|
html_content = f.read()
|
|
|
|
# Personalize content
|
|
html_content = html_content.replace('{{attendee_name}}', attendee['fields']['name'])
|
|
html_content = html_content.replace('{{attendee_role}}', attendee['fields'].get('role', 'Developer'))
|
|
|
|
# Send email
|
|
msg = MIMEMultipart('alternative')
|
|
msg['Subject'] = template_info['subject']
|
|
msg['From'] = self.smtp_username
|
|
msg['To'] = attendee['fields']['email']
|
|
|
|
html_part = MIMEText(html_content, 'html')
|
|
msg.attach(html_part)
|
|
|
|
with smtplib.SMTP(self.smtp_server, self.smtp_port) as server:
|
|
server.starttls()
|
|
server.login(self.smtp_username, self.smtp_password)
|
|
server.send_message(msg)
|
|
|
|
print(f"Sent {email_type} email to {attendee['fields']['email']}")
|
|
|
|
def create_follow_up_action(self, attendee_id: str, action_type: str, priority: str = 'Medium'):
|
|
"""Create follow-up action in Airtable"""
|
|
url = f"https://api.airtable.com/v0/{self.airtable_base_id}/Follow-up Actions"
|
|
headers = {
|
|
'Authorization': f'Bearer {self.airtable_api_key}',
|
|
'Content-Type': 'application/json'
|
|
}
|
|
|
|
record = {
|
|
"fields": {
|
|
"attendee": [attendee_id],
|
|
"action_type": action_type,
|
|
"action_status": "Completed",
|
|
"priority": priority,
|
|
"scheduled_date": datetime.now().isoformat()[:10],
|
|
"completed_date": datetime.now().isoformat()[:10],
|
|
"assigned_to": "Automated System",
|
|
"notes": f"Automated {action_type} sent via follow-up script"
|
|
}
|
|
}
|
|
|
|
response = requests.post(url, headers=headers, json={"records": [record]})
|
|
response.raise_for_status()
|
|
|
|
def main():
|
|
"""Main execution function for follow-up management"""
|
|
manager = FollowUpManager()
|
|
|
|
try:
|
|
# Handle post-survey reminders
|
|
attendees_needing_survey = manager.get_attendees_needing_followup()
|
|
print(f"Found {len(attendees_needing_survey)} attendees needing survey follow-up")
|
|
|
|
for attendee in attendees_needing_survey:
|
|
manager.send_personalized_email(attendee, 'post_survey_reminder')
|
|
manager.create_follow_up_action(attendee['id'], 'Send post-event survey')
|
|
|
|
# Handle high-engagement personal follow-ups
|
|
high_engagement = manager.get_high_engagement_attendees()
|
|
print(f"Found {len(high_engagement)} high-engagement attendees")
|
|
|
|
for engagement_record in high_engagement:
|
|
attendee_id = engagement_record['fields']['attendee'][0]
|
|
# Get attendee details and send personal follow-up
|
|
# Implementation would fetch attendee details and send personalized email
|
|
|
|
print("Follow-up processing completed!")
|
|
|
|
except Exception as e:
|
|
print(f"Error during follow-up processing: {e}")
|
|
raise
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Analytics Dashboard Configuration
|
|
|
|
### Google Data Studio Dashboard Setup
|
|
|
|
```rust
|
|
json
|
|
{
|
|
"dashboard_config": {
|
|
"name": "Rust Meetup 2025 - Analytics Dashboard",
|
|
"data_sources": [
|
|
{
|
|
"name": "Airtable - Attendees",
|
|
"connector": "airtable",
|
|
"base_id": "your_base_id",
|
|
"table": "Attendees"
|
|
},
|
|
{
|
|
"name": "Typeform - Pre Event",
|
|
"connector": "typeform",
|
|
"form_id": "your_pre_event_form_id"
|
|
},
|
|
{
|
|
"name": "Typeform - Post Event",
|
|
"connector": "typeform",
|
|
"form_id": "your_post_event_form_id"
|
|
}
|
|
],
|
|
"pages": [
|
|
{
|
|
"name": "Registration Overview",
|
|
"charts": [
|
|
{
|
|
"type": "scorecard",
|
|
"title": "Total Registrations",
|
|
"metric": "COUNT(attendee_id)",
|
|
"dimension": "registration_date"
|
|
},
|
|
{
|
|
"type": "time_series",
|
|
"title": "Registrations Over Time",
|
|
"metric": "COUNT(attendee_id)",
|
|
"dimension": "registration_date"
|
|
},
|
|
{
|
|
"type": "pie_chart",
|
|
"title": "Role Distribution",
|
|
"metric": "COUNT(attendee_id)",
|
|
"dimension": "role"
|
|
},
|
|
{
|
|
"type": "bar_chart",
|
|
"title": "Rust Experience Levels",
|
|
"metric": "COUNT(attendee_id)",
|
|
"dimension": "rust_level"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Pre-Event Insights",
|
|
"charts": [
|
|
{
|
|
"type": "heat_map",
|
|
"title": "Tool Usage Heatmap",
|
|
"metric": "COUNT(response_id)",
|
|
"dimensions": ["role", "current_tools"]
|
|
},
|
|
{
|
|
"type": "bar_chart",
|
|
"title": "Top Infrastructure Challenges",
|
|
"metric": "COUNT(response_id)",
|
|
"dimension": "top_challenges",
|
|
"sort": "metric DESC"
|
|
},
|
|
{
|
|
"type": "donut_chart",
|
|
"title": "Implementation Timeline",
|
|
"metric": "COUNT(response_id)",
|
|
"dimension": "implementation_likelihood"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Event Engagement",
|
|
"charts": [
|
|
{
|
|
"type": "scorecard",
|
|
"title": "Average Engagement Score",
|
|
"metric": "AVG(engagement_score)"
|
|
},
|
|
{
|
|
"type": "histogram",
|
|
"title": "Engagement Score Distribution",
|
|
"metric": "COUNT(engagement_id)",
|
|
"dimension": "engagement_score"
|
|
},
|
|
{
|
|
"type": "scatter_plot",
|
|
"title": "Session Duration vs Engagement",
|
|
"x_axis": "session_duration",
|
|
"y_axis": "engagement_score",
|
|
"size": "polls_participated"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Post-Event Analysis",
|
|
"charts": [
|
|
{
|
|
"type": "gauge",
|
|
"title": "Overall Satisfaction",
|
|
"metric": "AVG(overall_rating)",
|
|
"min_value": 1,
|
|
"max_value": 5
|
|
},
|
|
{
|
|
"type": "bar_chart",
|
|
"title": "Most Valuable Aspects",
|
|
"metric": "COUNT(feedback_id)",
|
|
"dimension": "most_valuable_aspect"
|
|
},
|
|
{
|
|
"type": "funnel_chart",
|
|
"title": "Conversion Funnel",
|
|
"steps": [
|
|
"Registered",
|
|
"Attended",
|
|
"Post Survey Completed",
|
|
"Community Joined"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 Deployment Scripts
|
|
|
|
### Environment Setup Script
|
|
|
|
```rust
|
|
bash
|
|
#!/bin/bash
|
|
# setup_environment.sh - Set up all required environment variables
|
|
|
|
echo "🔧 Setting up Rust Meetup 2025 environment..."
|
|
|
|
# Create .env file
|
|
cat > .env << EOF
|
|
# Typeform Configuration
|
|
TYPEFORM_API_TOKEN=your_typeform_token
|
|
PRE_EVENT_FORM_ID=your_pre_event_form_id
|
|
POST_EVENT_FORM_ID=your_post_event_form_id
|
|
|
|
# Airtable Configuration
|
|
AIRTABLE_API_KEY=your_airtable_api_key
|
|
AIRTABLE_BASE_ID=your_base_id
|
|
|
|
# Mentimeter Configuration
|
|
MENTIMETER_API_KEY=your_mentimeter_api_key
|
|
MENTIMETER_PRESENTATION_ID=your_presentation_id
|
|
|
|
# Email Configuration
|
|
SMTP_SERVER=smtp.gmail.com
|
|
SMTP_PORT=587
|
|
SMTP_USERNAME=your_email@gmail.com
|
|
SMTP_PASSWORD=your_app_password
|
|
|
|
# Event Configuration
|
|
EVENT_DATE=2025-XX-XX
|
|
EVENT_TIME=18:00
|
|
TIMEZONE=UTC
|
|
|
|
# Zapier Webhooks
|
|
ZAPIER_WEBHOOK_PRE_EVENT=https://hooks.zapier.com/hooks/catch/xxxxx/
|
|
ZAPIER_WEBHOOK_POST_EVENT=https://hooks.zapier.com/hooks/catch/xxxxx/
|
|
|
|
EOF
|
|
|
|
echo "✅ Environment file created (.env)"
|
|
echo "⚠️ Please update all placeholder values with your actual API keys and IDs"
|
|
|
|
# Install Python dependencies
|
|
echo "📦 Installing Python dependencies..."
|
|
pip install -r requirements.txt
|
|
|
|
echo "🎉 Setup complete! Run './scripts/test_integrations.sh' to test connections"
|
|
```
|
|
|
|
### Testing Script
|
|
|
|
```rust
|
|
bash
|
|
#!/bin/bash
|
|
# test_integrations.sh - Test all API connections
|
|
|
|
source .env
|
|
|
|
echo "🧪 Testing all integrations..."
|
|
|
|
# Test Airtable connection
|
|
echo "Testing Airtable connection..."
|
|
curl -H "Authorization: Bearer $AIRTABLE_API_KEY" \
|
|
"https://api.airtable.com/v0/$AIRTABLE_BASE_ID/Attendees?maxRecords=1" \
|
|
--silent --fail && echo "✅ Airtable: Connected" || echo "❌ Airtable: Failed"
|
|
|
|
# Test Typeform connection
|
|
echo "Testing Typeform connection..."
|
|
curl -H "Authorization: Bearer $TYPEFORM_API_TOKEN" \
|
|
"https://api.typeform.com/forms/$PRE_EVENT_FORM_ID" \
|
|
--silent --fail && echo "✅ Typeform: Connected" || echo "❌ Typeform: Failed"
|
|
|
|
# Test email configuration
|
|
echo "Testing email configuration..."
|
|
python3 -c "
|
|
import smtplib
|
|
import os
|
|
try:
|
|
server = smtplib.SMTP(os.getenv('SMTP_SERVER'), int(os.getenv('SMTP_PORT')))
|
|
server.starttls()
|
|
server.login(os.getenv('SMTP_USERNAME'), os.getenv('SMTP_PASSWORD'))
|
|
server.quit()
|
|
print('✅ Email: Connected')
|
|
except Exception as e:
|
|
print(f'❌ Email: Failed - {e}')
|
|
"
|
|
|
|
echo "🏁 Integration testing complete!"
|
|
```
|
|
|
|
---
|
|
|
|
## 📋 Production Checklist
|
|
|
|
### Pre-Event (2 weeks before)
|
|
|
|
- [ ] Set up all API connections and test
|
|
- [ ] Configure Zapier workflows
|
|
- [ ] Create email templates
|
|
- [ ] Set up Airtable base with schema
|
|
- [ ] Configure Mentimeter presentation
|
|
- [ ] Test end-to-end registration flow
|
|
- [ ] Set up monitoring and alerts
|
|
|
|
### Event Day
|
|
|
|
- [ ] Verify all live polling is working
|
|
- [ ] Monitor registration flow
|
|
- [ ] Check Mentimeter connectivity
|
|
- [ ] Have backup engagement methods ready
|
|
- [ ] Monitor Airtable updates in real-time
|
|
|
|
### Post-Event (within 24 hours)
|
|
|
|
- [ ] Export all Mentimeter data
|
|
- [ ] Trigger post-event email sequence
|
|
- [ ] Generate preliminary analytics
|
|
- [ ] Review follow-up actions
|
|
- [ ] Document lessons learned
|
|
|
|
This comprehensive automation setup will handle the entire attendee journey from registration to post-event community building, providing valuable insights for continuous improvement. |