Streamline your customer support workflow without additional licensing costs — perfect for small businesses and teams just getting started with Salesforce.
For small to medium-sized businesses using Salesforce, managing customer support inquiries can be challenging. Commercial solutions often come with hefty price tags, and custom development requires specialized knowledge.
What if you could leverage tools you already have — specifically Google Forms and Salesforce — to create a streamlined support system?
In this guide, I'll walk you through a cost-effective integration that automatically converts Google Form submissions into Salesforce cases. This solution offers:
- Zero additional licensing costs (works with standard Google Workspace and Salesforce)
- Automatic case creation from form submissions
- Detailed submission logging for troubleshooting
- Field mapping for standard and custom Salesforce fields
- Robust error handling and validation
This solution is ideal for:
- Support ticket collection
- Feature requests tracking
- Bug reporting systems
- Customer feedback management
Let's dive in!
The integration follows a simple workflow:
- A user submits a Google Form
- Google Apps Script triggers automatically
- The script formats the data for Salesforce
- Data is sent to Salesforce's Web-to-Case endpoint
- A new case is created in Salesforce
- The submission is logged for monitoring
Before you begin, ensure you have:
- Administrator access to both Google Forms and Salesforce
- Web-to-Case enabled in Salesforce:
- Navigate to Salesforce Setup → Feature Settings → Service → Web-to-Case
- Click "Enable Web-to-Case" if not already enabled
Design your form with fields that map to Salesforce Case fields:
- Required fields:
- Subject (Short answer or paragraph)
- Description (Paragraph)
- Optional fields:
- First Name (Short answer)
- Last Name (Short answer)
- Phone (Short answer with validation)
- Priority (Multiple choice: Low, Medium, High, Critical)
- Custom fields (According to your Salesforce configuration)
Pro tip: Keep the field names exactly as listed above to simplify the mapping process.
- Open your Google Form in the editor
- Click on the three dots menu (⋮) in the top right corner and select "Script editor"
- Copy and paste the following code:
/**
* Handles form submission and sends data to Salesforce Web-to-Case
* This script processes Google Form submissions and creates Salesforce cases
*/
function onFormSubmit(e) {
try {
// Validate input event
if (!e || !e.response) {
throw new Error('Invalid form submission event');
}
// Get the form response
var formResponse = e.response;
var itemResponses = formResponse.getItemResponses();
var formData = {};
// Track required fields to ensure we have minimum data for a case
var hasRequiredFields = {
subject: false,
description: false
};
// Map form responses to Salesforce fields
for (var i = 0; i < itemResponses.length; i++) {
var itemResponse = itemResponses[i];
var title = itemResponse.getItem().getTitle();
var answer = itemResponse.getResponse();
// Skip empty answers
if (!answer || answer.toString().trim() === '') {
continue;
}
// Map Google Form questions to Salesforce fields
// Adjust these mappings according to your form and Salesforce setup
switch (title) {
case "Subject":
formData['subject'] = answer;
hasRequiredFields.subject = true;
break;
case "Description":
formData['description'] = answer;
hasRequiredFields.description = true;
break;
case "First Name":
formData['first_name'] = answer;
break;
case "Last Name":
formData['last_name'] = answer;
break;
case "Phone":
// Basic phone format validation
formData['phone'] = answer.toString().replace(/[^\d+()-.\s]/g, '');
break;
case "Priority":
// Ensure valid priority values
var priority = answer.toString().toLowerCase();
if (['low', 'medium', 'high', 'critical'].includes(priority)) {
formData['priority'] = priority;
}
break;
case "Origin":
formData['origin'] = answer;
break;
// Add more mappings as needed
default:
// Handle custom fields - uncomment and customize as needed
// if (title === "Your Custom Field") {
// formData['00N3X00000XXXXX'] = answer;
// }
break;
}
}
// Validate required fields
var missingFields = [];
for (var field in hasRequiredFields) {
if (!hasRequiredFields[field]) {
missingFields.push(field);
}
}
if (missingFields.length > 0) {
throw new Error('Missing required fields: ' + missingFields.join(', '));
}
// Add required Salesforce Web-to-Case fields
formData['orgid'] = '00D000000000XXX'; // Replace with your Salesforce Organization ID
formData['retURL'] = 'https://www.example.com/thank-you'; // Thank you page
// Optional: Add record type if needed
// formData['recordType'] = '012000000000XXX'; // Replace with your Record Type ID
// Send data to Salesforce Web-to-Case endpoint
var options = {
'method': 'post',
'payload': formData,
'muteHttpExceptions': true // Capture HTTP errors in our code
};
Logger.log('Sending case to Salesforce with fields: ' + JSON.stringify(formData));
var response = UrlFetchApp.fetch('https://webto.salesforce.com/servlet/servlet.WebToCase', options);
// Check response
var responseCode = response.getResponseCode();
if (responseCode >= 200 && responseCode < 300) {
Logger.log('Case created successfully in Salesforce');
// Optional: Store submission ID for reference
var spreadsheetId = PropertiesService.getScriptProperties().getProperty('SUBMISSION_LOG_SPREADSHEET_ID');
if (spreadsheetId) {
logSubmission(spreadsheetId, formData, true);
}
} else {
var errorText = response.getContentText();
Logger.log('Error from Salesforce: ' + responseCode + ' - ' + errorText);
throw new Error('Salesforce returned error: ' + responseCode);
}
} catch (error) {
Logger.log('Error creating Salesforce case: ' + error.toString());
// Optional: Log failed submissions
var spreadsheetId = PropertiesService.getScriptProperties().getProperty('SUBMISSION_LOG_SPREADSHEET_ID');
if (spreadsheetId) {
logSubmission(spreadsheetId, formData || {}, false, error.toString());
}
}
}
/**
* Logs submission details to a spreadsheet for tracking
* Optional but highly recommended for troubleshooting
*/
function logSubmission(spreadsheetId, formData, success, errorMessage) {
try {
var sheet = SpreadsheetApp.openById(spreadsheetId).getActiveSheet();
var timestamp = new Date();
// Create a row with submission details
var rowData = [
timestamp,
success ? 'Success' : 'Failed',
formData['subject'] || '',
formData['first_name'] || '',
formData['last_name'] || '',
success ? '' : (errorMessage || 'Unknown error')
];
sheet.appendRow(rowData);
} catch (e) {
Logger.log('Error logging submission: ' + e.toString());
}
}
/**
* Setup function to initialize script properties
* Run this once to configure your script
*/
function setup() {
// Create a spreadsheet to log submissions
var spreadsheet = SpreadsheetApp.create('Salesforce Case Submission Log');
var sheet = spreadsheet.getActiveSheet();
// Set up headers
sheet.appendRow([
'Timestamp', 'Status', 'Subject', 'First Name', 'Last Name', 'Error'
]);
// Format the spreadsheet
sheet.setFrozenRows(1);
spreadsheet.getRange('A1:F1').setBackground('#f3f3f3').setFontWeight('bold');
// Save the spreadsheet ID to script properties
PropertiesService.getScriptProperties().setProperty(
'SUBMISSION_LOG_SPREADSHEET_ID',
spreadsheet.getId()
);
Logger.log('Setup complete. Submission log created: ' + spreadsheet.getUrl());
}
- Save the script (File > Save) with a descriptive name like "Salesforce Case Integration"
You'll need to update several key values in the script:
-
Salesforce Organization ID:
- In Salesforce, navigate to Setup → Company Information
- Copy your Organization ID (it starts with "00D")
- Replace
'00D000000000XXX'
in the script with your ID
-
Thank You Page URL:
- Replace
'https://www.example.com/thank-you'
with the URL where users should be redirected after submission - This can be a page on your website or a custom Google Form confirmation page
- Replace
-
Field Mappings:
- Make sure the case titles in the switch statement match exactly with your Google Form questions
- For custom fields, uncomment and modify the code in the default section of the switch statement
The logging system helps track and troubleshoot form submissions:
- In the script editor, click on "Run" in the menu
- Select the "setup" function to run it
- When prompted, authorize the script to access your Google account
- After running, check the logs (View > Logs) for a URL to the created spreadsheet
- Bookmark this spreadsheet for future reference
- In the script editor, click on the clock icon (Triggers) in the left sidebar
- Click "Add Trigger" button
- Configure the trigger with these settings:
- Choose which function to run:
onFormSubmit
- Choose which deployment should run: "Head"
- Select event source: "From form"
- Select event type: "On form submit"
- Failure notification settings: "Notify me daily" (recommended)
- Choose which function to run:
- Click "Save"
- Authorize the script when prompted
Before going live, perform a complete test:
- Submit a test entry through your Google Form
- Check the Apps Script logs for execution details (View > Logs)
- Verify that a case was created in Salesforce
- Verify that the submission was logged in your spreadsheet
Standard fields use predictable naming in the Web-to-Case API:
subject
- Case subjectdescription
- Case descriptionfirst_name
- Contact first namelast_name
- Contact last namephone
- Contact phonepriority
- Case priorityorigin
- Case origin
For custom fields, you'll need to find the field ID:
- In Salesforce, go to Setup → Object Manager → Case → Fields & Relationships
- Click on the custom field you want to use
- In the URL of the field details page, look for the "id" parameter (e.g., 00N3X00000XXXXX)
- In the script, use this ID as the key in the formData object:
formData['00N3X00000XXXXX'] = answer;
When implementing this solution, keep these security considerations in mind:
-
Data Privacy:
- Only collect information necessary for case resolution
- Include appropriate privacy notices on your form
- Consider encryption for sensitive data in the logging spreadsheet
-
Authentication:
- The script runs with the permissions of the Google Form owner
- Limit access to the Google Form and Google Apps Script
- Review Script authorization scopes carefully
-
Error Handling:
- Monitor error notifications regularly
- Check the submission log for failures
- Consider implementing rate limiting to prevent abuse
-
Check the script logs:
- In Script Editor, go to View > Logs
- Look for specific error messages
-
Verify Salesforce configuration:
- Confirm Web-to-Case is enabled
- Double-check your Organization ID (must start with 00D)
- Check if any validation rules in Salesforce are blocking case creation
-
Field mapping issues:
- Ensure Google Form question titles exactly match the switch statement cases
- Check for required fields that might be missing
- Verify custom field IDs are correct
If you encounter permission problems:
-
Re-authorize the script:
- In Script Editor: Run > Run Function > setup
- Follow the authorization prompts
-
Check execution transcript:
- After a form submission, check View > Execution Transcript
- Look for permission or authorization errors
If your Salesforce org uses record types:
- Get your Record Type ID from Salesforce
- Uncomment and update the recordType line in the code:
formData['recordType'] = '012000000000XXX'; // Your Record Type ID
You can add routing logic based on form responses:
// Example for routing based on priority
if (formData['priority'] === 'high' || formData['priority'] === 'critical') {
// Add a tag or assign to a specific queue
formData['00N3X00000XXXXX'] = 'Urgent'; // Custom field for tagging
}
While Google Forms doesn't natively support file uploads, you can:
- Ask users to provide links to files in cloud storage
- Use a Google Form add-on that supports file uploads
- Create a custom web form instead of using Google Forms
This Google Forms to Salesforce Web-to-Case integration offers a powerful yet simple way to streamline your customer support workflows without additional costs. By leveraging tools you already have access to, you can create a robust system that automatically converts form submissions into actionable support cases.
The solution is flexible enough to accommodate various use cases and can be extended with custom fields and conditional logic to meet your specific business requirements.
Have you implemented something similar? I'd love to hear about your experiences and any customizations you've made to the solution!
Want to take your Salesforce and Google Workspace integration to the next level? Follow me for more practical guides on streamlining your business processes with low-code solutions.
#Salesforce #GoogleWorkspace #CustomerSupport #Automation #CRM #NoCode #LowCode #Integration #ProductivityHacks