Gmail Processor
repository·main·Indexed 20 days ago
https://github.com/ahochsteger/gmail-processorAn open-source Google Apps Script library for automating Gmail workflows. It uses JSON-based rules to match emails and attachments to trigger actions such as storing files in Google Drive, performing OCR text extraction, decrypting password-protected PDFs, and logging data to Google Spreadsheets.
What's inside gmail-processor
- Gmail Processor is an open-source Google Apps Script library designed to automate the processing of Gmail messages and attachments. It uses a JSON configuration to match specific threads, messages, or attachments against criteria and triggers corresponding actions, such as storing attachments in Google Drive, decrypting PDFs, performing OCR text extraction, or logging data to Google Spreadsheets.
Key Features of Gmail Processor
mainGmail Processor provides the following automation capabilities:
- Extensive Automation: Match threads, messages, and attachments to trigger specific actions.
- Google Drive Integration: Store attachments, message PDFs, or entire threads in Google Drive.
- PDF Decryption: Decrypt and store password-protected PDF attachments.
- OCR Text Extraction: Extract text from images (JPEG, PNG, GIF) and PDFs to organize or annotate attachments.
- Google Spreadsheet Logging: Log information about processed items into a Google Spreadsheet.
- Flexible Configuration: Define rules and actions using a JSON configuration.
- Extensible Architecture: Easily add new actions and integrations.
Pass data between actions using actionMeta
mainYou can pass data from one action to a subsequent action by using the
actionMetaobject within a custom action.- Extract and Store: In your custom action (e.g.,
custom.parseInvoice), extract the required data and assign it to a key inactionMeta. - Access via Placeholder: In the subsequent action (e.g.,
attachment.store), access that data using the placeholder syntax{{message.<keyName>}}.
This allows for dynamic workflows where the output of a parsing or logic step determines the parameters of a storage or notification step.
// Example logic flow: // 1. custom.parseInvoice sets actionMeta.invoiceNumber // 2. attachment.store uses {{message.invoiceNumber}}- Extract and Store: In your custom action (e.g.,
Extract structured JSON from attachments using Gemini AI
mainThe processor supports extracting structured JSON payloads from email text and attachments using the Gemini REST API. This is achieved via the
attachment.extractWithAItrigger. When this action is triggered with an expected response schema, the processor retrieves the structured JSON and stores it in theactionMetamap for subsequent use in the processing pipeline.// Scenario: Extract Structured JSON // WHEN attachment.extractWithAI is triggered with an expected response schema // THEN it must retrieve the structured JSON and store it in the actionMeta map.How Gmail Processor processes and tracks emails
mainGmail Processor uses a hierarchical JSON configuration to match threads, messages, and attachments. Once a match is found, it executes a list of actions (e.g., exporting a thread as a PDF, adding a label, or storing an attachment).
To prevent re-processing the same items, the library supports three methods for tracking processed entities:
Mark processed threads by attaching a label:
- Best for: Simple cases with only one message per thread.
- Pros: Keeps messages in an unread state.
- Cons: Cannot process new messages added to a thread that has already been labeled.
Mark processed messages as read:
- Best for: Most use cases, especially threads with multiple messages.
- Pros: Can process additional messages within the same thread even after the thread has been previously processed.
- Cons: Marks messages as read, which may affect your inbox view.
Custom:
- Best for: Complex edge cases requiring maximum flexibility.
- Pros: Most flexible; allows the user to define their own logic via actions.
- Cons: Requires careful configuration to ensure matching rules and marking actions align, otherwise items may be processed repeatedly.
Planned AI-powered data extraction and categorization
mainThe roadmap includes first-party AI integration designed to transform the processor from a rule-based tool into an intelligent data pipeline.
Key planned features include:
- AI-Powered Data Extraction: New actions like
message.extractWithAIorattachment.extractWithAIthat send content to an LLM (e.g., via Gemini REST API) and inject structured results into the context viaactionMeta. - AI-Based Categorization & Summarization: Using LLMs to classify, tag, or summarize threads/messages. This allows for auto-labeling threads by topic or routing messages based on intent.
Users can currently achieve similar results by implementing custom actions that use Google Apps Script's
UrlFetchAppto call LLM APIs directly.- AI-Powered Data Extraction: New actions like
How actionMeta enables action chaining and data injection
mainThe
actionMetamechanism is a core architectural pattern used to store results from one action so they can be consumed by subsequent actions in a pipeline. This allows for complex workflows, such as extracting data from an attachment and then using that extracted data to construct a filename or a storage path.Currently, this pattern is implemented in
attachment.extractText. Future updates aim to formalize this as a generalized way to inject structured results into the processing context.// Conceptual example of the pattern used in attachment.extractText // Extract data -> use in filename -> store fileNote on Async execution in Google Apps Script (GAS)
mainWhile the library uses
Promise-based handling for certain operations (likestoreDecryptedPdf), users should be aware of Google Apps Script (GAS) constraints when considering asynchronous patterns:- Execution Limit: GAS has a 6-minute execution limit.
- No Background Workers: GAS does not support true background workers.
- Async Support: While GAS V8 supports
async/await, full async migrations for the entire processing pipeline are limited by these environment constraints.
Commit Message Format and Requirements
mainWhen using the Commit Message Skill, the generated output follows a specific structure to ensure compliance with project standards:
- Header:
<type>(<scope>): <description>(constrained to 50-72 characters). - Body: A detailed explanation of the changes (included if necessary).
- Footer: Used for breaking changes or issue references.
- Required Trailers: Every message must include these exact metadata lines:
AI-Assisted: trueAI-Tool: Antigravity
The final message is returned in a fenced code block for easy copying.
feat(attachment): add support for inline image extraction The new extraction logic handles 'multipart/related' messages correctly. AI-Assisted: true AI-Tool: Antigravity- Header:
Strict 100% Test Coverage Enforcement for SpreadsheetConfigProvider
mainTheSpreadsheetConfigProviderimplementation must maintain a strict 100% unit test coverage threshold. This requirement specifically applies to all parsing and conversion branches within the provider code. Any regression in code coverage that drops below 100% must result in a CI (Continuous Integration) failure.Limitations of bidirectional conversion between JSON and Spreadsheets
mainWhen using the bidirectional conversion feature (JSON-to-Sheet or Sheet-to-JSON), be aware of the following constraints:
Nesting Hierarchy Loss
Converting highly complex, deeply nested JSON configurations into a flat row model may cause issues. For example, if you have multiple different message filters under a single thread, or multiple attachment actions per attachment rule, the conversion may result in repeated rows with duplicate thread queries.
Non-Standard Types
Spreadsheet cells only support standard types: strings, numbers, booleans, and JSON strings.
Warning: JavaScript function expressions or custom validation callbacks configured via the API code cannot be serialized into spreadsheet cells and will be lost during conversion.
Use SpreadsheetConfigProvider to configure Gmail Processor via Google Sheets
mainThe
SpreadsheetConfigProviderallows you to define Gmail Processor rules and settings using a Google Sheet instead of writing JSON or YAML. This is designed for non-technical users to provide a low-barrier interface for configuration.Key Features
- Tabular Configuration: Define rules in a flat tabular structure within a spreadsheet.
- Automatic Parsing: The provider parses the flat spreadsheet rows into the hierarchical context structure required by the Gmail Processor.
- Validation: The parsed spreadsheet data is integrated into the existing Zod validation pipeline via
ConfigSchema.parse()to ensure configuration integrity. - Bidirectional Conversion: Supports converting between JSON and Spreadsheet formats (JSON-to-Sheet and Sheet-to-JSON).
Usage
To run the processor using a spreadsheet as the configuration source, use the
runWithSpreadsheetentry point provided by theGmailProcessorclass.// Example entry point usage GmailProcessor.runWithSpreadsheet(spreadsheetId);