# Send Leads to Google Sheets

> Add a row to a Google Sheet for every missed call with a short Google Apps Script web app - or ask us to set it up for you.

Source: https://edesy.in/docs/missed-call/guides/send-leads-to-google-sheets

There is no built-in Google Sheets connector. You have three ways to get missed calls into a sheet:

- **Download the CSV** and import it. Free with no webhook set. See [CSV Export](https://edesy.in/docs/missed-call/guides/csv-export).
- **Ask us to set it up**: we connect a sheet for your account on request. Tell us on the [Missed Call Service page](https://edesy.in/missed-call-service).
- **Build it yourself** with Google Apps Script, as below. It takes about 10 minutes.

## 1. Prepare the sheet

Create a Google Sheet with these headers in row 1:

`received_at | from | to | number_name | call_sid`

## 2. Add the script

In the sheet choose **Extensions > Apps Script**, replace the code with this, and save:

```js
function doPost(e) {
  var event = JSON.parse(e.postData.contents);
  if (event.event !== "call.missed") {
    return ContentService.createTextOutput("ignored");
  }

  var d = event.data;
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];

  // Skip retries and replays of an event already written.
  var sids = sheet.getRange("E:E").getValues().flat();
  if (sids.indexOf(d.call_sid) === -1) {
    sheet.appendRow([event.timestamp, d.from, d.to, d.phone_number_name, d.call_sid]);
  }
  return ContentService.createTextOutput("ok");
}
```

## 3. Deploy it as a web app

1. Choose **Deploy > New deployment**, type **Web app**.
2. Execute as **Me**; who has access: **Anyone**.
3. Deploy, authorise, and copy the web app URL (`https://script.google.com/macros/s/.../exec`).

## 4. Point the webhook at it

In [missedcall.edesy.in](https://missedcall.edesy.in) open **Webhook**, paste the web app URL (the one ending in `/exec`) and save. Click **Send test**: it should report delivered. Then give your number a missed call and check that a row appears. Read the limits below before using this for a live campaign.

## Limits of the DIY route

- Apps Script cannot read request headers, so it cannot check `X-Edesy-Signature`. Keep the web app URL private; anyone with it can add rows.
- **Redirects.** An Apps Script web app runs your `doPost` and then answers with a redirect to `script.googleusercontent.com`. Our webhook follows that one redirect, so deliveries show as delivered. Use the `https://script.google.com/macros/s/.../exec` URL itself: a shortened or custom-domain link to it redirects elsewhere first, and that redirect is not followed. The `call_sid` check above keeps retries and replays from adding duplicate rows.
- Want the signature checked too? Put a small relay of your own in front of the sheet (see [Connect Your CRM](https://edesy.in/docs/missed-call/guides/connect-your-crm#option-2-build-it-yourself)) or ask us to set it up.
- Apps Script has daily quotas. For large campaigns, use the CSV export or a proper database.
- `timestamp` is UTC. Format the column in the sheet if you want IST.
