- Node.js (v14 or higher)
- Google Cloud Platform account
- Twilio account
- Typeform account
npm install dotenv papaparse googleapis twilio express nanoid libphonenumber-js- Go to Google Cloud Console
- Create a new project (or select existing)
- Enable the Google Sheets API:
- Navigate to "APIs & Services" > "Library"
- Search for "Google Sheets API"
- Click "Enable"
- Navigate to "APIs & Services" > "Credentials"
- Click "Create Credentials" > "Service Account"
- Fill in the details:
- Name:
voter-survey-workflow - Description:
Service account for voter survey automation
- Name:
- Click "Create and Continue"
- Grant role: "Editor" (or create custom role with Sheets access)
- Click "Done"
- Click on the service account you just created
- Go to the "Keys" tab
- Click "Add Key" > "Create new key"
- Choose JSON format
- Download the file and save it as
credentials.jsonin your project directory
.gitignore
Option 1: Create manually
- Go to Google Sheets
- Create a new spreadsheet
- Name it "Voter Survey Database" (or your preferred name)
- Copy the Spreadsheet ID from the URL:
https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID/edit
Option 2: Create via test script
node test-workflow.js create-spreadsheet- Open your spreadsheet
- Click "Share" button
- Add the service account email (found in
credentials.jsonunderclient_email) - Grant "Editor" permissions
- Uncheck "Notify people"
- Click "Share"
- Sign up at Twilio
- Get a phone number with SMS capabilities
- Find your credentials in the Twilio Console:
- Account SID
- Auth Token
- Phone Number (format: +1XXXXXXXXXX)
Create a .env file in your project root:
# Google Sheets Configuration
GOOGLE_CREDENTIALS_PATH=./credentials.json
GOOGLE_SPREADSHEET_ID=your_spreadsheet_id_here
GOOGLE_SHEET_NAME=Voter Survey
# Twilio Configuration
TWILIO_ACCOUNT_SID=your_account_sid
TWILIO_AUTH_TOKEN=your_auth_token
TWILIO_FROM_NUMBER=+1234567890
# Survey Configuration
SURVEY_BASE_URL=https://yourform.typeform.com/to/form_id
UTM_CAMPAIGN=jerseycity_survey_oct2025
# Webhook Configuration (optional)
PORT=3000Run the test suite:
# Test all connections
node test-workflow.js all
# Test individual components
node test-workflow.js config # Validate configuration
node test-workflow.js sheets # Test Google Sheets connection
node test-workflow.js twilio # Test Twilio connectionnode test-workflow.js generate-csvThis creates sample-voters.csv with test data.
# Import without sending SMS
node voter-survey-workflow.js import sample-voters.csv
# Import and send SMS
node voter-survey-workflow.js import sample-voters.csv --send-sms- In Typeform, go to your form settings
- Navigate to "Connect" > "Webhooks"
- Add webhook URL:
https://your-domain.com/webhook/typeform - Make sure to include
utm_idas a hidden field in your form
Use ngrok to expose your local server:
# Start the webhook server
node voter-survey-workflow.js webhook
# In another terminal, start ngrok
ngrok http 3000
# Use the ngrok URL in Typeform webhook settings
# Example: https://abc123.ngrok.io/webhook/typeform-
Never commit credentials:
echo "credentials.json" >> .gitignore echo ".env" >> .gitignore
-
Use environment-specific credentials:
- Development: Use test Twilio numbers
- Production: Use production credentials
-
Limit service account permissions:
- Only grant access to specific spreadsheets
- Use custom IAM roles if possible
-
Rotate credentials regularly:
- Generate new service account keys periodically
- Update Twilio auth tokens if compromised
Error: "The caller does not have permission"
- Verify service account email is shared with the spreadsheet
- Check that the Google Sheets API is enabled
- Ensure service account has proper IAM roles
Error: "Unable to parse range"
- Check that
GOOGLE_SHEET_NAMEmatches the sheet tab name - Sheet names are case-sensitive
Error: "Unable to create record: The 'From' number is not a valid phone number"
- Ensure phone number is in E.164 format (+1XXXXXXXXXX)
- Verify the number is SMS-enabled in Twilio console
Error: "Authentication Error"
- Double-check Account SID and Auth Token
- Ensure no extra spaces in
.envfile
"No valid records to process"
- Check that CSV has required columns:
FirstName,Voter File VANID,Home PhoneorLandlinePhone - Verify phone numbers are in valid formats
- Review cleaned data logs for skipped records
- Set up automated imports with cron jobs
- Configure production webhook endpoints
- Set up monitoring and logging
- Create backup procedures for your spreadsheet
For issues with:
- Google Sheets API: Google Sheets API Documentation
- Twilio: Twilio Support
- This workflow: Check logs and test suite output