ahochsteger / gmail-processor

Gmail Processor is an open-source project that automates the processing of Gmail messages and attachments using Google Apps Script and execute actions (e.g. store attachments in a GDrive folder, log information in a spreadsheet) depending on matching criteria.
http://ahochsteger.github.io/gmail-processor/
Apache License 2.0
487 stars 135 forks source link

Action attachment.store fails with TypeError #329

Closed db82407 closed 6 months ago

db82407 commented 7 months ago

Describe the bug

The attachment.store action fails with TypeError: Cannot read properties of undefined (reading 'object') at store (GmailProcessorLib:300:84)\n at descriptor.value (GmailProcessorLib:4673:35)

To Reproduce

Steps to reproduce the behavior:

Config: (note this expects email to have dmarc label):

var config = {
  description: "Store DMARC attachments",
  settings: {
    markProcessedMethod: "mark-read",
    maxBatchSize: 10,
    maxRuntime: 280,
    sleepTimeThreads: 100,
    sleepTimeMessages: 0,
    sleepTimeAttachments: 0
  },
  global: {
    thread: {
      match: {
        query: "has:attachment -in:trash -in:drafts -in:spam newer_than:1d",
        maxMessageCount: -1,
        minMessageCount: 1
      },
      actions: []
    }
  },
  threads: [
    {
      description: "Store all Dmarc attachments sent to root@xxxxxxx.com",
      match: {
        query: "label:dmarc"
      },
      actions: [
        {
          name: "attachment.store",
          args: {
            location: "/Dmarc-reports/${attachment.name}",
            conflictStrategy: "keep"
          }
        }
      ]
    }
  ]

dry-run works ok, but safe-mode fails attempting to store first attachment.

Expected behavior

The attachment should be stored in GDrive, without causing a TypeError.

Logs / Screenshots

4:19:58 PM  Info    [2024-04-01T15:19:58.208Z] INFO: Processing of thread id 18e997504c513f07 (subject:'Report Domain: xxxxxxx.com Submitter: protection.outlook.com Report-ID: f9c8782390e04fb7805c7cfc63fe740a') started ...
4:19:58 PM  Info    [2024-04-01T15:19:58.210Z] INFO: Executing action 'attachment.store' with args: {"location":"/Dmarc-reports/${attachment.name}","conflictStrategy":"keep"}
4:19:58 PM  Info    [2024-04-01T15:19:58.210Z] DEBUG: Calling method 'store' ...
4:19:58 PM  Error   [2024-04-01T15:19:58.212Z] ERROR: Action attachment.store caused an error: TypeError: Cannot read properties of undefined (reading 'object')
4:19:58 PM  Info    [2024-04-01T15:19:58.213Z] INFO: Action result: {"ok":false,"error":{}}
4:19:58 PM  Error   
Error: Error in action 'attachment.store': TypeError: Cannot read properties of undefined (reading 'object')
Processing Trace:
{
  "traces": {
    "thread": {
      "configIndex": 0,
      "index": 0,
      "match": {
        "firstMessageSubject": ".*",
        "labels": ".*",
        "maxMessageCount": -1,
        "minMessageCount": 1,
        "query": "label:dmarc"
      },
      "object": {
        "id": "18e997504c513f07",
        "firstMessageSubject": "Report Domain: xxxxxxx.com Submitter: protection.outlook.com Report-ID: f9c8782390e04fb7805c7cfc63fe740a",
        "lastMessageDate": "2024-04-01T11:39:22.000Z",
        "messageCount": 1,
        "permalink": "https://mail.google.com/mail?extsrc=sync&client=docs&plid=ACUX6DMwbUfS3MMIgU_sKit9dUp5gN2J2jdrf-c"
      }
    }
  },
  "action": {
    "description": "",
    "name": "attachment.store",
    "processingStage": "post-main",
    "args": {
      "location": "/Dmarc-reports/${attachment.name}",
      "conflictStrategy": "keep"
    }
  },
  "data": {
    "timer.startTime": "2024-04-01T15:19:57.667Z",
    "thread.index": 0,
    "threadConfig.index": 0,
    "thread.matched": true
  },
  "error": {
    "message": "Cannot read properties of undefined (reading 'object')",
    "stack": "TypeError: Cannot read properties of undefined (reading 'object')\n    at store (GmailProcessorLib:300:84)\n    at descriptor.value (GmailProcessorLib:4673:35)\n    at ActionRegistry.executeAction (GmailProcessorLib:223:20)\n    at GmailProcessorLib:3932:60\n    at Array.forEach (<anonymous>)\n    at GmailProcessorLib:3929:18\n    at Array.forEach (<anonymous>)\n    at ThreadProcessor.executeActions (GmailProcessorLib:3925:28)\n    at ThreadProcessor.processEntity (GmailProcessorLib:4479:23)\n    at ThreadProcessor.processConfigs (GmailProcessorLib:4461:31)"
  }
}
handleActionResult  @ GmailProcessorLib.gs:3919
(anonymous) @ GmailProcessorLib.gs:3943
(anonymous) @ GmailProcessorLib.gs:3929
executeActions  @ GmailProcessorLib.gs:3925
processEntity   @ GmailProcessorLib.gs:4479
processConfigs  @ GmailProcessorLib.gs:4461
run @ GmailProcessorLib.gs:4100
runWithJson @ GmailProcessorLib.gs:4120

Here's the body of a failed email with attachment:

This is a multi-part message in MIME format.

--_mpm_a4bcd9a515b44b9d8eceb05d7333675fpiotk5m200exchangecorpm_
Content-Type: multipart/related;
    boundary="_rv_a4bcd9a515b44b9d8eceb05d7333675fpiotk5m200exchangecorpm_"

--_rv_a4bcd9a515b44b9d8eceb05d7333675fpiotk5m200exchangecorpm_
Content-Type: multipart/alternative;
    boundary="_av_a4bcd9a515b44b9d8eceb05d7333675fpiotk5m200exchangecorpm_"

--_av_a4bcd9a515b44b9d8eceb05d7333675fpiotk5m200exchangecorpm_

--_av_a4bcd9a515b44b9d8eceb05d7333675fpiotk5m200exchangecorpm_
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: base64

PGRpdiBzdHlsZSA9ImZvbnQtZmFtaWx5OlNlZ29lIFVJOyBmb250LXNpemU6MTRweDsiPlRoaXMgaX
MgYSBETUFSQyBhZ2dyZWdhdGUgcmVwb3J0IGZyb20gTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBGb3Ig
RW1haWxzIHJlY2VpdmVkIGJldHdlZW4gMjAyNC0wMy0zMCAwMDowMDowMCBVVEMgdG8gMjAyNC0wMy
0zMSAwMDowMDowMCBVVEMuPC8gZGl2PjxiciAvPjxiciAvPllvdSdyZSByZWNlaXZpbmcgdGhpcyBl
bWFpbCBiZWNhdXNlIHlvdSBoYXZlIGluY2x1ZGVkIHlvdXIgZW1haWwgYWRkcmVzcyBpbiB0aGUgJ3
J1YScgdGFnIG9mIHlvdXIgRE1BUkMgcmVjb3JkIGluIEROUyBmb3IgdG9ja2lmeS5jb20uIFBsZWFz
ZSByZW1vdmUgeW91ciBlbWFpbCBhZGRyZXNzIGZyb20gdGhlICdydWEnIHRhZyBpZiB5b3UgZG9uJ3
Qgd2FudCB0byByZWNlaXZlIHRoaXMgZW1haWwuPGJyIC8+PGJyIC8+PGRpdiBzdHlsZSA9ImZvbnQt
ZmFtaWx5OlNlZ29lIFVJOyBmb250LXNpemU6MTJweDsgY29sb3I6IzY2NjY2NjsiPlBsZWFzZSBkby
Bub3QgcmVzcG9uZCB0byB0aGlzIGUtbWFpbC4gVGhpcyBtYWlsYm94IGlzIG5vdCBtb25pdG9yZWQg
YW5kIHlvdSB3aWxsIG5vdCByZWNlaXZlIGEgcmVzcG9uc2UuIEZvciBhbnkgZmVlZGJhY2svc3VnZ2
VzdGlvbnMsIGtpbmRseSBtYWlsIHRvIGRtYXJjcmVwb3J0ZmVlZGJhY2tAbWljcm9zb2Z0LmNvbS48
YnIgLz48YnIgLz5NaWNyb3NvZnQgcmVzcGVjdHMgeW91ciBwcml2YWN5LiBSZXZpZXcgb3VyIE9ubG
luZSBTZXJ2aWNlcyA8YSBocmVmID0iaHR0cHM6Ly9wcml2YWN5Lm1pY3Jvc29mdC5jb20vZW4tdXMv
cHJpdmFjeXN0YXRlbWVudCI+UHJpdmFjeSBTdGF0ZW1lbnQ8L2E+LjxiciAvPk9uZSBNaWNyb3NvZn
QgV2F5LCBSZWRtb25kLCBXQSwgVVNBIDk4MDUyLjwvIGRpdiA+

--_av_a4bcd9a515b44b9d8eceb05d7333675fpiotk5m200exchangecorpm_--

--_rv_a4bcd9a515b44b9d8eceb05d7333675fpiotk5m200exchangecorpm_--

--_mpm_a4bcd9a515b44b9d8eceb05d7333675fpiotk5m200exchangecorpm_
Content-Type: application/gzip
Content-Transfer-Encoding: base64
Content-ID: <b2256ee0-bd6c-48cb-9d96-0ebb5c37f48c>
Content-Description: protection.outlook.com!xxxxxxx.com!1711756800!1711843200.xml.gz
Content-Disposition: attachment; filename="protection.outlook.com!xxxxxxx.com!1711756800!1711843200.xml.gz";

H4sIAAAAAAAEAO2dS3PiOBCA71s1/yHFfeQnYKY8nv0Bs7WHveyNErKMBbblkmRI8utXxg9MwkKys8
R26EvArZbVaulT62Ec/8djmjzsqJCMZ98nFjInP4Ivv/kRpeEKk+2DTs7kt0cZfp/ESuXfDGO/36O9
g7hYG7ZpWsbff/z8i8Q0xZNWmV1X/soyqXBG6EQX9/Dg1yYE2gLfaC4OKYLmXKhlShUOscIHoRbrWy
4znNLgz0IlnG8R4alvtNJaS5fEkiBMsSDVfX5PGRFc8khVGSqFWrsuioVBtCDe3LOdhUlNN1rNPXNK
5iQiMyeic9fEvnHUrTNr4+hS4GzdFK5lK7pmuk5zy5pPZ56pq1ZJWgWahYdkz3XsMrm8ru9nvLhhW+
SJJ/ycJ4w8LfNilTAZ06M5XNcsCxQnWxY9VZWtZbUGDrcsDYRvVF8aqcyjg7D8rGV5kPGM+kbeCGQj
ka0oJyqwyiqUX2pZxAMt0H8r+8+aqp1OuGjNFnx/9I7khSB0yfJg6iLbNZHrIdfVpbbyVpXwItMG+E
b1pZXXZdIdTgrtz7BNKV3EZM4lU2VXq6rTlXQVS//kWEqtcXRV7YmoTjn6q1PXl+XqRmwr6LOQZopF
TPf2bo/Y0YTndKl4wLtdu5vwWjsSPA1Wuu6EopM2P9VoM8YUh1RUwhP9bkJj82tDfVyoeCmoLBLVMf
6ld652wsqHNKFEcRE4SoVZXAhVbHRfZxs8t9lmVtg7kcXR83OindyodrJXVtStUF8cG+LEpH8zEKf4
mWeSyqsmFut5tlKRuyYkTfL9xrFt/OjkM76fPUWyWP+6id1+dLTwXNOeMZPolg7SsvG0IYeLN1vR4d
141bqlfovpe5G1nQvI2jdENtJjOyA7XGQVTXMqBBfA7RC5dbyeuIVQO2xuIdQOElkPWbOeJsc9RNqY
q3LtBsRCpB09tov7CbSALQTaz0CsCcgCsoDsWJC9s53jhO0o8Aq8jpZXD00vRVhYy94vsbCWbfIOEd
vetqB6nRijYgvgQqgdJbPlCe2lqTGsZgFZQHZoyDp9PVQBcRagBWjfA62roTVtPTNeIMceHLXVchf2
oADY4QNbPrdd9dePirQLZNmXmHU+a6QFbAHbkcVZZ4q8BdLR9uKDi/3sQUGUvUQD4DokXD8+yt7Z6W
wTZVcUqAVqxxVk33Y+C9NiIBaIHRix93Q0W02LMdAKtI6S1ms/m4UAC8gCsoNC9r4CbCozoBVoHR+t
trlA3hTZtoWsxXxwzxjfbKP4vSFWUqyU7jJMPfEoYap8idMwsH1p2VdtWXnC7pgz00JrnOdSpiq/yk
yT5VZsnPfgf6Sj6lMfeIYyvP1YOEO5RAUEsyEFs48/Q7mv6ScsGIHa0U5BO6eew3seEJAFZAHZ2oI7
fysaIAvIjh3Z+5oXw3sMgdjREmt5Uw2riywXeX3tzPaw/fReZvWtlCRJsVK68Fht6OmDhD1SSwqp0k
eknfyWzVfTMq3pzQCFEeSXR5DzHW3YG9jdMWR4M3UYQ2AM+T8NhDHkhiuHa7/9+2RLBzgFA2KHtW7w
jeb/UAX/ALEgU5GpagAA

--_mpm_a4bcd9a515b44b9d8eceb05d7333675fpiotk5m200exchangecorpm_--

Additional context

Affected version of gmail-processor: 24

The code at GmailProcessorLib:300:84 is:

const file = context.proc.gdriveAdapter.storeAttachment(context.attachment.object, {...

so it looks like context.attachment is undefined.

Add any other context about the problem here.

I attempted to debug this myself, by copying the library code (advanced), but that failed to run with this reference error:

Execution log
4:37:33 PM  Notice  Execution started
4:37:35 PM  Error   
ReferenceError: Drive is not defined
defaultContext  @ GmailProcesorLib.gs:132
run @ GmailProcesorLib.gs:90669
processMail @ Code.gs:42

here's GmailProcesorLib.gs:132

static defaultContext(runMode = Context_1.RunMode.SAFE_MODE) {
        const logger = new Logger_1.Logger();
        const ctx = {
            type: Context_1.ContextType.ENV,
            env: {
                cacheService: CacheService,
                gdriveApp: DriveApp,
                documentApp: DocumentApp,
                driveApi: Drive, // line 132
                gmailApp: GmailApp,
                mailApp: MailApp,
                spreadsheetApp: SpreadsheetApp,
                utilities: Utilities,
                runMode: runMode,
                session: Session,
                timezone: (Session === null || Session === void 0 ? void 0 : Session.getScriptTimeZone()) || "UTC",
                urlFetchApp: UrlFetchApp,
            },
            envMeta: {},
            log: logger,
            meta: {},
        };
        ctx.envMeta = this.buildMetaInfo(ctx);
        ctx.meta = { ...ctx.envMeta };
        return ctx;
    }
ahochsteger commented 6 months ago

@db82407 the issue you are facing is, that you want to execute an attachment action within a thread context where no attachment is defined yet. You have to at least wrap it within an attachments property that takes a list of attachment configs. I recommend to use the Gmail Processor Playground that performs a schema check and shows you that attachment.store is the reason of the problem. Also have a look at the new examples section in the documentation.