google.script.run
הוא API אסינכרוני של JavaScript בצד הלקוח, שמאפשר לדפים של שירות HTML לקרוא לפונקציות של Apps Script בצד השרת. בדוגמה הבאה מוצגת הפונקציונליות הבסיסית ביותר של google.script.run
– הפעלת פונקציה בשרת מ-JavaScript בצד הלקוח.
Code.gs
function doGet() { return HtmlService.createHtmlOutputFromFile('Index'); } function doSomething() { Logger.log('I was called!'); }
Index.html
<!DOCTYPE html> <html> <head> <base target="_top"> <script> google.script.run.doSomething(); </script> </head> </html>
אם פורסים את הסקריפט הזה כאפליקציית אינטרנט ונכנסים לכתובת ה-URL שלה, לא רואים כלום, אבל אם בודקים את היומנים, אפשר לראות שהפונקציה של השרת doSomething()
נקראה.
קריאות מצד הלקוח לפונקציות מצד השרת הן אסינכרוניות: אחרי שהדפדפן מבקש מהשרת להפעיל את הפונקציה doSomething()
, הדפדפן ממשיך מיד לשורה הבאה של הקוד בלי להמתין לתגובה. המשמעות היא שקריאות לפונקציות בשרת לא יתבצעו בסדר שאתם מצפים. אם מבצעים שתי קריאות לפונקציה בו-זמנית, אין דרך לדעת איזו פונקציה תפעל קודם. התוצאה עשויה להיות שונה בכל פעם שהדף נטען. במצב הזה, success handlers ו-failure handlers עוזרים לשלוט בזרימת הקוד.
ממשק google.script.run
API מאפשר 10 קריאות בו-זמניות לפונקציות של השרת. אם תבצעו שיחה 11 בזמן ש-10 שיחות עדיין פועלות, הפונקציה של השרת תתעכב עד שאחד מ-10 המקומות יתפנה. בפועל, כמעט ולא צריך להתייחס למגבלה הזו, במיוחד כי רוב הדפדפנים כבר מגבילים את מספר הבקשות המקבילות לאותו שרת למספר נמוך מ-10.
לדוגמה, ב-Firefox המגבלה היא 6. בדומה לכך, רוב הדפדפנים מעכבים בקשות שרת עודפות עד שאחת מהבקשות הקיימות תושלם.
פרמטרים וערכי החזרה
אפשר לקרוא לפונקציית שרת עם פרמטרים מהלקוח. באופן דומה, פונקציה בצד השרת יכולה להחזיר ערך ללקוח כפרמטר שמועבר אל handler של הצלחה.
הפרמטרים והערכים המוחזרים החוקיים הם פרימיטיבים של JavaScript כמו Number
, Boolean
, String
או null
, וגם אובייקטים ומערכים של JavaScript שמורכבים מפרימיטיבים, אובייקטים ומערכים. גם אלמנט form
בתוך הדף הוא פרמטר תקין, אבל הוא חייב להיות הפרמטר היחיד של הפונקציה, והוא לא יכול להיות ערך החזרה. הבקשות ייכשלו אם תנסו להעביר Date
, Function
, רכיב DOM מלבד form
, או סוג אסור אחר, כולל סוגים אסורים בתוך אובייקטים או מערכים. גם אובייקטים שיוצרים הפניות מעגליות ייכשלו, ושדות לא מוגדרים במערכים יהפכו ל-null
.
שימו לב: אובייקט שמועבר לשרת הופך לעותק של המקור. אם פונקציית שרת מקבלת אובייקט ומשנה את המאפיינים שלו, המאפיינים בלקוח לא מושפעים.
גורמים שמטפלים בהצלחה
מכיוון שהקוד בצד הלקוח ממשיך לשורה הבאה בלי לחכות לסיום של קריאה לשרת, withSuccessHandler(function)
מאפשרת לכם לציין פונקציית קריאה חוזרת בצד הלקוח שתפעל כשהשרת יגיב. אם פונקציית השרת מחזירה ערך, ה-API מעביר את הערך לפונקציה החדשה כפרמטר.
בדוגמה הבאה מוצגת התראה בדפדפן כשהשרת מגיב. הערה: דוגמת הקוד הזו דורשת הרשאה כי הפונקציה בצד השרת ניגשת לחשבון Gmail שלכם. הדרך הכי פשוטה לתת הרשאה לסקריפט היא להפעיל את הפונקציה getUnreadEmails()
באופן ידני בעורך הסקריפטים פעם אחת לפני טעינת הדף. לחלופין, כשפורסים את אפליקציית האינטרנט, אפשר לבחור להריץ אותה בתור 'המשתמש שניגש לאפליקציית האינטרנט'. במקרה כזה, תתבקשו לתת הרשאה כשנטען את האפליקציה.
Code.gs
function doGet() { return HtmlService.createHtmlOutputFromFile('Index'); } function getUnreadEmails() { return GmailApp.getInboxUnreadCount(); }
Index.html
<!DOCTYPE html> <html> <head> <base target="_top"> <script> function onSuccess(numUnread) { var div = document.getElementById('output'); div.innerHTML = 'You have ' + numUnread + ' unread messages in your Gmail inbox.'; } google.script.run.withSuccessHandler(onSuccess) .getUnreadEmails(); </script> </head> <body> <div id="output"></div> </body> </html>
רכיבי handler של כשלים
אם השרת לא מגיב או מחזיר שגיאה, אפשר להשתמש ב-withFailureHandler(function)
כדי לציין מטפל בשגיאות במקום מטפל בהצלחה, עם האובייקט Error
(אם יש כזה) שמועבר כארגומנט.
כברירת מחדל, אם לא מציינים handler לטיפול בשגיאות, השגיאות נרשמות ביומן במסוף JavaScript. כדי לשנות את ההתנהגות הזו, צריך להתקשר אל withFailureHandler(null)
או לספק מטפל בכשלים שלא עושה כלום.
התחביר של פונקציות לטיפול בשגיאות כמעט זהה לזה של פונקציות לטיפול בהצלחה, כמו שרואים בדוגמה הזו.
Code.gs
function doGet() { return HtmlService.createHtmlOutputFromFile('Index'); } function getUnreadEmails() { // 'got' instead of 'get' will throw an error. return GmailApp.gotInboxUnreadCount(); }
Index.html
<!DOCTYPE html> <html> <head> <base target="_top"> <script> function onFailure(error) { var div = document.getElementById('output'); div.innerHTML = "ERROR: " + error.message; } google.script.run.withFailureHandler(onFailure) .getUnreadEmails(); </script> </head> <body> <div id="output"></div> </body> </html>
אובייקטים של משתמשים
אפשר להשתמש שוב באותו handler של הצלחה או כישלון לכמה קריאות לשרת על ידי קריאה ל-withUserObject(object)
כדי לציין אובייקט שיועבר ל-handler כפרמטר שני.
ה'אובייקט המשתמש' הזה – לא להתבלבל עם המחלקה User
– מאפשר לכם להגיב להקשר שבו הלקוח יצר קשר עם השרת. אובייקטים של משתמשים לא נשלחים לשרת, ולכן הם יכולים להיות כמעט כל דבר, כולל פונקציות, רכיבי DOM וכו', בלי ההגבלות על פרמטרים וערכי החזרה של קריאות לשרת. עם זאת, אובייקטים של משתמשים לא יכולים להיות אובייקטים שנבנו באמצעות האופרטור new
.
בדוגמה הזו, לחיצה על אחד משני הלחצנים תעדכן את הלחצן הזה עם ערך מהשרת, בלי לשנות את הלחצן השני, למרות ששניהם משתמשים באותו handler של הצלחה. בתוך רכיב ה-onclick
handler, מילת המפתח this
מתייחסת אל button
עצמו.
Code.gs
function doGet() { return HtmlService.createHtmlOutputFromFile('Index'); } function getEmail() { return Session.getActiveUser().getEmail(); }
Index.html
<!DOCTYPE html> <html> <head> <base target="_top"> <script> function updateButton(email, button) { button.value = 'Clicked by ' + email; } </script> </head> <body> <input type="button" value="Not Clicked" onclick="google.script.run .withSuccessHandler(updateButton) .withUserObject(this) .getEmail()" /> <input type="button" value="Not Clicked" onclick="google.script.run .withSuccessHandler(updateButton) .withUserObject(this) .getEmail()" /> </body> </html>
טפסים
אם קוראים לפונקציית שרת עם רכיב form
כפרמטר, הטופס הופך לאובייקט יחיד עם שמות שדות כמפתחות וערכי שדות כערכים. כל הערכים מומרים למחרוזות, חוץ מהתוכן של שדות file-input, שהופך לאובייקטים מסוג Blob
.
בדוגמה הזו מתבצע עיבוד של טופס, כולל שדה להזנת קובץ, בלי לטעון מחדש את הדף. הקובץ מועלה ל-Google Drive ואז כתובת ה-URL של הקובץ מודפסת בדף בצד הלקוח. בתוך הפונקציה onsubmit
handler, מילת המפתח this
מתייחסת לטופס עצמו. שימו לב: כשכל הטפסים בדף נטענים, פעולת השליחה שמוגדרת כברירת מחדל מושבתת על ידי preventFormSubmit
. כך מונעים את ההפניה של הדף לכתובת URL לא מדויקת במקרה של חריגה.
Code.gs
function doGet() { return HtmlService.createHtmlOutputFromFile('Index'); } function processForm(formObject) { var formBlob = formObject.myFile; var driveFile = DriveApp.createFile(formBlob); return driveFile.getUrl(); }
Index.html
<!DOCTYPE html> <html> <head> <base target="_top"> <script> // Prevent forms from submitting. function preventFormSubmit() { var forms = document.querySelectorAll('form'); for (var i = 0; i < forms.length; i++) { forms[i].addEventListener('submit', function(event) { event.preventDefault(); }); } } window.addEventListener('load', preventFormSubmit); function handleFormSubmit(formObject) { google.script.run.withSuccessHandler(updateUrl).processForm(formObject); } function updateUrl(url) { var div = document.getElementById('output'); div.innerHTML = '<a href="' + url + '">Got it!</a>'; } </script> </head> <body> <form id="myForm" onsubmit="handleFormSubmit(this)"> <input name="myFile" type="file" /> <input type="submit" value="Submit" /> </form> <div id="output"></div> </body> </html>
ראנרים של סקריפטים
אפשר לחשוב על google.script.run
ככלי ליצירת 'מפעיל סקריפטים'. אם מוסיפים לסקריפט מפעיל לטיפול בהצלחה, מפעיל לטיפול בכישלון או אובייקט משתמש, לא משנים את המפעיל הקיים, אלא מקבלים מפעיל סקריפטים חדש עם התנהגות חדשה.
אפשר להשתמש בכל שילוב ובכל סדר של withSuccessHandler()
, withFailureHandler()
ו-withUserObject()
. אפשר גם להפעיל כל אחת מהפונקציות לשינוי ב-script runner שכבר הוגדר בו ערך. הערך החדש פשוט מחליף את הערך הקודם.
בדוגמה הזו מוגדרת פונקציית טיפול משותפת בשגיאות לכל שלוש הקריאות לשרת, אבל שתי פונקציות טיפול נפרדות להצלחה:
var myRunner = google.script.run.withFailureHandler(onFailure);
var myRunner1 = myRunner.withSuccessHandler(onSuccess);
var myRunner2 = myRunner.withSuccessHandler(onDifferentSuccess);
myRunner1.doSomething();
myRunner1.doSomethingElse();
myRunner2.doSomething();
פונקציות פרטיות
פונקציות שרת שהשם שלהן מסתיים בקו תחתון נחשבות פרטיות.
אי אפשר לקרוא לפונקציות האלה באמצעות google.script
והשמות שלהן אף פעם לא נשלחים ללקוח. לכן אפשר להשתמש בהם כדי להסתיר פרטי הטמעה שצריך לשמור בסוד בשרת. google.script
גם לא יכול לראות פונקציות בספריות ופונקציות שלא הוגדרו ברמה העליונה של הסקריפט.
בדוגמה הזו, הפונקציה getBankBalance()
זמינה בקוד הלקוח. משתמש שבודק את קוד המקור יכול לגלות את השם שלה גם אם לא קראתם לה. עם זאת, הפונקציות deepSecret_()
ו-obj.objectMethod()
לא נראות בכלל ללקוח.
Code.gs
function doGet() { return HtmlService.createHtmlOutputFromFile('Index'); } function getBankBalance() { var email = Session.getActiveUser().getEmail() return deepSecret_(email); } function deepSecret_(email) { // Do some secret calculations return email + ' has $1,000,000 in the bank.'; } var obj = { objectMethod: function() { // More secret calculations } };
Index.html
<!DOCTYPE html> <html> <head> <base target="_top"> <script> function onSuccess(balance) { var div = document.getElementById('output'); div.innerHTML = balance; } google.script.run.withSuccessHandler(onSuccess) .getBankBalance(); </script> </head> <body> <div id="output">No result yet...</div> </body> </html>
שינוי הגודל של תיבות דו-שיח באפליקציות Google Workspace
אפשר לשנות את הגודל של תיבות דו-שיח מותאמות אישית ב-Google Docs, ב-Sheets או ב-Forms על ידי קריאה לשיטות google.script.host
, setWidth(width)
או setHeight(height)
בקוד בצד הלקוח. (כדי להגדיר את הגודל הראשוני של תיבת דו-שיח, משתמשים בשיטות HtmlOutput
setWidth(width)
ו-setHeight(height)
).
שימו לב: תיבות דו-שיח לא ממוקמות מחדש במרכז החלון הראשי כשמשנים את הגודל שלהן, ואי אפשר לשנות את הגודל של סרגלי צד.
סגירת תיבות דו-שיח וסרגלי צד ב- Google Workspace
אם משתמשים בשירות HTML כדי להציג תיבת דו-שיח או סרגל צד ב-Google Docs, ב-Sheets או ב-Forms, אי אפשר לסגור את הממשק על ידי קריאה ל-window.close()
. במקום זאת, צריך להתקשר למספר google.script.host.close()
.
לדוגמה, ראו את הקטע בנושא הצגת HTML בתור Google Workspace ממשק משתמש.
העברת המיקוד בדפדפן ב- Google Workspace
כדי להעביר את המיקוד בדפדפן של המשתמש מתיבת דו-שיח או מסרגל צד חזרה לעורך של Google Docs, Sheets או Forms, פשוט קוראים למתודה google.script.host.editor.focus()
.
השיטה הזו שימושית במיוחד בשילוב עם השיטות של שירות המסמכים Document.setCursor(position)
ו-Document.setSelection(range)
.