Data out · Google Sheets
A Google Sheet that fills itself as leads arrive.
Some people will always live in a spreadsheet. Outbound OS posts each event — new lead, reply, engaged — to a Google Apps Script web app you deploy on your own sheet, which writes it as a row under your header names.
- 01
CRM event
A lead is created, replies or becomes engaged
- 02
Apps Script
Receives the event and matches sheet headers
- 03
New sheet row
Adds the event’s lead data to your spreadsheet
Before you connect
What you need ready.
- A Google Sheet you control
- The supplied Apps Script deployed as a web app
- The deployment URL saved in Outbound OS
In your workspace
What this connection makes possible.
- Rows for lead.created, lead.replied and lead.engaged
- Columns matched by header name, so you can reorder or add columns
- Retries on temporary failures
- No Google OAuth or third-party add-on
Connect & verify
Set it up, one step at a time.
- 01
Add the script
In your sheet: Extensions → Apps Script. Paste the script below and save.
- 02
Deploy it as a web app
Deploy → New deployment → Web app, executing as you, with access for anyone who has the link.
- 03
Paste the URL
Copy the deployment URL into Integrations → Google Sheets, press Test, then Save.
Check the whole connection
Use the connection test and check that a sample row arrives under the expected column headings in your sheet.
Configuration exampleView code
const HEADERS = ['Event','ID','Name','Company','Mobile','Email','Country',
'Product','Quantity','Status','Score','Tier','Source',
'Deal Value','Created At'];
const FIELD_BY_HEADER = {
'Event': 'event', 'ID': 'id', 'Name': 'name', 'Company': 'company',
'Mobile': 'mobile', 'Email': 'email', 'Country': 'country',
'Product': 'product', 'Quantity': 'quantity', 'Status': 'status',
'Score': 'score', 'Tier': 'leadTier', 'Source': 'source',
'Deal Value': 'dealValue', 'Created At': 'createdAt'
};
function doPost(e) {
const data = JSON.parse(e.postData.contents);
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Leads') ||
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
if (sheet.getLastRow() === 0) sheet.appendRow(HEADERS);
const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn())
.getValues()[0].map(String);
sheet.appendRow(headers.map(function (h) {
const key = FIELD_BY_HEADER[h.trim()];
const value = key ? data[key] : undefined;
if (key === 'mobile' && value) return "'" + value;
return value == null ? '' : value;
}));
return ContentService.createTextOutput(JSON.stringify({ ok: true }))
.setMimeType(ContentService.MimeType.JSON);
}FAQ
Google Sheets questions
Does it copy leads that already exist?
Yes. Backfill existing leads sends every current lead to the sheet in the background; after that, rows arrive as events happen.
Build the rest of your workflow
Make it your own
Connect Google Sheets to your workspace.
Start with the installation guide, or get help connecting your own accounts.