Use a Google doc (spreadsheet) in my script - google-apps-script

I'm new to SO (although not to the SE medium), so though I've searched for an answer (using the site's search function and Google) there's a chance it's been asked and answered before; if so, thanks in advance for flagging as duplicate (provided I can find some assistance in the original, naturally).
I'm trying to compose a script for my personal use that would aggregate and filter RSS feeds. I've got the RSS corner handled (thanks in large part to this Programmer's Library entry), but the point where I'm stuck is that I want to make the filter modular by making it look for phrases contained in a spreadsheet file on my Google Drive. That way, if I ever need to modify/add filtering terms, I could simply edit the file on my Drive instead of going into my script's code.
So, I've been browsing the APIs for classes File, Spreadsheet, SpreadsheetApp, ScriptDb, as well as this Developer's article, but I just can't get my head around it (and I get the feeling I might not be looking in the right place). What I need to do, in the most basic terms, is load (and perhaps save) an array (it could be Object[][] for all I'm concerned) from (to) a spreadsheet file on my Drive. Then I could easily filter by the entries of said array. Another thing I'll be interested in doing is to keep some statistics on how much each term was used as an active filter, which is where saving a modified array back to my Drive would come in handy.
In conclusion, I should mention that I took some Java in collage, but as a math major I was never very accomplished with it; I'm comfortable using examples of similar things and making adjustments to do what I need, but probably not much more than that (although I'm more than willing to learn, if things are explained in a way a non-professional-programmer can understand). I'll appreciate any help you could give me (referring me to the correct place in which to get my answers would be super), but please keep in mind that my head's liable to explode if things get too technical.
Many thanks.

here is an example with your criteria :
function getArrayFromSheet(sheetName) {
var ss = SpreadsheetApp.openById('0AnqSFd3iikE3dF9hb3RUeHBqNUt2NGdkRlUycVZQN0E');// edit this id to suit your spreadsheet
var sh = ss.getSheetByName(sheetName);
var lastRow = sh.getLastRow();
var lastCol = sh.getLastColumn();
var data = sh.getRange(2,1,lastRow,lastCol).getValues();// starting from row nr 2 to skip headers if present (otherwhise start from 1)
// data is an array of arrays [[row1],[row2],[row3],[...]] 0 indexed, each row inside the array is an array of the cell values
return data
}
// usage :
function testFunction(){
var firstRowOfData = getArrayFromSheet('filters')[0];
Logger.log(firstRowOfData)
}
here is a testSpreadsheet to start with (make a copy to run the code)

Related

Writing a script to Clear Data at a specific time, Archive the cleared data and if possible move certain fields to a separate sheet

I have a google form that I am trying to have people answer questions to each day. It is mandatory that this form is completed before they come to the facility. I need a script to clear the data in the Response Tab at midnight each night and I need that data that is being cleared to be archived in a separate sheet if possible. A bonus feature would if as the responses come in each day, the could populate on a separate sheet with 4 fields, "Student ID", "Last Name", "First Name" and "Cleared"
I know I'm asking a lot! The most important thing is the clearing daily and being able to archive the previous day's data (even if it has to be a tab in that file)
To be fair I'm also very new to using scripts if I have to do anything special besides add script I might need some guidance there as well.
Any help anyone could give would be awesome!!!
As Nabnub has already indicated, this is really too much for one question. However, the appointment scheduling system that I made for my tutoring website, (see tutoringbyroger.com), does something quite similar to what you would need, so I will give you some quick pointers below on what worked for me:
You will need to open up the form where the information comes in and go into the script editor from there. Once in there, this function should get you started:
function closeForm(e){
// First we will get the information they entered and parse it
// into an array of strings:
var responsesArray = e.response.getItemResponses();
var txtResponsesArray = [];
var len = responsesArray.length;
for(var i=0; i < len; ++i){
txtResponsesArray[i] = responsesArray[i].getResponse();
}
// We can now do stuff with the strings in txtResponsesArray, like add them to
// a spreadsheet or something.
}
In the script editor you will need to click on triggers, and add a trigger to run the above function when the form is closed. That way, you can capture the data and process it the instant it is submitted.
Create a separate function whose sole purpose is to clear out the information that you would like to clear. This can be from the form or the spreadsheet, or both. It can be in the same script file, just outside of the closeForm() function.
Create another trigger to run the function that does the deleting when you would like that task done.
Anyhow, that is a taste of what you will need to get started. Here are some relevant links to some documentation you might find useful:
How to open a form. (Note: the ID comes from the url of the form when you edit it)
How to open a spreadsheet.
I hope that gives you some idea of where to start.

Getting "We're sorry, a server error occurred. Please wait a bit and try again." But only on one sheet

So I have (what I assume is) a fairly long script to automate giving permissions in Google Sheets. To make it work, I have to first remove all the editors, otherwise Google just puts them in every category. I can't figure out how to stop that, short of removing them completely.
In my test file, I am the owner. Though I assume I need to add something that will add the script runner's account as an editor, just in case they are not. (edited to add: Apparently you can not remove yourself as editor, so even if you are not the owner, you can still run the rest of the script. Thank you, google! EDITED AGAIN: THAT IS A FILTHY LIE. I wish I had linked to the person who said this, because they are WRONG. You can remove yourself, I'm now waiting for the owner to add me back in. 9__6)
So I'm using this:
//removes all Editors
var SpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var editors = SpreadSheet.getEditors();
for (var i = 0; i < editors.length; i++) {
SpreadSheet.removeEditor(editors[i]);
};
Which has been working, in this exact file, every time I test it. Yesterday, however, I got this error:
"We're sorry, a server error occurred. Please wait a bit and try
again."
referencing this line specifically:
var editors = SpreadSheet.getEditors();
But it works in the other test sheets I've made. I'm worried that it is just going to randomly not work when I deploy it on the floor, and I will have no idea why, or how to fix it.
Is there a better way to accomplish this? These sheets are live already, and have been shared with tonnes of people, so I need to either remove their edit permissions or switch their edit type to 'view'.
(I know you can do it for folders, but I would like it specifically for a file, since I am ultimately not the one who owns these files and who knows how they have been organised.)
Thank you for any help!
....
October 23rd, 2016 - It's happening again, on multiple different sheets. I commented everything out, and it is definitely this bit that is causing problems:
//removes all Editors
var SpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var editors = SpreadSheet.getEditors();
for (var i = 0; i < editors.length; i++) {
SpreadSheet.removeEditor(editors[i]);
};
The getEditors is too much, man. Is there another way to do this? Is there another way to remove editors, or set them to 'view only' and then back to 'edit' when I'm done?
(If google would just put only the emails in each protection range as I've defined it instead of everyone, I would not have this problem. But they will not, and I have to remove everyone for this script to work.)
I have already looked at a lot of the linked answers, and they didn't seem to reply. Is getEditors too heavy to use reliably?
I am really not a scripter, and could use any links or guidance anyone could give.
I also can't seem to unaccept my own answer as an answer...
edited 11/14/2016 - Problem persists. The linked answer talks about using the "string replace function", and how changing that made the script work. I am not using that. The rest of my script is a repeat of this type of thing:
//Sheet1
var sh3 = ss.getSheetByName("Sheet1");
var protection = sh3.protect().setDescription('Sheet1 - Wizards'); //protects whole sheet
protection.addEditors(['wizard1#test.com',
'wizard2#test.com',
'wizard3#test.com']);
//adds email addresses to WIZARD range
var unprotected = sh3.getRange('A10:T');
protection.setUnprotectedRanges([sh3.getRange("B3:B3"),
sh3.getRange("C1"),
sh3.getRange("B72:B72"),
sh3.getRange("C2:K8"),
sh3.getRange("A10:T70"),
sh3.getRange("A75:Q")]);
//unprotects everything but frozen header. (unprotects the Sheet1 Legend too.)
var range = sh3.getRange('C2:K8'); //selects the range
var protection = range.protect().setDescription('Sheet1 - Legend'); //names the range
var me = Session.getEffectiveUser();
protection.addEditors(['wizard1#test.com',
'wizard2#test.com',
'wizard3#test.com'
'supervisor1#test.com’]);
//put Sheet1 supervisor emails here
var range = sh3.getRange('C1'); //selects the range
var protection = range.protect().setDescription('Sheet1 - Part Number'); //names the range
var me = Session.getEffectiveUser();
protection.addEditors(['wizard1#test.com',
'wizard2#test.com',
'wizard3#test.com'
'supervisor1#test.com’]);
//put Sheet1 supervisor emails here
var range = sh3.getRange('A10:T38'); //selects the range
var protection = range.protect().setDescription('Sheet1 - worker 1'); //names the range
var me = Session.getEffectiveUser();
protection.addEditors(['wizard1#test.com',
'wizard2#test.com',
'wizard3#test.com',
'lead1#test.com’,
'worker1#test.com',
'worker2#test.com']);
//put emails here - Sheet1 worker level
var range = sh3.getRange('A43:Q'); //selects the range
var protection = range.protect().setDescription('Sheet1 - Artists 2'); //names the range`
var me = Session.getEffectiveUser();
protection.addEditors(['wizard1#test.com',
'wizard2#test.com',
'wizard3#test.com'
'lead1#test.com’
'worker1#test.com',
'worker2#test.com']);
//put emails here - Sheet1 worker level
... Omg the spacing is so off, please ignore that and any commas I might have missed going through. I needed to quickly anonymise this so I can post it. The actual code is spaced right, and does have all the proper commas.
So what am I doing wrong??? Why is google freaking out over the getEditors() bit, and why only in certain sheets??
I saw somewhere else that this is just a catch-all error for "google has no idea wth just happened, but it didn't work. Try again later, and maybe it will work? Fingers crossed????"
Which is frustrating AS HECK because this is not a fancy function at all.
November 29th, 2016: Had a few spare minutes on my hands today, so I thought I'd try this script again. Still didn't work.
But oh my god I think I've cracked it! It's to do with the sharing settings! When the file was originally created, the 'anyone with a link' was selected as the option for sharing.
Well, I thought that didn't give enough security, so I switched my template to 'only specific people'. I then manually removed everyone, thinking maybe this would work.
Ran it again, it worked.
Tried it again, without manually removing, hoping that just changing the sharing settings would work. IT DID!!! So I went to fix the one far down the pipeline that was sitting there with no protections.
Turns OUT that you CAN remove yourself through scripting, even though I had read somewhere that google would not do that. So, since I am not the owner of the sheet, I am now locked out. Which will be another problem, and another question.
But as soon as I get this licked, or get the actual owner to run the script, I will update if this has actually solved it.
I will be so much happier when this works!
Posting an answer because my problem has disappeared? I didn't change anything, but I tried it this morning and it is working. Same sheet, same code, no server error.
This exact same code ran on different copies of this sheet (of which I was also the owner) at the same time as this stupid server error popped up on one, so I really don't know what happened.
I will just pray to the Google Gods and hope that nothing goes wrong. (Best plan, y/y?)
Thank you to Rubén and noogui for their input.
Had the same thing happen to me. Had this Gscript that i couldnt get to run for the life of me. Restarted computer. Signed out of everything. Reuploaded the script. Went to bed. Next morning everything worked fine.
I had a similar problem, but here is what I found ... basically I was linking to a library that was either removed or I lost permissions to. Since I wasn't using this particular library, I removed the library and now all my sheets work again.

New Google Sheets custom functions sometimes display "Loading..." indefinitely

SPECIFIC FOR: "NEW" google sheets only.
This is a known issue as highlighted by google in the new sheets.
Issues: If you write complex* custom functions in google-apps-script for google sheets, you will occasionally run into cells which display a red error box around the cell with the text "Loading..."
Google has suggested:
If this occurs, try reloading the page or renaming the function and changing all references to the new name.
However for other developers experiencing this issue (and who are unable to escape the "loading..." error), I've written my findings in the answer below on how to get past this (with limitations) consistently.
*We're treating this question as the canonical answer for Google Sheet's indefinite "Error... Loading data" problem. It's not limited to complex or slow functions.
Important Tip: Create multiple copies of your entire spreadsheet as you experiment. I have had 3 google spreadsheets corrupted and rendered completely in-accessible (stuck in a refresh loop). This has happened when I was experimenting with custom functions so YOU HAVE BEEN WARNED!
You will want to try one or many of the following ways to fix this issue:
As suggested by google, try re-loading the spreadsheet or re-naming the function or changing the parameters in the cell to see if this fixes the issue.
Surround ALL your custom functions in a try-catch block. This will help detect code issues you may not have tested properly. Eg:
try{
//methods
}catch(ex){
return "Exception:"+ex;
}
Revert to the old sheets and test your functions and check for any other type of error such as an infinite loop or invalid data format. If the function does not work in the old sheets, it will not work in the new sheets and it will be more difficult to debug.
Ensure NONE of your parameters refer to, can expect to or will ever contain a number larger than 1 million (1000000). No idea why but using a number larger than a million as any parameter will cause your function to fail to execute. If you have to, ask the input to be reduced in size (maybe divide by 1000 or ask for M instead of mm).
Check for numeric or floating point issues where numbers may exceed a normal set of significant figures. The new sheets seems to be a little glitchy with numbers so if you are expecting very large or very complex numbers, your functions may not work.
Finally, if none of the above work, switch to the old google sheets and continue working.
If you find any other limitations or causes for functions to fail to execute, please write them below for me and other users who are heavy g-sheet users!
I also had the infinite loading issue with the following function.
// check if an item can be checked off
function checkedOff( need, have ) {
var retStr = "nope";
if( have >= need ){
retStr = "yep";
}
return retStr;
};
Turns out you shouldn't have a trailing ";". Removing the semicolon solved the problem.
// check if an item can be checked off
function checkedOff( need, have ) {
var retStr = "nope";
if( have >= need ){
retStr = "yep";
}
return retStr;
}
This runs as one would expect.
FWIW, I just ran into this and the culprit ended up being a getRange() call that pulled several thousand rows into an array. Periodically it would get hung on the "Loading..." message.
I worked around it by putting that range into the document cache. It's a little kludgy because the cache only stores strings, not arrays, but you can force it back into an array using .split(',') when you need to access the array.
(In my case it's a single array. There's probably a way to do it using a double array, either by sending each row or column into its own cache, or reading the cache value back N items at a time, each N becoming its own array.)
Here's the relevant bit from my code:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("mySheet"); //search the "mySheet" sheet
// is the big list already in the cache?
var cache = CacheService.getDocumentCache();
var cached = cache.get("columnValues");
if (cached != null) {
var columnValues = cached.split(','); // take the cached string and make it an array
} else { // it's not in the cache, so put it there
var column = 1; // the column with your index
var columnValues = sheet.getRange(2, column, sheet.getLastRow()).getValues(); // first row is header
cache.put("columnValues",columnValues,60000); // this forces the array into a string as if you used .join() on it
}
This is definitely a bug in Apps Script -- getRange() shouldn't hang without a timeout or error message. But at least there's a workaround. Here's the bug I opened against it, where I've also put the full code.gs from my sheet.
One cause: Permissions needing authorizing.
As far as {this problem, better phrased the cell result(s) of a custom function displaying the disgustingly-vague message ‘Loading... Error: loading data...’}, indeed in the case where all instances of the same/similar custom function call displaying this error, is that Google Sheets needs permissions to run the script (often additionally: meaning in the past it didn't need these), so instead of {acting appropriately: then prompting the user for these permissions else returning that error}, Sheets instead hangs with this disgustingly vague error.
Additional permissions can be needed from 1 or more:
Google App Scripts has since rewriting their permission structure --how this problem now just happened to me, per my internal note O80U3Z.
Your code or some library it uses made changes to require more access ...but in this case you have a much better chance of guessing the cause of this disgustingly-vague error, so hopefully won't be reading here.
To fix, I explicitly ran my GAS spreadsheet code by both: clicking one of my custom menu functions and, in the ‘script editor’, running one of my custom JS functions notably the ‘onOpen()’ since that is most comprehensive. The first promoted me for indeed new permissions, via popup ‘Authorization RequiredThe application "MM6ZBT(MM6Z83 script)" needs authorization to run.’, though onOpen() also did this in cases of GAS revising its permissions since we used that sheet. Then, as I was still getting this ‘Loading...’ error, I reloaded the web page (so the sheet), and, at least for these cases of this disgustingly vague error, it was gone and the computations worked fine :-)
TL;DR - Try duplicating the sheet tab and delete the old one
I struggled with this issue today, and tried some of the approaches mentioned. For various reasons, renaming the function wasn't possible for me.
It was very clear that if I called a my function like this in cell X25:
=myFunction("a", 1, "b", 2, "c", 3)
The cell would be stuck "Loading...", while just changing a parameter slightly (e.g. converting a number to a string) the cell would evaluate fine.
=myFunction("a", "" & 1, "b", 2, "c", 3)
Just copying the code into another cell (e.g. X24) and executing it there seemed to bypass the problem. As soon as I moved it back to the original parameters or cell, it got stuck "Loading..." again.
So I would assume it's some kind of caching of "Cell ID", function and parameters that go bonkers on Google's side.
My good-enough solution was to simply duplicate the Sheet tab, delete the old one, and finally rename the new one back to the original name. This solved the problem for me.
I also had the "loading data..." error but none of the fixes described here worked for me. It didn't seem to be caused by the issues described here. In my case, I narrowed it down to a specific floating point operation issue (it looks like a real bug in Google Sheets to me), and documented one possible work around at
Google Sheets / Apps "Loading data" error: is there a better workaround?
To summarize (at the request of commenter Steve), if a cell with
= myfunction(B10)
generated a "loading data" error, then for me it could be fixed by wrapping the argument in a "value()" function:
= myfunction(value(B10))
which converts the number in cell B10 (which seemed like a normal number but generated problems somehow) into a normal number that works fine.
I also had the problem that you explained. It seems that it can be caused in more than one way.
I ended up finding that my custom function was displaying that error because it relied on data from an =IMPORTRANGE() call, and that call was failing.
I eventually found that the =IMPORTRANGE() call was failing because I had forgotten to update the URL that it was importing from when I had uploaded a new version of that imported-from sheet. It seems that trying to IMPORTRANGE from a trashed file can cause the infinite "Loading..." error.
Update 2022
It looks like this bug is still happening. I tried ALL the solutions mentioned here but none worked.
What worked was to start with a blank slate. I recreated the file, copy-pasted my data, reapplied my preferred style and format, and lo-and-behold the sheet finally managed to pull the data using my custom functions.
This is a definitely a bug on Google's end - and it's all the more annoying because they removed the "Report a problem" button from the "Help" section.
Nevermind
The newer sheet has stopped working too. This is so annoying ..
The problem is that when a custom function formula cell starts showing Loading..., the custom function does not get called at all. The code in the script project thus does not come into play. Even the simplest custom functions sometimes suffer from the issue.
The problem usually goes away if you clear the formula cell and undo, or slightly edit the custom function's parameters to cause it to get re-evaluated. But that does not solve the issue. Google has been dragging their feet solving the underlying cause for many years.
To help the issue get Google's attention, star issue 233124478 in the issue tracker. Click the star icon ☆ in the top left-hand corner to vote for fixing the issue and get notified of status changes. Please do not post a "me too" or "+1" reply, but just click the star icon. Google prioritizes issues with the most stars.
Add-ons
I had two add-ons, and no function was loading.
I removed them, and all is well!
For me, renaming the custom function solved the problem. For now at least.
Just to add to Azmo 's answer...
I in fact removed all trailing semi-colons from the code:
// check if an item can be checked off
function checkedOff( need, have ) {
var retStr = "nope"
if( have >= need ){
retStr = "yep"
}
return retStr
}
And discovered, that when doing this over a large range you can also max out the acceptable number of calls to the API.
To get around it I added an IF THEN check around my custom script call.
So instead of:
=checkedOff(H10,H11)
Use something like this to check for a populated field before execution:
=if(H17<>"-",checkedOff(H10,H11),0)
My app script pulling data from my MSSQL database displayed just fine on GoogleSheets my laptop browser but then did not display on the Android GS app.
Per this thread it looks like there's a number of issues that could cause this, but #DestinyArchitect's answer above re: Permissions seemed like the simplest fix.
While testing my app script, Sharing was off for this GoogleSheet file.
Once I moved it to my team's folder where we have default Sharing switched on with a few team members, the MSSQL data showed right up on the GoogleSheet in my Android GS app.
Easy fix, this time...
In my case, the cell was stuck with a Loading... message due to "probably" a race condition between functions and formulas resolutions.
This is my custom function:
function ifBlank(value1, value2) {
return !!value1 ? value1 : value2;
}
This is the formula calling it:
=IFBLANK(VLOOKUP($A2,Overrides!$A$2:$E,5,FALSE),VLOOKUP($A2,'_resourceReq'!$A$2:$C,3))
Those VLOOKUP values could be pretty complex and could also take some time to resolve.
Solution: (in my case)
Wrapping the VLOOKUP() into TO_TEXT() or VALUE() for example.
So, changing the formula to =IFBLANK(TO_TEXT(VLOOKUP($A2,Overrides!$A$2:$E,5,FALSE)),TO_TEXT(VLOOKUP($A2,'_resourceReq'!$A$2:$C,3))) worked well.
If that doesn't work maybe try resolving the value from a function into a cell before using it as the argument of your custom function.
In my case, multiple cells using functions experienced this issue, but the simple answer was... wait.
In my case, I was scraping data via importXML functions across multiple rows and
columns. I was thrilled with the results, feeling on top of the world, then "Loading..." started showing its ugly face. For way too long. That's how I wound up here in troubleshooting mode, impatient and upset that Google was doing me wrong.
I tried many of the solutions here, only to find my "Loading..." antagonist acting unpredictably, popping up randomly like whacamoles, nothing to do with the code itself.
So. In my case, it was a matter of waiting it out (towards an hour for some rows, but I had so many cells fetching url data).
My layman's guess is that fetching data like this gets put in their bandwidth pipeline, lesser priority than typing a url into a search bar or other user requests.

Need help parsing through a page & getting all comments found into an Array using a RegEx pattern in Google Apps Script?

My problem lies in 2 parts however I'm hoping solving 1 will fix the other. I've been trying to parse through a page and get all the comments found within a forum thread.
The comments are found using a RegEx pattern and the idea is that whatever lies in the comment will be read into an array until there aren't any more comments left. Each comment div follows this format
<div id="post_message_480683" style="margin-right:2px;"> something </div>
I'm trying to locate up to "post_message_[some number]" since each number seems to be generated randomly and then get whatever is between that particular div. My 1st problem is my RegEx just doesn't seem to be working I've tried a few but none yielded any results (except for when I insert the post message no. in manually), Here's the code so far:
function GetPosts() {
var posts = new Array(60);
var url = "http://forums.blackmesasource.com/showthread.php?p=480683";
var geturl = UrlFetchApp.fetch(url).getContentText().toString();
var post_match = geturl.match(/<div id="post_message_(.+)" style="margin-right:2px;">(\w.+)<\/div>/m);
Logger.log(post_match);
}
Edit: I initially tried getting this info via GAS's Xml.Parse() class but after grabbing the URL I just didn't know what to do since suffixing
.getElement().getElement('div') (I also tried .getElements('div') and other variations with 'body' & 'html')
would cause an error. Here is the last code attempt I tried before trying the RegEx route:
function TestArea() {
var url = "http://forums.blackmesasource.com/showthread.php?p=480683";
var geturl = UrlFetchApp.fetch(url).getContentText().toString();
//after this point things stop making sense
var parseurl = Xml.parse(geturl, true);
Logger.log(geturl);
//None of this makes sense because I don't know HOW!
//The idea: Store each cleaned up Message Div in an Array called posts
//(usually it's no more than 50 per page)
//use a for loop to write each message into a row in GoogleSpreasheet
for (var i = 0; i <= parseurl - 1; i++) {
var display = parseurl[i];
Logger.log(parseurl); }
}
Thanks for reading!
In general like the comment points out - be aware of parsing HTML with RegEx.
In my past personal experience, I've used Yahoo's YQL platform to run the HTML through and using XPath on their service. Seems to work decently well for simple reliable markup. You can then turn that into a JSON or XML REST service that you can grab via UrlFetch and work on that simplified response. No endorsement here, but this might be easier than to bring down the full raw HTML into Google Apps Script. See below for the YQL Console. I also don't know what their quotas are - you should review that.
Of course, the best course is to convince the site owner to provide an RSS feed or an API.

Trigger Google Apps Script by email

I'm looking for examples of a pattern where a demon script running within a GoogleAppsForBusiness domain can parse incoming email messages. Some messages will will contain a call to yet a different GAScript that could, for example, change the ACL setting of a specific document.
I'm assuming someone else has already implemented this pattern but not sure how I go about finding examples.
thx
You can find script examples in the Apps Script user guide and tutorials. You may also search for related discussions on the forum. But I don't think there's one that fits you exactly, all code is out there for sure, but not on a single script.
It's possible that someone wrote such script and never published it. Since it's somewhat straightforward to do and everyone's usage is different. For instance, how do you plan on marking your emails (the ones you've already read, executed, etc)? It may be nice to use a gmail filter to help you out, putting the "command" emails in a label right away, and the script just remove the label (and possibly set another one). Point is, see how it can differ a lot.
Also, I think it's easier if you can keep all functions in the same script project. Possibly just on different files. As calling different scripts is way more complicated.
Anyway, he's how I'd start it:
//set a time-driven trigger to run this function on the desired frequency
function monitorEmails() {
var label = GmailApp.getUserLabelByName('command');
var doneLabel = GmailApp.getUserLabelByName('executed');
var cmds = label.getThreads();
var max = Math.min(cmds.length,5);
for( var i = 0; i < max; ++i ) {
var email = cmds[i].getMessages()[0];
var functionName = email.getBody();
//you may need to do extra parsing here, depending on your usage
var ret = undefined;
try {
ret = this[functionName]();
} catch(err) {
ret = err;
}
//replying the function return value to the email
//this may make sense or not
if( ret !== undefined )
email.reply(ret);
cmds[i].removeLabel(label).addLabel(doneLabel);
}
}
ps: I have not tested this code
You can create a google app that will be triggered by an incoming email message sent to a special address for the app. The message is converted to an HTTP POST which your app receives.
More details here:
https://developers.google.com/appengine/docs/python/mail/receivingmail
I havn't tried this myself yet but will be doing so in the next few days.
There are two ways. First you can use Google pub/sub and handle incomming notifications in your AppScrit endpoint. The second is to use the googleapis npm package inside your AppScript code an example here. Hope it helps.
These are the steps:
made a project on https://console.cloud.google.com/cloudpubsub/topicList?project=testmabs thing?
made a pubsub topic
made a subscription to the webhook url
added that url to the sites i own, i guess? I think I had to do DNS things to confirm i own it, and the error was super vague to figure out that was what i had to do, when trying to add the subscription
added permission to the topic for "gmail-api-push#system.gserviceaccount.com" as publisher (I also added ....apps.googleusercontent.com and youtrackapiuser.caps#gmail.com but i dont think I needed them)
created oauth client info and downloaded it in the credentials section of the google console. (oauthtrash.json)