0

I'm currently trying to use Martin Hawksey's Google Apps event manager from his blog, but I am running into 2 problems.

#1) The date in the conformation emails is posting the "today's" date & time instead of the event date & time (it's in his original and he never fixed it). Most are saying has to do with this section not being right:

    var variableData = isDate(data[normalizeHeader(templateVars[i])]);
    email = email.replace(templateVars[i], variableData || "");
  }

  return email;
}

// Test if value is a date and if so format 
function isDate(sDate) {
  var scratch = new Date(sDate);
  if (scratch.toString() == "NaN" || scratch.toString() == "Invalid Date") {
    return sDate;
  } 
  else {
    return Utilities.formatDate(new Date(), TZ, "dd MMM yy HH:mm");
  }
}

#2) My other issue is in the template for joining instructions I can't call-to any variables (i.e. ${"Invoice"} or ${"Amount"} :: instead it returns "today's" date <-- I added more cells and added a column for each and they have data in them, and made correct adjustments in the script; still nothing.

ex.

Template: "Your Invoice # is: ${"Invoice"} and your total amount due is: ${"Amount"}"
Reality: "Your Invoice # is: 13 Feb 13 13:18 and your total amount due is: 13 Feb 13 13:18."

Here is my full script and changes I made (not too different from his original): https://gist.github.com/hakarune/4985606

Any and all help would be very much appreciated, the biggest and most important thing is that date though.... Thanks you

j0k
  • 22,600
  • 28
  • 79
  • 90
hakarune
  • 402
  • 2
  • 7
  • 20
  • Cool event manager! I watched the video. Interesting stuff the G script for apps. Didn't knew about. – powtac Feb 19 '13 at 13:31
  • 1
    Yeah, it's amazing, just want it to work 100% before I use it. – hakarune Feb 19 '13 at 13:54
  • That script could use some optimization, reducing the multiple calls to `setValue()` by creating arrays and using `setValues()` instead. See [Best Practices - Google Apps Script](https://developers.google.com/apps-script/best_practices). – Mogsdad Feb 21 '13 at 13:17
  • Sadly my javascript skills are not the greatest and wouldn't really know how to change it arrays without breaking it.. :( – hakarune Feb 21 '13 at 14:40

1 Answers1

4

For problem #1, the comments for the isDate() function say that if the given sDate is a valid date, a formatted version of that date will be returned. But the call to formatDate() passes new Date(), which will be the current date & time. Instead, it should pass new Date(sDate).

return Utilities.formatDate(new Date(sDate), TZ, "dd MMM yy HH:mm");

For problem #2, looks like the problem is again with isDate(). The fillInTemplateFromObject() function is calling isDate() to format the template data if it's a date, expecting it will be left as-is otherwise. The problem is that every number will pass the isDate() check, since the test is simply whether new Date(sDate) will produce a date. See this reference, you'll see that it would end up being treated as new Date(milliseconds). You're getting the current date because of the bug described above... fix that and you'll get a different date, but still a date. Check Detecting an "invalid date" Date instance in JavaScript, it may provide a more conclusive test, if it works in apps-script.

Here's a fix of isDate() for you to try. It includes the fix for problem #1, and pulls in the isValidDate() routine from Detecting an "invalid date" Date instance in JavaScript to more accurately differentiate between dates and numbers.

// From https://stackoverflow.com/questions/1353684
// Returns 'true' if variable d is a date object.
function isValidDate(d) {
  if ( Object.prototype.toString.call(d) !== "[object Date]" )
    return false;
  return !isNaN(d.getTime());
}

// Test if value is a date and if so format
// otherwise, reflect input variable back as-is. 
function isDate(sDate) {
  if (isValidDate(sDate)) {
    sDate = Utilities.formatDate(new Date(sDate), TZ, "dd MMM yy HH:mm");
  }
  return sDate;
}

If you're curious, this is the test code I ran in the debugger. The comments show what was displayed as values in the debugger.

var TZ = "GMT"; // isDate() uses a global variable for TimeZone, let's try GMT

function myFunction() {
  var a = new Date();     // Fri Feb 22 2013 20:48:07 GMT-0500 (EST)
  var b = isDate(a);      // "23 Feb 13 01:48"
  var c = 142312;         // 142312.0
  var d = isDate(c);      // 142312.0
  var e = 'test string';  // "test string"
  var f = isDate(e);      // "test string"
  var g = 'Feb 22, 2013'  // "Feb 22, 2013"
  var h = isDate(g);      // "Feb 22, 2013"
  debugger;
}
Community
  • 1
  • 1
Mogsdad
  • 44,709
  • 21
  • 151
  • 275
  • Thanks, i'll give that a go tomorrow :) – hakarune Feb 21 '13 at 14:40
  • Yep that fixes problem #1 (THANKS A LOT!!!), which is the one that's actually important. As for question #2, it sounds like from what you're saying and the reading, that I would have to recode pretty much everything around 'isDate()' in order to fix it... I don't think that's in my ability, honestly I thought it would have been something simpler like to verify **if** x is a date (req format: **mm/dd/yyyy tt:tt:tt**) then 'Date(sDate)' [and what do that whole thing] **else** not just post the same 'NaN' data from the cell.... – hakarune Feb 23 '13 at 01:15
  • 1
    @hakarune - I've added a code snippet that should do the trick. It really is as simple as you describe. I've tested it in apps-script, and it works. Only variables that are already Date objects will get formatted - that means a string "February 22 2013" would remain a string, whereas the original version would have turned it into a date. Still, I think this should take care of it for you! – Mogsdad Feb 23 '13 at 01:47
  • Thanks for the amazing work dude! Sadly problem #2 now returns the 2 errors: `Unexpected exception upon serializing continuation` && `Apps Script: There was a problem sending to undefined` when trying to use the code. I thought I did it properly.... I replaced: `function isDate(sDate) { var scratch = new Date(sDate); if (scratch.toString() == "NaN" || scratch.toString() == "Invalid Date") { return sDate; } else { return Utilities.formatDate(new Date(), TZ, "dd MMM yy HH:mm"); } }` with your full code above.... or was I supposed to replace `var variableData = isDate(` too? – hakarune Feb 27 '13 at 03:45
  • I've seen `serialization` errors when using the debugger, usually while stepping through code - there's an [issue report for it](http://code.google.com/p/google-apps-script-issues/issues/detail?id=1267), with a request to raise new issues with specific repro scenarios. WRT "Problem Sending", that's an error message from the script. The "undefined" indicates that the magical object creation has a problem, like your data is missing a column heading "email" or "email address". (The script has both of those, did it always?) Sounds like you replaced the right bit. Did you update the gist? – Mogsdad Feb 27 '13 at 04:02
  • To be honest I don't even know what's going on with it now, it works fine for the accept bookings and emails properly and works marvelous, but that error is from "Send Joining Instructions" command. I've searched the Script up and down, and even reverted back to the original script, but I'm continuing to receive that error and don't know why.... My gist hasn't been updated yet, I'll do that now. **EDIT:** Gist is now updated to newest code, and here is my full Docs spreadsheet setup (it was working before, all I've changed was the organization of content and correctly mapped it in the code... – hakarune Feb 27 '13 at 04:53
  • You added new columns to the `EventTMP` sheet (and consequently to each of your events) but also renamed the `email address` column to `email`. That renaming is causing the `undefined` error, because the `rowData` object has no `emailAddress` value. Either change that heading back, or change instances of `rowData.emailAddress` to `rowData.email` in the script. – Mogsdad Feb 27 '13 at 05:21
  • @hakarune: moved to [chat](http://chat.stackoverflow.com/rooms/25196/chat-about-gas-event-manager) – Mogsdad Feb 27 '13 at 05:32
  • Oh I thought it was covered by `var emailAddress = rowData.email;` – hakarune Feb 27 '13 at 05:33