Tired of manually processing invoices? I recently built a demo that automates this tedious task using the power of Gemini, AppSheet’s new Gmail integration, and a custom Apps Script library. Let me show you how it works!
Here’s the setup:
- Gmail Integration: AppSheet’s new Gmail integration allows you to trigger automations based on incoming emails. I’ve set it up to monitor a specific Gmail label called “Invoices”.
- Apps Script Library: Using my “GeminiApp” (available on Github) which simplifies the interaction with Google’s Gemini AI models directly from Apps Script. This library handles the heavy lifting of making API calls and managing responses.
- Controlled Generation: Gemini’s “Controlled Generation” feature lets me define a JSON schema that structures the AI’s output. This is key for extracting invoice data in a consistent, machine-readable format.
The Workflow:
- Invoice Received: When an invoice email arrives and is labelled “Invoices”, AppSheet’s Gmail integration kicks in.
- Automation Triggered: AppSheet triggers an automation that calls a custom Apps Script function called
jsonControlledGeneration
. - Data Extraction: The
jsonControlledGeneration
function uses the GeminiApp library to send the email body to Gemini with a predefined JSON schema for invoice data. - Structured Output: Gemini processes the email content and extracts the relevant invoice details (e.g., invoice number, supplier name, date, amount) in a JSON format that adheres to the schema.
- Downstream Processing: The structured JSON output can then be easily returned to the AppSheet automation for further actions, such as automatically populating your data table, updating a database, or triggering a payment process.
If you would like to try this yourself, instructions are provided below.
Want to try it yourself?
To set this demo up you will either need a Google AI Studio API key or a Google Cloud project with Vertex AI enabled. Information on both these setups is included in the GeminiApp Setup Instructions. Once you have these you can follow these steps:
- Open the GeminiApp Controlled Generation Google Apps Script project and click ‘Make a copy’ from the Overview page
- Open the Invoice Tracker template and click ‘Copy and Customize’, then click OK on the Error Creating App: Apps Script function is invalid error
- Navigate to appsheet.com and from your ‘recent’ apps open the ‘Invoice Tracker’ app
- Open Automations and for the ‘New Invoices’ event under the Gmail Event Source, click Authorize, then
- In the ‘Add a new data source’ enter a name e.g. Invoices Trigger, click the Gmail button and follow the authentication steps
- Once complete in the AppSheet Automation settings select your Gmail account and a Label to watch
- In the Process section click on the GeminiApp task and click on the blue file icon, then select your copied version of the Apps Script project and click Authorize
- Once Authorize, from the Function Name select
jsonControlledGeneration
To test this app, you can copy and send this example invoice.
![](https://pulse.appsscript.info/files/2025/02/Screenshot-2025-02-16-162113.png)
Step 7: Click on the blue file icon, then select your copied version of the Apps Script project
The Power of Controlled Generation
Controlled Generation is a powerful way for extracting information from unstructured data like emails. By defining a JSON schema, I can specify exactly what information I want Gemini to extract and how it should be structured. This ensures that the output is consistent and reliable, eliminating the need for manual cleanup or post-processing.
Here’s an example of a simple JSON schema for invoice data:
const schema = { "type": "object", "properties": { "Invoice Reference": { "type": "string", "description": "Unique identifier for the invoice" }, "Supplier Name": { "type": "string", "description": "Name of the supplier" }, "Invoice Date": { "type": "string", "description": "Date the invoice was issued", "format": "date" }, "Due Date": { "type": "string", "description": "Date the invoice is due", "format": "date" }, "Invoice Amount": { "type": "number", "description": "Total amount due on the invoice" }, "Notes": { "type": "string", "description": "Additional notes related to the invoice", "nullable": true } }, "required": ["Invoice Reference"] }
Creating JSON Schemas with Gemini
Creating JSON schemas can seem a bit daunting at first, but Gemini can actually help you with that too! If you have sample data in a Google Sheet, you can use the Gemini Side Panel to generate a schema automatically. Just highlight the data and ask Gemini to create a JSON schema for you. You can even provide a description for each property to make your schema more understandable. Below is a prompt you can use in the Gemini Sheet Side Panel to generate a schema for your own data:
I'm using Controlled Generation with the Gemini API as described in the document https://drive.google.com/file/d/1ETKHlEUDQzJ-f2fmAzsuDjcwdt1D7R2y/view?usp=drive_link I need help creating a JSON schema to capture data from a screen. Could you generate a JSON schema suitable for using Controlled Generation with the Gemini API? I want to extract specific information from what's displayed on my screen. Here are my requirements: * **Comprehensive Schema:** The schema should be designed to capture a variety of relevant data points from the screen. * **Detailed Descriptions:** Please include a clear and concise \`description\` for each \`property\` in the schema. This will help me understand the purpose of each field. * **Format Specification:** If any columns contain date or datetime data, please use the \`format\` field to specify the appropriate format (e.g., "date", "date-time"). This is crucial for accurate data parsing. * **Output Example:** Please provide the schema in the following format: ``` const schema = { description: "Description of the data", type: "array", // or "object", depending on the structure items: { // If type is array type: "object", properties: { propertyName: { type: "string", // or other appropriate type description: "Description of the property", format: "date", // or "date-time", if applicable nullable: false, // or true }, // ... more properties }, required: ["propertyName"], // If any properties are required }, properties: { // If type is object propertyName: { type: "string", // or other appropriate type description: "Description of the property", format: "date", // or "date-time", if applicable nullable: false, // or true }, // ... more properties }, required: ["propertyName"], // If any properties are required }; ```
Limitations and future developments
While the beta Gmail integration in AppSheet marks a significant new feature, it’s important to note a current limitation is support for processing email attachments. Currently, the integration focuses on metadata such as sender name, subject, and message body, but the AppSheet team have acknowledged attachment support will be added in the near future.
Looking ahead, at Google Cloud Next 2024 the AppSheet team announced an upcoming “Gemini Extract” feature, currently in private preview. This feature intends to include a native Gemini ‘controlled generation’ feature which would let app creators select the data fields they would like populated from sources including images and text. This should be a more intuitive approach to data extraction, directly integrating Gemini capabilities into AppSheet. The Next video includes a Google URL to sign up to the Gemini Extract feature https://goo.gle/appsheet-previews?r=qr
Summary
The Invoice Tracker example hopefully highlights the opportunity for streamlined solutions with data extraction with AppSheet’s Gmail integration, Gemini, and Apps Script.The GeminiApp library also simplifies the integration of Google’s Gemini AI models into Google Workspace, providing developers with tools to create sophisticated AI-powered applications.
Using the structured JSON output with Controlled Generation can help AppSheet creators by making it easier to ensure you get the data back in a suitable format including the type of data you need, such as dates. With the GeminiApp library, rapid prototyping is achievable, in the ‘Invoice Tracker’ example I was able to get a functional prototype up and running in under 30 minutes.
AppSheet’s Gmail integration, generally available to all AppSheet and Google Workspace Core users, can trigger automations directly from incoming emails without requiring app deployment. Combined with Apps Script functions this opens the door to some powerful opportunities for AppSheet creators. Integrating Gemini-powered AI extraction with AppSheet and Apps Script provides an innovative solution for automating data extraction from emails. By taking advantage of these capabilities, citizen developers can create efficient and user-friendly solutions.
![](https://pulse.appsscript.info/files/2022/06/2022-GDE-Workspace-Profile-Badge.jpg)
Member of Google Developers Experts Program for Google Workspace (Google Apps Script) and interested in supporting Google Workspace Devs.