# 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

๐Ÿฆ€ Welcome to Rust Meetup 2025!

Provisioning: Infrastructure Automation with Rust, Nushell & KCL

Hi {{attendee_name}},

Thank you for registering! We're excited to have you join us for an exciting deep dive into modern infrastructure automation.

๐Ÿ“… Event Details

๐ŸŽฏ What to Expect

Based on your survey responses, we'll cover:

๐Ÿ“ฑ Interactive Participation

We'll be using live polls during the presentation. Save this QR code or link:

Join Live Polls

๐Ÿ“š Pre-Event Resources

Optional reading to get the most out of the session:

๐Ÿ“… Add to Calendar
``` ### Post-Event Follow-up Email **Subject**: ๐Ÿ™ Thank you for joining Rust Meetup 2025! ```rust html

๐Ÿ™ Thank you for joining us!

Your feedback shapes our community

Hi {{attendee_name}},

Thank you for attending Rust Meetup 2025! It was great having you as part of our community exploring the future of infrastructure automation.

๐Ÿ“Š Quick Feedback Survey

Help us improve future events (takes 3 minutes):

Share Your Feedback

๐Ÿ“š Session Resources

๐Ÿš€ Next Steps

Ready to get started? Here's how:

๐ŸŽฏ Personalized for You

Based on your interests in {{learning_focus}}:

Have questions? Our community is here to help! Join the discussion or reach out directly.

๐Ÿ’ฌ Join Community
``` --- ## ๐Ÿ”ง 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.