> ## Documentation Index
> Fetch the complete documentation index at: https://docs.duvo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Google Sheets Workflows

> Build Duvo agents that log data to spreadsheets, act on lists as work queues, and enrich rows with external information.

<Info>
  **Time to complete:** 15–25 minutes

  **Difficulty:** Beginner to Intermediate

  **Prerequisites:** Google Sheets connection

  **You'll build:** Agents that log data to spreadsheets, act on lists, and enrich rows with external information
</Info>

***

## Why Automate With Google Sheets?

**The Problem**: Spreadsheets sit at the center of most business workflows, but keeping them up to date is manual work. Teams copy data from emails, forms, and CRM systems into Sheets by hand. Lists in Sheets sit idle when they should be driving outreach or operations. Rows with incomplete data stay incomplete because enrichment requires too many lookups.

**The Solution**: Duvo agents can read from and write to Google Sheets on your behalf — logging data as it arrives, executing operations against every row in a list, and filling in missing information from external sources.

**What you can achieve**:

* Keep a tracking spreadsheet current without manual data entry
* Turn a spreadsheet list into a work queue your agent processes automatically
* Enrich rows with data from external systems so your team works with complete records
* Generate structured reports by pulling from multiple sources and writing results into a formatted sheet
* Audit every action in a log spreadsheet for transparency and review

***

### Before You Start

Make sure you have these ready:

<Check>**Google Sheets connection** — Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Google account</Check>
<Check>**Gmail or Outlook connection** (optional) — if your workflow involves incoming emails</Check>
<Check>**Slack connection** (optional) — for notifications when rows are processed or anomalies are found</Check>
<Check>**CRM connection** (optional) — HubSpot, Salesforce, or Pipedrive for enrichment and logging</Check>

***

### Use Case 1: Building a Live Data Tracker

**Outcome**: A shared spreadsheet stays current automatically. When something happens — an email arrives, a form is submitted, a CRM record changes — a new row appears in your Sheet. No manual copying, no batch imports.

This is the most common Google Sheets pattern in Duvo. Logging into Sheets from any trigger gives your team a single place to track what is happening across systems.

<Steps>
  <Step title="Create the Destination Sheet" icon="table">
    Before building the agent, set up the spreadsheet you want to log into:

    1. Create a new Google Sheet (or use an existing one)
    2. Add column headers in row 1 matching the data you want to capture — for example: `Date`, `From`, `Company`, `Subject`, `Amount`, `Status`
    3. Copy the spreadsheet URL — you will include it in your AOP
  </Step>

  <Step title="Create Your Agent" icon="plus">
    1. Click **"+ Create Agent"** from your dashboard
    2. Select **"Use Agent Builder"**
  </Step>

  <Step title="Paste This AOP" icon="clipboard">
    Adapt this example to your specific data source:

    ```
    Monitor my Gmail inbox for new emails from orders@supplier.com.

    For each email that arrives:
    1. Extract the following fields from the email body:
       - Date received
       - Sender name
       - Sender email address
       - Order number
       - Total amount
       - Delivery date requested

    2. Append a new row to the "Order Log" Google Sheet at [paste your spreadsheet URL].
       Write the values in this column order: Date, Sender Name, Sender Email, Order Number, Amount, Delivery Date, Status.
       Set the Status column to "Received".

    3. If the total amount is over $10,000, send me a Slack message:
       "Large order received: Order #[number] from [sender] for $[amount]"
    ```
  </Step>

  <Step title="Enable the Trigger" icon="zap">
    To log data automatically as emails arrive:

    1. Open your agent settings
    2. Go to **Triggers**
    3. Select **Gmail** as the trigger source
    4. Enter the sender address to filter (for example, `orders@supplier.com`)

    See [Event-Driven Triggers](/user-guide/assignment-features/event-driven-triggers) for full setup details.
  </Step>

  <Step title="Connect Required Connections" icon="plug">
    Under **Connections**, enable:

    * **Gmail** — required for the trigger
    * **Google Sheets** — for logging rows
    * **Slack** — for high-value alerts (optional)
  </Step>
</Steps>

#### Expected Results

* A new row appears in your spreadsheet each time a matching email arrives
* High-value orders trigger an immediate Slack notification
* The Status column is pre-filled, ready for your team to update as the order progresses
* No manual copying required — the spreadsheet becomes a live record

***

### Use Case 2: Driving Bulk Actions from a Spreadsheet List

**Outcome**: A list in your spreadsheet becomes a work queue. Your agent reads each row, takes the appropriate action (sending an email, updating a record, calling an API), and marks the row as processed. You handle exceptions; the routine work runs automatically.

This pattern works for outreach lists, follow-up queues, batch record updates, and any situation where a spreadsheet drives operations.

<Steps>
  <Step title="Prepare Your Spreadsheet" icon="table">
    Set up a sheet with one row per item to process. Add a **Status** column so the agent can track progress:

    | Name      | Email                                       | Company | Message               | Status  |
    | --------- | ------------------------------------------- | ------- | --------------------- | ------- |
    | Alex Chen | [alex@example.com](mailto:alex@example.com) | Acme Co | Follow up on proposal | Pending |
    | Sara Lee  | [sara@example.com](mailto:sara@example.com) | Buildco | Check invoice status  | Pending |

    Leave the Status column as "Pending" for rows that need processing.
  </Step>

  <Step title="Create Your Agent" icon="plus">
    1. Click **"+ Create Agent"** from your dashboard
    2. Select **"Use Agent Builder"**
  </Step>

  <Step title="Paste This AOP" icon="clipboard">
    ```
    Open the "Outreach Queue" Google Sheet at [paste your spreadsheet URL].

    Find all rows where the Status column is "Pending".

    For each Pending row:
    1. Read the Name, Email, Company, and Message columns.
    2. Send a personalized email to the contact:
       - Subject: "Following up — [Company]"
       - Body: Address them by first name, acknowledge their company, and include the content from the Message column. Keep it brief and professional.
    3. After sending, update the Status column for that row to "Sent" and write today's date in the "Date Sent" column.
    4. If sending fails, set Status to "Failed" and note the reason in a "Notes" column.

    After processing all rows, send me a Slack summary:
    "Outreach complete: [X] emails sent, [Y] failed. Review the sheet at [URL] for details."
    ```
  </Step>

  <Step title="Connect Required Connections" icon="plug">
    Under **Connections**, enable:

    * **Google Sheets** — for reading the queue and updating status
    * **Gmail or Outlook** — for sending emails
    * **Slack** — for the completion summary (optional)
  </Step>

  <Step title="Schedule or Trigger" icon="calendar-clock">
    You can run this agent:

    * **On demand** — click **Start Work** when you want to process the queue
    * **On a schedule** — set it to run daily or weekly in **Agent Settings** > **Schedule**
    * **When the sheet changes** — use [Event-Driven Triggers](/user-guide/assignment-features/event-driven-triggers) if your trigger source can notify Duvo on update
  </Step>
</Steps>

#### Expected Results

* All "Pending" rows are processed in sequence
* Each row is marked "Sent" or "Failed" immediately after the action is taken
* You receive a Slack summary with the final counts
* Rows that fail are clearly marked so you can investigate and retry
* The sheet doubles as an audit trail — every action is timestamped

***

### Use Case 3: Enriching and Cleaning Spreadsheet Data

**Outcome**: Rows with incomplete or raw data are updated in place with information pulled from external sources. What took hours of manual lookup — filling in company sizes, verifying addresses, resolving duplicate entries — runs automatically.

This pattern works for lead enrichment, data validation, deduplication, and standardizing fields imported from other systems.

<Steps>
  <Step title="Identify What Needs Enriching" icon="search">
    Decide which columns are missing data or need cleanup. Common examples:

    * A list of email addresses that needs company name, industry, and headcount added
    * A list of addresses that needs to be standardized and geocoded
    * A product list that needs current pricing pulled from a supplier portal
    * A contact list with duplicate rows that need to be merged
  </Step>

  <Step title="Create Your Agent" icon="plus">
    1. Click **"+ Create Agent"** from your dashboard
    2. Select **"Use Agent Builder"**
  </Step>

  <Step title="Paste This AOP" icon="clipboard">
    Adapt this example to your enrichment task:

    ```
    Open the "Leads" Google Sheet at [paste your spreadsheet URL].

    Find all rows where the "Company Size" column is blank.

    For each row:
    1. Read the "Company Domain" column.
    2. Use the web browser to find the company's LinkedIn page or website. Look for:
       - Company size (number of employees)
       - Industry
       - Headquarters location
    3. Write the values you find into the "Company Size", "Industry", and "HQ Location" columns for that row.
    4. If you cannot find a value with confidence, write "Not found" rather than leaving the cell blank.

    After finishing, count how many rows were successfully enriched and how many returned "Not found". Send me a Slack message with the summary.
    ```
  </Step>

  <Step title="Connect Required Connections" icon="plug">
    Under **Connections**, enable:

    * **Google Sheets** — for reading and updating rows
    * **Browser** — for looking up information on external sites
    * **Slack** — for the completion summary (optional)

    For enrichment from specific systems, also enable:

    * **HubSpot or Salesforce** — if enriching from your CRM
    * **Exa** — for company and contact research via AI-powered web search
  </Step>
</Steps>

#### Expected Results

* Blank fields are filled in automatically for each row
* "Not found" is written where data genuinely does not exist, so gaps are visible rather than hidden
* You receive a summary telling you how complete the enrichment was
* The sheet is ready for segmentation, outreach, or import into another system

***

### Tips for Better Results

**Reference the spreadsheet by URL, not by name**: When writing your AOP, paste the full Google Sheets URL rather than the spreadsheet name. This removes ambiguity if multiple sheets share a similar name and makes it easy to update the target later.

**Use a Status column for any queue-based workflow**: Marking rows as "Pending", "In Progress", "Done", or "Failed" lets your agent resume safely if interrupted. It also gives your team an at-a-glance view of queue health.

**Keep headers in row 1 and data starting in row 2**: Agents expect standard spreadsheet layout. If your sheet has merged headers, grouped columns, or data starting in a different row, include that detail in your AOP.

**Process in batches for large sheets**: If you have thousands of rows, tell the agent to process a fixed number per Run (for example, "process the first 100 Pending rows"). This keeps each Run fast and lets you monitor quality as you go.

**Convert .xlsx files before connecting**: If you uploaded an Excel file to Google Drive, convert it to a native Google Sheet first. Go to **File** > **Save as Google Sheets**. Some Google Sheets operations are not supported on imported `.xlsx` files — see the [Google Sheets connection page](/user-guide/connections/available-connections/google-sheets#troubleshooting) for details.

**Add Human-in-the-Loop for sends and updates**: For any workflow that sends emails or modifies records in an external system, consider adding an approval step before the action is taken. See [Human-in-the-Loop](/user-guide/assignment-features/human-in-the-loop).

***

### Troubleshooting

<AccordionGroup>
  <Accordion title="Agent cannot find the spreadsheet" icon="file-x">
    * Confirm the Google Sheets connection is authorized on the [Connections page](https://app.duvo.ai/integrations)
    * Make sure the Google account you authorized has access to the spreadsheet
    * Paste the full spreadsheet URL directly into your AOP rather than using the file name
  </Accordion>

  <Accordion title="Rows are being duplicated" icon="copy">
    * Add a deduplication check to your AOP: "Before appending, check whether a row with the same \[Order Number / Email / ID] already exists. If it does, skip it."
    * Add a unique identifier column (such as Order Number or Email) and use it as the key for deduplication
  </Accordion>

  <Accordion title="Status column is not being updated after processing" icon="circle-x">
    * Check whether the column header in your AOP exactly matches the header in the sheet — spelling and capitalization must match
    * If the sheet has multiple tabs, specify the tab name in your AOP: "Update the Status column in the 'Queue' tab"
  </Accordion>

  <Accordion title="Data appears in the wrong columns" icon="columns-3">
    * Review the column order in your AOP and compare it to the actual headers in your sheet
    * If columns have been added or reordered since the agent was built, update the AOP to reflect the current layout
  </Accordion>

  <Accordion title="The agent is processing rows that are already done" icon="list-checks">
    * Confirm the Status filter in your AOP exactly matches the value you set when marking rows done (for example, "Done" vs "Completed" — these are different)
    * If rows were marked manually and formatting differs (extra spaces, different capitalization), standardize the values in the sheet
  </Accordion>

  <Accordion title="Enrichment quality is low or inconsistent" icon="search-x">
    * Provide more specific instructions in your AOP about where to find information — for example, "Look for the employee count on the company's LinkedIn About page"
    * Upload a reference document via [Files](/user-guide/assignment-features/files) listing the sources your agent should prefer
    * Use the [Learning Feature](/user-guide/assignment-features/learning-feature) to correct outputs and improve accuracy over time
  </Accordion>
</AccordionGroup>

***

### Related Resources

<CardGroup cols={2}>
  <Card title="Google Sheets Connection" icon="table" href="/user-guide/connections/available-connections/google-sheets">
    Connect and authorize Google Sheets
  </Card>

  <Card title="Event-Driven Triggers" icon="zap" href="/user-guide/assignment-features/event-driven-triggers">
    Start Runs automatically on a trigger
  </Card>

  <Card title="Human-in-the-Loop" icon="user-check" href="/user-guide/assignment-features/human-in-the-loop">
    Add approval steps before sends and updates
  </Card>

  <Card title="Files" icon="file" href="/user-guide/assignment-features/files">
    Upload reference documents
  </Card>

  <Card title="Learning Feature" icon="graduation-cap" href="/user-guide/assignment-features/learning-feature">
    Improve accuracy over time
  </Card>

  <Card title="Gmail Workflows" icon="mail" href="/user-guide/examples/gmail-workflows">
    Triage inboxes and extract email data
  </Card>

  <Card title="Weekly Sales Report" icon="chart-column" href="/user-guide/examples/weekly-sales-report">
    Generate structured reports automatically
  </Card>
</CardGroup>
