How to share functions in google scripts - google-apps-script

Ok. this is simple but I had no success searching in internet.
I want to allow people to use the functions I make in Drive Scripts Editor, so that whoever that wants to use them in their own scripts can.
I want to be clear as I am not a programmer, so here is an example:
I have this script:
function myFunction(a, b) {
return a + b;
}
Then I want other people to just type:
function anothersFunction() {
var x = Titleofproject.myFunction(1, 2);
}
In order to get a 3 for his x (obviously Titleofproject would be much larger).
The idea is to give them the possibility of using it, but not to see the project source code, at least for now.
Thank you!

You can create a Shared Library but note that this is against best practices and the page starts with this:
Warning: A script that uses a library will not run as quickly as it would if all the code were contained within a single script project. Although libraries can make development and maintenance more convenient, you should avoid them in projects where speed is critical. Because of this issue, libraries should not be used in add-ons.

Related

Finding differences in two text files from DriveApp

I'm making a script that copies the contents of a Google Doc into a text file and stores it on Google Drive. The user then edits the document and when they are finished it copies a new version to drive in a separate file. I have this part done, but now I need to know how to make the script automagically compare the differences in the text and then change the color of these differences in the doc. Any ideas?
The only thing I've tried is asking my friend who knows a lot more than me when it comes to programming, haha. He couldn't help me.
function copyQuestions() {
var body = DocumentApp.getActiveDocument().getBody();
var getquestions = body.getText()
DriveApp.createFile('tempquestions.txt', getquestions);
DocumentApp.getUi()
.alert('Questions have been copied to a new file on Google Drive. Get to work, and be sure not to delete the file!')
}
function copyAnswers() {
var body = DocumentApp.getActiveDocument().getBody();
var getanswers = body.getText()
DriveApp.createFile('tempanswers', getanswers);
DocumentApp.getUi()
.alert('Coloring answers...')
}
The script creates files with copies of the document's contents. I need to know how to compare the differences between the two of those now. Thank you!
Sounds like you need a Diff engine. You can attempt to write your own by leveraging well-known algorithms such as Levenshtein Distance or Dice's Coefficient but if you're not so inclined you can try looking for an existing javascript library that's compatible with Apps Script.
Did a quick search and found a few open-source repos. I can't vouch for their compatibility with Apps Script, but at least one of them seems viable (JSDiff supports EcmaScript 3 where Apps Script supports up to EcmaScript 5):
JSDIFF
Source (web-packed) : http://incaseofstairs.com/jsdiff/diff.js
Github : https://github.com/kpdecker/jsdiff
NODE-DELTA
Github : https://github.com/znerol/node-delta

Always include the latest version of custom Google Drive library

I'm trying to link a custom library to a document that will be copied and shared with many people. I want to have all documents link to the latest version of the library, so when I modify the library I don't have to access all the documents to change the link.
This is the scenario:
I created a simple single function library (e.g. library TestLib, function foo()), and saved a first version of it. Then I've created a SpreadSheet with a script that generates a user menu that calls function TestLib.foo(). I've linked version 1 of the library to the script. Now I want to make several copies of the document, one for each people who will need it. The problem is that these documents are linked to version 1 of the library. If I made a change to the library and create a version 2, I have to manually re-link all documents to the new version. That's gonna be lot of work...
Is there a way to have the script to always link to the latest version?
NOTE: the library project is shared in read-only mode (people won't collaborate with the code. They just call foo() from the menu when needed).
Thank!
MIX
I made a new test, trying to overtake the version "limitation" problem.
The idea is a little complicated, but promising. The spreadsheet calls a function in library LinkLib: this library will be saved in a single version and the source code will never modified. The library function simply calls a function on another library (MainLib), whom source code can change over time. Spreadsheet doesn't need to change the version of the linked library (there will never be new version of BaseLib source code), while BaseLib can change the version of MainLib linked if I made changes in MainLib's source code..
The problem is: changing the version of a linked resource is treated as a source code modification. So you need to save a new version of BaseLib to actually use an updated version of MainLib's function.
Hope this mess is somewhat clear...
It makes sense that the described version management behave like this. But damn, I'm still stuck with this problem...
this is possible but with a risk. simply use "development mode" for all documents using the library. whenever you update the library it will include the new code automatically.
the risks are that you will have to be careful to never save an intermediate/partial change as all changes need to not break anything. this can be tricky and is best to have a separate library copy to use when making and testing changes. once tested you may copy all files and "save all" together so the script doesnt have partial saves.
basically you lose the development facilities of using versions.
read more about library development mode in the official docs.

Can I add a .js library? how?

I have some code from gitHub I'd like to run in GAS, but it uses a library (chance.js) I don't know how to install.
I have looked at the documentation here, and tried to follow the steps but I don't have a project key (because nobody's used it in GAS?).
I see that I might be able to call it from my script (?), but I don't even know how to start with that - I am a novice at this.
Is there a simple way to add this library? Can you point me to any resources?
Download the development version of chance.js. Open it and copy the whole text. Then go to your Apps Script editor, create a new script (File/New/Script File) and paste the text into there. Then at the bottom of the chance.js code (but before the closing parenthesis) you need to add chance = new Chance();
btw. In Apps Script every single time you start a function manually or through a trigger, all the js code in all js files belonging to the project is being executed and only afterwards is the selected function run. Of course that doesn't mean that the code inside of all the functions is being run.
edit:
Here is a better approach.
Change the start of chance.js from (function () { to Chance = (function () {. And then change the end from })(); to
return Chance;
})();
chance = new Chance();

How to include a file into your project

I'm creating a Google Apps Script that's kind of a quiz marker / email merger in one. I've got everything working but my code is pretty long because I find myself having to use procedural coding. This is mostly because I don't know how to use the editor to include a class / library.
I've viewed the Crash Course Video by Kalyan on using the Script Editor, but it didn't answer my question. I've also scoured the internet with no luck.
If you look in the top left of this screenshot, you'll see I have Code.gs and test.gs:
I have all my code in the Code.gs file, but I want to include test.gs in Code.gs. Once I figure out how to do that, I'd like to create a couple of simple classes to organize my functions a bit better (and possibly re-use my classes later).
Thanks in advance!
To clarify Zig Mandel's answer and add to it:
All .gs files that are located in the same Script Project have global access to each other. That is to say that a function that you define in test.gs is accessible by Code.gs if they are in the same Script Project
You can create your own library of code. To do this you would simply create another Script Project, then go to Resources -> Manage libraries..., and add the project key of your original project (that contains the Code.gs and test.gs files). The project key is located in File -> Project properties.
The second bullet point is a good way to organize your code. If you have the same code that you are reusing throughout many Script Projects, then you want to put those functions into one Script Project and create a library out of them, as I explained above.
You already included the code. Should work as is. You can also look at the apps script docummentation and learn to use libraries for code reuse:
https://developers.google.com/apps-script/guide_libraries.
This makes development easier but for best performance you should include them all in your project before publishing like you did this time.
Part of the problem may be the order of execution. The .gs files are executed in order of creation. Copying Code.gs, deleting the original, then running functions from the new copy may fix your problem.
<?!= include('JavaScript.html'); ?>
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}

Organizing Spreadsheet Code in several *.gs files - even possible?

I am trying to organize my code for a Spreadsheet in several script files. Within the script editor I can create as many *.gs files as I want, but I can't figure out how to access code that would be defined in another script.
Simple Example of what I'd like do achieve:
Code.gs:
function onEdit(){
myFunctionFromLibrary_gs();
}
Library.gs:
function myFunctionFromLibrary_gs(){
Browser.msgBox("hi there");
}
The onEdit() is obviously called by a Trigger.
Without modification this will result in a Runtime-Error, stating that
myFunctionFromLibrary_gs TypeError: is not a function, it is undefined.
So how can I make this work, or is this currently not supported?
Thx in advance for your help.
Yes, it's possible.
You are not limited to a single server Code.gs file. You can spread server code across multiple files for ease of development. All of the server files are loaded into the same global namespace, so use JavaScript classes when you want to provide safe encapsulation.
Reference: Google Documentation - features and limitations
I don't know what the _gs suffix means for Google, but without it (see code bellow), the code works.
file1.gs:
function onEdit(){
myFunctionFromLibrary();
}
file2.gs
function myFunctionFromLibrary(){
Browser.msgBox("hi there");
}
I know this is an old question but I found it looking for a similar task and happened to find the answer during my same search.
From the docs at https://developers.google.com/apps-script/guide_libraries#writingLibrary:
If you want one or more methods of your script to not be visible (nor usable) to your library users, you can end the name of the method with an underscore. For example, myPrivateMethod_().
While your function does not END in an underscore, it may have special meaning in other places than just this, or the _gs suffix may also have special meaning (particularly given the same filename suffix).