Gmail Processor

website·Indexed 31 days ago

https://ahochsteger.github.io/gmail-processor/

A tool for processing Gmail threads, messages, and attachments, featuring capabilities to store attachments to Google Drive, extract text, and decrypt PDFs. It supports a configurable system of global and attachment actions, string and date expressions, regular expressions, and environment placeholders for string substitution.

Tokens
19.5K
Snippets
85
Records
157
Agent score
75%

What's inside Gmail Processor

  1. Overview of Gmail Processor

    Gmail Processor is an open-source Google Apps Script library written in TypeScript that automates the processing of Gmail messages and attachments. It uses a JSON configuration to match threads, messages, and attachments against specific criteria and trigger corresponding actions, such as storing attachments in Google Drive or logging data to Google Spreadsheets.
  2. Understand gmail-processor action processing scopes

    Actions in gmail-processor are triggered within specific processing scopes, which determine the context available to the action:

    • global.*: Globally available; can be placed anywhere in the configuration.
    • thread.*: Runs in the context of a thread (includes message and attachment context).
    • message.*: Runs in the context of a message (includes attachment context).
    • attachment.*: Runs specifically in the context of an attachment.
  3. Identify context types using ContextType

    The ContextType enum identifies the type of context available for processing:

    • attachment: Contains attachment configuration and info about the current attachment.
    • env: Contains environment information and references to environment objects.
    • message: Contains message configuration and info about the current message.
    • proc: Contains processing info (configuration, integration adapters, action registry, and timer).
    • thread: Contains thread configuration and info about the current thread.
  4. Automate Gmail processing and actions

    The Gmail Processor allows you to automate the handling of emails by using a configuration to match specific threads, messages, and attachments, which then triggers defined actions based on those matches.
  5. Use Attachment placeholders during Gmail attachment processing

    The following placeholders are available when the gmail-processor is processing a Gmail attachment. These can be used to access metadata about the file or capture specific parts of the filename and content type using regex match groups defined in the match configuration.
    KeyDescriptionExample
    attachment.contentTypeThe content type of the attachment"application/pdf"
    attachment.contentType.match.1Regex match group 1 from content type"pdf"
    attachment.contentType.match.appTypeNamed regex match group appType from content type"pdf"
    attachment.hashSHA1 content hash of the attachment"aa0b8cc192a5d8d5b5d8ecda24fd096..."
    attachment.index0-based index of the attachment"0"
    attachment.isGoogleTypetrue if the attachment is a Google Workspace file"false"
    attachment.matchedOverall matching result for all conditions in match config"true"
    attachment.nameThe name of the attachment"attachment1.pdf"
    attachment.name.match.1Regex match group 1 from attachment name"1"
    attachment.name.match.attNrNamed regex match group attNr from attachment name"1"
    attachment.sizeThe size of the attachment"18"
    attachmentConfig.index0-based index of the attachment configuration"0"
  6. Set up the gmail-processor development environment

    To start developing for gmail-processor, clone the repository and set up your environment using either Devbox for a consistent toolset or a traditional Node.js installation. Ensure you have Node.js 22+ installed if not using Devbox.
    # 1. Clone the repository
    git clone https://github.com/ahochsteger/gmail-processor.git
    cd gmail-processor
    
    # 2. Setup environment
    # Option A: Using Devbox (Recommended)
    devbox shell
    
    # Option B: Traditional (Ensure Node.js 22+ is installed)
    
    # 3. Install dependencies
    npm run all:reinstall
  7. Extract values from email subjects using Regular Expressions

    You can use named capture groups in a regular expression within the match.subject configuration to extract specific data from an email's subject line. Extracted values are accessible via the message.subject.match object. For example, a capture group defined as (?<school>...) will be available as {{message.subject.match.school}}.
    {
      "messages": [
        {
          "name": "extract-message-fields-from-subject",
          "match": {
            "subject": "regularExpressions (?<school>[^-]+)-(?<reportType>[^-]+)-(?<reportSubType>[^-]+)-(?<date>[0-9-]+)"
          },
          "attachments": [
            {
              "actions": [
                {
                  "name": "attachment.store",
                  "args": {
                    "location": "/Reports/{{message.subject.match.school}}/All Reports/{{message.subject.match.reportType}}/{{message.subject.match.reportSubType}}/{{message.subject.match.date}}-{{attachment.name}}"
                  }
                }
              ]
            }
          ]
        }
      ]
    }
  8. Migrate configuration validation to Zod v4

    As of version 2.17.4, the project has migrated its configuration validation and serialization from class-transformer and ajv to Zod v4. Developers should update any custom configuration schemas or validation logic to use Zod v4 syntax.
    // Example Zod v4 schema usage
    import { z } from 'zod';
    
    const ConfigSchema = z.object({
      apiKey: z.string().min(1),
      timeout: z.number().default(3000),
    });
    
    type Config = z.infer<typeof ConfigSchema>;
  9. Store specific Gmail attachments to Google Drive

    This example demonstrates how to filter for unread threads with attachments containing a specific subject, filter for messages sent by the user, and store attachments named 'invoice.pdf' to a dynamic path in Google Drive using placeholder substitution.
    {
      "description": "Use this to get started with Gmail Processor. It stores an attachment to Google Drive.",
      "settings": {
        "markProcessedMethod": "mark-read"
      },
      "global": {
        "thread": {
          "match": {
            "query": "has:attachment -in:trash -in:drafts -in:spam after:{{date.now|formatDate('yyyy-MM-dd')}} is:unread subject:\"[GmailProcessor-Test] simple\""
          }
        }
      },
      "threads": [
        {
          "match": {
            "query": "from:${user.email}"
          },
          "messages": [
            {
              "attachments": [
                {
                  "match": {
                    "name": "^invoice\\.pdf$"
                  },
                  "actions": [
                    {
                      "name": "attachment.store",
                      "args": {
                        "location": "/GmailProcessor-Tests/e2e/{{date.now|formatDate('yyyy-MM-dd')}}/basics/simple/{{message.subject}}-{{attachment.name}}",
                        "conflictStrategy": "keep"
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  10. Automate Gmail processing with Gmail Processor

    Gmail Processor provides several core capabilities for email automation:

    • Google Drive Integration: Store attachments, PDFs of messages, or entire threads in Google Drive.
    • OCR Text Extraction: Extract text (e.g., invoice numbers) from JPEG, PNG, GIF, and PDF attachments.
    • Spreadsheet Logging: Log information about processed threads, messages, and attachments into a Google Spreadsheet.
    • JSON-based Configuration: Define matching rules and actions via a flexible JSON configuration.
  11. Access extracted attachment text in subsequent actions

    Values extracted by the attachment.extractText action are stored in the attachment.extracted.match object. You can reference these named capture groups using double-curly brace syntax in later actions.
    {
      "name": "attachment.store",
      "args": {
        "location": "/folder/{{attachment.name.match.basename}}-number-{{attachment.extracted.match.invoiceNumber}}.pdf",
        "description": "Invoice number: {{attachment.extracted.match.invoiceNumber}}"
      }
    }