Use this page if you want the automatic version of the missed-call workflow.

The main workflow is:

Missed call → text → short form → Google Sheet → AI job note → follow-up status

The script below helps with the AI part.

When a new form response lands in your Google Sheet, the script sends the request details to AI and fills in:

AI job note
AI priority
AI next step
Callback script

This is optional.

If you want the fastest setup, use the manual AI version from the newsletter first.

Use this script when you want the AI columns to fill automatically.

What you need

Before you start, you need:

A Google Form
A Google Sheet connected to that form
The team columns added to the Sheet
An AI API key
15–30 minutes to test carefully

Step 1: Set up your form

Create a Google Form called:

Quick Service Request

Use these questions:

What do you need help with?
How urgent is it?
Where is the job?
Best time to call back?
Anything else we should know?

Connect the form responses to a Google Sheet.

Name the Sheet:

Missed Call Leads

Step 2: Add these columns to the Sheet

In the Google Sheet, add these team columns to the right side:

Status
Assigned to
Next follow-up
AI job note
AI priority
AI next step
Callback script
Outcome notes

The script needs these exact four output column names:

AI job note
AI priority
AI next step
Callback script

If you change those column names, you also need to update the script.

Step 3: Get an AI API key

This script example uses the Gemini API.

You can create an API key from Google AI Studio.

Important: free or low-cost AI API plans may have limits and different data-use rules.

Before sending customer details to any AI tool, check the provider’s data settings.

You can reduce privacy risk by sending only what the AI needs.

For example, send this:

Water heater leak, ZIP 28277, wants help today

Not this:

Full name, full address, phone number, private notes

Step 4: Open Apps Script

Open the Google Sheet connected to your form.

Go to:

Extensions → Apps Script

Delete any starter code.

Paste the full script below.

Step 5: Paste this script

/**
 * FieldCue missed-call AI job note script
 *
 * What it does:
 * - Runs when a Google Form response lands in the linked Google Sheet
 * - Reads the submitted row
 * - Sends service, urgency, location, and notes to Gemini
 * - Writes back AI job note, priority, next step, and callback script
 *
 * Before using:
 * - Add these output columns to your Sheet:
 *   AI job note
 *   AI priority
 *   AI next step
 *   Callback script
 *
 * - Add your Gemini API key in Apps Script:
 *   Project Settings -> Script Properties
 *   Property: GEMINI_API_KEY
 *   Value: your API key
 */

const CONFIG = {
  model: "gemini-2.5-flash",

  // Change these if your Google Form question names are different.
  inputHeaders: {
    service: "What do you need help with?",
    urgency: "How urgent is it?",
    location: "Where is the job?",
    notes: "Anything else we should know?"
  },

  // These columns must exist in your Sheet.
  outputHeaders: {
    jobNote: "AI job note",
    priority: "AI priority",
    nextStep: "AI next step",
    callbackScript: "Callback script"
  }
};

/**
 * Main function. Set this up as an installable trigger:
 * Event source: From spreadsheet
 * Event type: On form submit
 */
function onFormSubmit(e) {
  const sheet = e.range.getSheet();
  const rowNumber = e.range.getRow();
  processRow_(sheet, rowNumber);
}

/**
 * Optional test function.
 * Use this after you submit one test form response.
 * It processes the last row in the active Sheet.
 */
function testLastRow() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const rowNumber = sheet.getLastRow();
  processRow_(sheet, rowNumber);
}

function processRow_(sheet, rowNumber) {
  const lastColumn = sheet.getLastColumn();
  const headers = sheet.getRange(1, 1, 1, lastColumn).getValues()[0];
  const row = sheet.getRange(rowNumber, 1, 1, lastColumn).getValues()[0];

  const values = {
    service: getValueByHeader_(headers, row, CONFIG.inputHeaders.service),
    urgency: getValueByHeader_(headers, row, CONFIG.inputHeaders.urgency),
    location: getValueByHeader_(headers, row, CONFIG.inputHeaders.location),
    notes: getValueByHeader_(headers, row, CONFIG.inputHeaders.notes)
  };

  const aiResult = createJobNote_(values);

  writeValueByHeader_(sheet, headers, rowNumber, CONFIG.outputHeaders.jobNote, aiResult.job_note);
  writeValueByHeader_(sheet, headers, rowNumber, CONFIG.outputHeaders.priority, aiResult.priority);
  writeValueByHeader_(sheet, headers, rowNumber, CONFIG.outputHeaders.nextStep, aiResult.next_step);
  writeValueByHeader_(sheet, headers, rowNumber, CONFIG.outputHeaders.callbackScript, aiResult.callback_script);
}

function createJobNote_(values) {
  const apiKey = PropertiesService.getScriptProperties().getProperty("GEMINI_API_KEY");

  if (!apiKey) {
    throw new Error("Missing GEMINI_API_KEY in Script Properties.");
  }

  const prompt = `
Read this service request and create a short job note for a home-service business.

Return ONLY valid JSON with these keys:
{
  "job_note": "",
  "priority": "High | Medium | Low",
  "next_step": "",
  "callback_script": ""
}

Rules:
- Keep the job note practical and under 40 words.
- Do not promise pricing or availability.
- If urgency is today or emergency, priority should usually be High.
- Callback script should sound natural and short.
- Do not include full personal details unless they are necessary.

Service: ${values.service || ""}
Urgency: ${values.urgency || ""}
Location: ${values.location || ""}
Notes: ${values.notes || ""}
`;

  const url = `https://generativelanguage.googleapis.com/v1beta/models/${CONFIG.model}:generateContent?key=${apiKey}`;

  const payload = {
    contents: [
      {
        parts: [
          { text: prompt }
        ]
      }
    ],
    generationConfig: {
      temperature: 0.2,
      responseMimeType: "application/json"
    }
  };

  const response = UrlFetchApp.fetch(url, {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  });

  const status = response.getResponseCode();
  const body = response.getContentText();

  if (status < 200 || status >= 300) {
    throw new Error(`Gemini API error ${status}: ${body}`);
  }

  const parsed = JSON.parse(body);
  const text = parsed.candidates &&
    parsed.candidates[0] &&
    parsed.candidates[0].content &&
    parsed.candidates[0].content.parts &&
    parsed.candidates[0].content.parts[0] &&
    parsed.candidates[0].content.parts[0].text;

  if (!text) {
    throw new Error(`No AI text returned: ${body}`);
  }

  return JSON.parse(text);
}

function getValueByHeader_(headers, row, headerName) {
  const index = headers.indexOf(headerName);
  return index === -1 ? "" : row[index];
}

function writeValueByHeader_(sheet, headers, rowNumber, headerName, value) {
  const index = headers.indexOf(headerName);

  if (index === -1) {
    throw new Error(`Missing output column: ${headerName}`);
  }

  sheet.getRange(rowNumber, index + 1).setValue(value || "");
}

Step 6: Add your API key

In Apps Script, go to:

Project Settings → Script Properties

Add a new property:

Property: GEMINI_API_KEY
Value: your Gemini API key

Save it.

Do not paste your API key directly into the Sheet.

Do not share your API key with anyone.

Step 7: Create the trigger

In Apps Script, open:

Triggers

Add a new trigger.

Use these settings:

Function to run: onFormSubmit
Deployment: Head
Event source: From spreadsheet
Event type: On form submit

Save it.

Google may ask you to authorize the script.

Review the permissions before approving.

Step 8: Test it

Submit a test form response.

Use a simple test like:

Service: Repair
Urgency: Today
Location: 28277
Notes: Water heater leaking in garage

Go back to the Sheet.

Check if these columns filled in:

AI job note
AI priority
AI next step
Callback script

If they filled in, the automation is working.

If it does not work

Check these common issues first.

The AI columns are blank

Make sure these columns exist exactly:

AI job note
AI priority
AI next step
Callback script

Column names must match the script.

The script says the API key is missing

Go back to:

Project Settings → Script Properties

Confirm this property exists:

GEMINI_API_KEY

The script cannot find your form fields

Your Google Form question names may be different.

Update this part of the script:

inputHeaders: {
  service: "What do you need help with?",
  urgency: "How urgent is it?",
  location: "Where is the job?",
  notes: "Anything else we should know?"
}

Make the text match your Sheet headers exactly.

The model name fails

The model name may change over time.

In the script, look for:

model: "gemini-2.5-flash"

If needed, replace it with the current Flash model name shown in your AI Studio account.

Privacy reminder

Use the least customer information needed.

For AI job notes, you usually do not need the customer’s full name, full address, or phone number.

A cleaner input is:

Service needed
Urgency
ZIP code
Short notes

That is usually enough to prepare a callback.

Want the simple checklist?

If you want the simple missed-call workflow checklist, reply SETUP to FieldCue Weekly and tell us what phone system, CRM, scheduling tool, or texting tool you use.

Examples:

SETUP — Google Voice
SETUP — Housecall Pro
SETUP — Just my iPhone
SETUP — Not sure

— FieldCue Weekly

Keep reading