0

When I run the below code manually it works fine, but when running on a trigger it fails. I had a look for this FULL in the Google documentation, and the only context I can see it in is to do with permissions, but I think this already has full permission.

Full error code:

TypeError: Cannot find function getMessages in object FULL.
at getCalendarInvites(Calendar:44)
at removePastInvites(Calendar:11)

Relevant parts of my code

function removePastInvites(threads) {

  var labelName = "Past Events";  
  var days = 5;   
  var count = 0;
  var archivedEmails = []
  var email = "foo@bar.com"
  if (threads == null) {
  var threads = GmailApp.getInboxThreads();  // did this so that I can either call the method directly or pass        
                                             // threads in from a separate method call
  }
  var calendarInvites = getCalendarInvites(threads); // line 11
...
...
...

function getCalendarInvites(threads) {
  var messages, attachments;
  var inviteEmails = [];
  for (thread in threads) {
    messages = threads[thread].getMessages()   // line 44

What I've tried/workaround

I could do something like this

function removePastInvitesNoArgs() {
  var threads = ...
  removePastInvites(threads)
}

function removePastInvites(threads) {

  // original code
}

But I still don't really understand why my original script doesn't work.

Update: I have taken the (for..in) feedback on board, and this had some side-effects, but was not the main cause of the problem.

TheMaster
  • 45,448
  • 6
  • 62
  • 85
Chris A
  • 863
  • 1
  • 10
  • 31
  • Possible duplicate of [Why is using "for...in" with array iteration a bad idea?](https://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-a-bad-idea) – TheMaster Sep 23 '19 at 13:16
  • OK, subbing in `for (var i=0...` seems to work, but why is it only an issue when time-triggered and not when running the script directly? – Chris A Sep 23 '19 at 13:47
  • Also why is it ok when I use the workaround? – Chris A Sep 23 '19 at 13:55
  • 1
    Maybe Google sends extra properties, when opened via time triggers... or you missed/misinterpreted/concluded some other issue as due to time triggers(coincidence?). If you use `for...in`, try logging in `for (thread in threads) {Logger.log(thread).log(threads[thread])`... Usually there would be plenty of objects in inbuilt classes other than documented ones. `for..in` loops over all [enumerable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in) properties regardless of whether they're present in itself or it's prototype. – TheMaster Sep 23 '19 at 14:06
  • If you do use `for...in`, make sure that the key being iterated is the object's ownProperty: usually done as `for (thread in threads) {if(threads.hasOwnProperty(thread)){/*your code*/}` – TheMaster Sep 23 '19 at 14:08
  • Just created a function `testTriggeredArguments(foo)` whose only code is to email me `foo` and I got the following `{year=2019, month=9, day-of-month=23, day-of-week=1, week-of-year=39, hour=14, minute=18, second=59, timezone=UTC, authMode=FULL, triggerUid=1766004}` – Chris A Sep 23 '19 at 14:20
  • Why don't you log the threads to obtain a better understanding about where the problem comes from? – ziganotschka Sep 23 '19 at 14:24
  • @ziganotschka logging only works when running through the console. – Chris A Sep 23 '19 at 14:25
  • 1
    Anyway, I have solved the problem. If you call a method (which has an argument) via a trigger, the argument is populated with certain metadata (see `testTriggeredArguments(foo)` above) so `threads` was not considered `null` hence `GmailApp.getInboxThreads()` was not called so `threads` didn't actually contain threads – Chris A Sep 23 '19 at 14:28
  • 1
    Glad to hear that you solved your problem, but logging actually does work on trigger. If you open the logs from the Apps Script editor interface, you can see fresh logs after every script run on trigger, as you can verify by looking at the timestamp. – ziganotschka Sep 23 '19 at 14:33
  • Consider adding it as a answer. See [answer] – TheMaster Sep 23 '19 at 14:39
  • @TheMaster done, but I can't accept it for 2 days and I can't remove the incorrect "duplicate of" message – Chris A Sep 23 '19 at 14:52
  • 1
    Removed my close vote and upvoted your answer. The comment will however stay as a helpful link for future readers. – TheMaster Sep 23 '19 at 14:53

1 Answers1

0

Cause

On a triggered event, Google passes in certain metadata when calling the function. An example of this metadata is shown below:

{year=2019, month=9, day-of-month=23, day-of-week=1, week-of-year=39, hour=14, minute=18, second=59, timezone=UTC, authMode=FULL, triggerUid=1766004}

If the function that you are calling takes an argument, the metadata is used as the argument of your function.

function testTriggeredArguments(foo) {
  var email = "foo@bar.com"
  var subject = "Triggered Arguments Test"
    GmailApp.sendEmail(email, subject, foo)
}

The email will contain the metadata shown above.

Solution

Don't call functions which take arguments via a trigger.

Chris A
  • 863
  • 1
  • 10
  • 31