6

On this post, Serge replies: "but you can, of course, use any function from different script files inside a project".

What is the protocol to do that?

I have a function that I want to use in three different scripts. It's pretty dense and I'm continually refining it, so I don't want to copy and paste all the code between functions. The files are all within the same project. Serge's response at this link is the closest I can come to confirm it's possible, but it doesn't give the protocol.

How to make a call from one Google Apps Script to a function in another?

To be more specific, I have a function that deletes a file, grabs a template, copies it, renames it, and fills it out with the current data in a spreadsheet. I want to run that function within several emailing scripts that go out at different times, with different messages, to different people.

Thanks!

UPDATED AFTER MOGSDAD RESPONSE:

I have 5 .gs files, all within the same script project (like the two .gs files you showed in your example. One creates a new file (newFile.gs), the others are intended to email it at various times to various audiences. An example of one of the .gs file would look like this:

function emailNewDoc() {

//Here's where I want to run the script newFile.gs so that the new doc is created before the mail goes out

var message = "Hi,";
message += '<a href='+url+'>Here's the new document</a>' //url is defined in newDoc.gs after the new document is created

var subject = "The updated document"
var recipients = "xyz@xyz.com"

MailApp.sendEmail(recipients, subject, message);

}

As you can see, I don't know what to type on the second line to get the newFile.gs to run as part of emailNewDoc.gs. Sorry to be pedantic. I'm a total novice, but think google scripts is going to change my life forever if I can figure out the basics.

***EDIT AFTER SERGE'S COMMENT

Serge, here's the code in the original .gs file

function newFile() {

var docTemplate = "[insert template doc key here]"; //this one uses the document key, not the file name like mine did
var copy = DocsList.getFileById(docTemplate).makeCopy("my DOCUMENT");
var url = copy.getUrl();
var copyId = copy.getId();
var copyDoc = DocumentApp.openById(copyId);
var body = copyDoc.getActiveSection();
body.replaceText('{date}', Utilities.formatDate(new Date(sheet.getRange('A1').getValues()), SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "MMM dd"));
}

As you can see, I define URL, and that's the variable I want to pull into another function so I can email it out.

Thanks again!

Manikandan C
  • 668
  • 1
  • 9
  • 22
duck
  • 149
  • 1
  • 4
  • 15
  • The name of the .gs file is not important, you just have to use the function name that is in this script file. – Serge insas Dec 06 '13 at 17:06
  • Mogsdad, Serge, thank you both. I can get it to work now. However, what doesn't work is the URL part (see my main question). Is it possible to refer to the variable url that I created in the other function? – duck Dec 06 '13 at 17:16
  • You can add the URL as a return value in your function that is in the other .gs. could you edit your question with that function code? (So that I can write an example) – Serge insas Dec 06 '13 at 17:36
  • Serge, thank you. I updated my question to include the code you requested. – duck Dec 06 '13 at 17:47
  • Yep, sorry, was away for a while... – Serge insas Dec 06 '13 at 18:41

3 Answers3

9

I think I understand the question you are asking. Here is an example project with its functions to set up my explanation:

scriptOne.gs:

  • functionA();
  • functionB();
  • functionC();

scriptTwo.gs:

  • functionD();
  • functionE();
  • functionF();

In scriptOne.gs, I can call functionD() simply by doing this:

functionA() {
  functionD();
}

functionB() {
}

functionC() {
}

I know it seems super elementary, but I use this simple nomenclature to call functions from the other projects. Does that not work for you? If you could provide a clear example of what you are trying to achieve, I could try and give you a better answer.

If you are trying to run ALL of the functions in scriptTwo.gs in one line, then I would create a runScriptTwo() function in scripTwo.gs that calls all of the functions in your scriptTwo.gs file. Then you can call your runScriptTwo() in my first code, instead of calling functionD(). Does that make sense?

cvnntg
  • 334
  • 2
  • 9
  • Thanks cvnntg. Yes, I am very novice, so I just didn't know how to write it out. This works now! – duck Dec 06 '13 at 17:12
  • However, what doesn't work is the URL part (see my main question). For example, in your functionD() let's say you create a new document and define a variable url. Is it possible to then use that variable in function(A), say to send the url in the body of an email? – duck Dec 06 '13 at 17:14
  • Hi. Sorry it has taken me so long to respond. I believe this is possible if you return the URL in functionD(). But you cannot call the same variable from functionD() in functionA() because once the program exits functionD(), that variable will be gone. – cvnntg Dec 30 '13 at 05:49
3

Serge's reply is about script files inside a script project. Script projects can have multiple files. Here's how you create them:

Screenshot

In this example, we have two "gs" files, "Code" and "Utilities":

Screenshot

Any function in the project can invoke the getHtmlTable() function that's in Utilities.gs just by calling it. There's no special protocol required.

The primary other way that you can use functions from other scripts is to create and attach Libraries. Not much to it, once you understand them. Start with the Google Apps Script "Libraries" doc.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
  • Thanks Mogsdad, I updated my question based on your comment. I'm still confused about what code to type in to call the .gs file that is part of the same script file. – duck Dec 06 '13 at 16:40
3

Just another answer to clarify your last point :

Here is your code that calls the other function :

function emailNewDoc() {
var url = newFile();  // this is calling the other function and gets the value you need from it  
var message = "Hi,";
message += '<a href='+url+'>Here's the new document</a>' //url is defined in newDoc.gs after the new document is created

var subject = "The updated document"
var recipients = "xyz@xyz.com"

MailApp.sendEmail(recipients, subject, 'please read html body',{htmlBody : message} );

}

and in the other function (eventually in another .gs file in the same project change the end of your function) :

function newFile() {
  var docTemplate = "[insert template doc key here]"; //this one uses the document key, not   the file name like mine did
  var copy = DocsList.getFileById(docTemplate).makeCopy("my DOCUMENT");
  var url = copy.getUrl();
  var copyId = copy.getId();
  var copyDoc = DocumentApp.openById(copyId);
  var body = copyDoc.getActiveSection();
  body.replaceText('{date}', Utilities.formatDate(new   Date(sheet.getRange('A1').getValues()), SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "MMM dd"));
  return url;// this returns the value you need in the other function
}
Serge insas
  • 45,904
  • 7
  • 105
  • 131
  • Thanks Serge. So all you did was add return url as a final command in the script? I did that...now it lets the function run all the way through (i.e. it sends the email with the link)...but the link that comes in the email is undefined (i.e. when you hover over it it says 'undefined' and there is no http link). To be clear, I define url in newFile, then in my script for emailNewDoc I send the link as 'Here's the new document' – duck Dec 06 '13 at 19:02
  • Arent you actually looking for libraries? Read about them, I think thats what you want. – Zig Mandel Dec 06 '13 at 19:05
  • Thanks Zig. No, I don't think libraries is necessary. I read up on them extensively today. The main problem is solved (I can now run a function that is in a different .gs file). But I want to be able to pull a variable (in this case a URL) that is created as part of the function that is in a different .gs file). – duck Dec 06 '13 at 19:11
  • @user3063164 : I just copied/pasted your code in a test script and it works... I get the link with the url except that it's not formatted as it should... this is plain text, not html so the tag has no effect, I get this : Hi,Here's the new document ALSO, there is a typo in your code in the comment... should be "url" and not "newFile.url" take just the variable name (url) hoping it's clear enough ... – Serge insas Dec 06 '13 at 19:14
  • Still can't get it to work :( To review the basics of what I've got: in the "external" function (newFile) I define url (which is working) and then I put the command return url. Then in the current function I put the command url = newFile() and in the body of the email I put just url (not even href, just url to see what it returns), but I get nothing. – duck Dec 06 '13 at 19:45
  • But here's what I noticed. the url = newFile() command is actually running the newFile function, which deletes the file and thus makes the url obsolete. So I wonder if the fact that the command to get the url -- i.e. url = newFile() -- is actually changing the url is part of the reason why it keeps coming back undefined? – duck Dec 06 '13 at 19:49
  • no offense but what are you talking about ? the code I posted works. the end. nothing gets deleted and the url is valid and (now) properly formatted. – Serge insas Dec 06 '13 at 20:20
  • Hi Serge, thanks for your perseverance and patience. As noted on another post last week, I'm a complete novice to coding, starting last Monday. After a few days away from this problem, I rebuilt my code from scratch starting with the starter code you provided. Although I cannot find the difference between what I've got now and what I had last Friday, the script now works as intended! I can't thank you (and others who posted) enough for the tremendous value you have added. These scripts will save me hours and hours every week as a part of a nonprofit volunteer role. Thank you!!! – duck Dec 09 '13 at 17:54
  • glad to hear that..., good luck if you keep learning Google Apps Script, I can assure you it can really make life easier (even if it causes headaches sometimes ;-) – Serge insas Dec 09 '13 at 18:01