एचटीएमएल सेवा: सर्वर के फ़ंक्शन के साथ संपर्क करना

google.script.run एक एसिंक्रोनस है क्लाइंट-साइड JavaScript API, जो एचटीएमएल-सेवा पेजों को सर्वर-साइड को कॉल करने की अनुमति देता है 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>

अगर इस स्क्रिप्ट को वेब ऐप्लिकेशन के तौर पर डिप्लॉय किया जाता है और इसके यूआरएल पर जाया जाता है, तो आपको कुछ भी करते हुए, लेकिन लॉग देखने पर आपको दिखेगा कि सर्वर फ़ंक्शन doSomething() पर कॉल किया गया.

सर्वर-साइड फ़ंक्शन के लिए क्लाइंट-साइड कॉल एसिंक्रोनस होते हैं: जब ब्राउज़र, सर्वर से doSomething() फ़ंक्शन चलाने का अनुरोध करता है, तो ब्राउज़र जवाब का इंतज़ार किए बिना, कोड की अगली लाइन पर तुरंत चला जाता है. इसका मतलब है की वजह से सर्वर फ़ंक्शन कॉल, शायद आपकी उम्मीद के मुताबिक काम न करें. अगर आपको एक साथ दो फ़ंक्शन कॉल करते हैं, तो यह जानने का कोई तरीका नहीं है कि कौन सा फ़ंक्शन पहले चलाएं; हर बार पेज लोड करने पर, नतीजे अलग-अलग हो सकते हैं. ऐसी स्थिति में, सक्सेस हैंडलर और फ़ेल हैंडलर कोड के फ़्लो को कंट्रोल करने में मदद करते हैं.

google.script.run एपीआई, सर्वर फ़ंक्शन को एक साथ 10 कॉल करने की अनुमति देता है. अगर आपने जब 10 चल रहा हो, तब आप 11वां कॉल करते हैं, तो सर्वर फ़ंक्शन 10 स्पॉट में से एक को मुक्त किए जाने तक देरी होगी. आपको शायद ही कभी इस प्रतिबंध के बारे में सोचने पर विचार करते हैं, विशेषकर जब कि ज़्यादातर ब्राउज़र पहले से ही एक ही सर्वर को 10 से कम संख्या पर एक साथ अनुरोधों की संख्या. उदाहरण के लिए, Firefox में यह सीमा छह है. ज़्यादातर ब्राउज़र, सर्वर के ज़्यादा अनुरोधों को तब तक रोकते हैं, जब तक कि कोई मौजूदा अनुरोध पूरा नहीं हो जाता.

पैरामीटर और रिटर्न वैल्यू

क्लाइंट के पैरामीटर के साथ सर्वर फ़ंक्शन को कॉल किया जा सकता है. इसी तरह, सर्वर फ़ंक्शन, क्लाइंट को सक्सेस हैंडलर.

कानूनी पैरामीटर और रिटर्न वैल्यू, Number जैसे JavaScript प्रिमिटिव हैं, Boolean, String या null के साथ-साथ, ऐसे JavaScript ऑब्जेक्ट और अरे प्रिमिटिव, ऑब्जेक्ट, और सरणियों से बने होते हैं. पेज में मौजूद form एलिमेंट पैरामीटर के रूप में भी कानूनी है, लेकिन यह फ़ंक्शन का एकमात्र पैरामीटर होना चाहिए और यह रिटर्न वैल्यू के रूप में कानूनी नहीं है. अनुरोध विफल हो सकता है, यदि आप form या दूसरी तरह के पाबंदी वाले टाइप के अलावा Date, Function, DOM एलिमेंट, इसमें ऑब्जेक्ट या अरे में पाबंदी वाले टाइप शामिल हैं. ऑब्जेक्ट जो बनाते हैं सर्कुलर रेफ़रंस भी काम नहीं करेंगे और अरे के अंदर तय नहीं किए गए फ़ील्ड बन जाएंगे null.

ध्यान दें कि सर्वर को पास किया गया ऑब्जेक्ट, ओरिजनल ऑब्जेक्ट की कॉपी बन जाता है. अगर कोई सर्वर फ़ंक्शन को एक ऑब्जेक्ट मिलता है और वह अपनी प्रॉपर्टी बदल देता है, यानी क्लाइंट पर इसका कोई असर नहीं होगा.

सक्सेस हैंडलर

क्योंकि क्लाइंट-साइड कोड, सर्वर के इंतज़ार किए बिना अगली लाइन पर काम करता है कॉल पूरा करने के लिए, withSuccessHandler(function) आपको यह तय करने की अनुमति देता है कि सर्वर जवाब. अगर सर्वर फ़ंक्शन कोई वैल्यू दिखाता है, तो एपीआई वैल्यू को नए फ़ंक्शन को पैरामीटर के तौर पर चुनें.

यहां दिए गए उदाहरण में, सर्वर के जवाब देने पर ब्राउज़र से जुड़ी सूचना दिखाई गई है. ध्यान दें कि इस कोड सैंपल के लिए अनुमति की ज़रूरत होती है, क्योंकि सर्वर-साइड फ़ंक्शन आपके 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>

फ़ेलियर हैंडलर

अगर सर्वर जवाब नहीं दे पाता है या गड़बड़ी की जानकारी देता है, तो withFailureHandler(function) आपको इसकी मदद से सक्सेस हैंडलर के बजाय फ़ेलियर हैंडलर सेट करने देता है, Error ऑब्जेक्ट (अगर कोई है) को तर्क के तौर पर दिया गया हो.

अगर आपने गड़बड़ी वाले फ़ंक्शन के लिए हैंडलर नहीं चुना है, तो डिफ़ॉल्ट रूप से गड़बड़ियां, 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>

उपयोगकर्ता ऑब्जेक्ट

आप कॉल करके सर्वर withUserObject(object) का इस्तेमाल करें, जिसे हैंडलर को दूसरे पैरामीटर के रूप में पास किया जाएगा. यह “उपयोगकर्ता ऑब्जेक्ट” — यह User क्लास — इससे आपको के संदर्भ में है, जब क्लाइंट ने सर्वर से संपर्क किया. क्योंकि यूज़र ऑब्जेक्ट सर्वर को भेजा जाता है, तो इनमें लगभग सभी चीज़ें शामिल हो सकती हैं, जिनमें फ़ंक्शन, DOM शामिल हैं एलिमेंट, और इसी तरह की अन्य वैल्यू, पैरामीटर और रिटर्न वैल्यू पर लगी पाबंदियों के बिना का इस्तेमाल किया जा सकता है. हालांकि, उपयोगकर्ता ऑब्जेक्ट ऐसे नहीं हो सकते हैं जो new ऑपरेटर.

इस उदाहरण में, दोनों में से किसी भी बटन पर क्लिक करने से वह बटन मान को सर्वर से बदलें, जबकि अन्य बटन में कोई परिवर्तन न हो, भले ही वे एक सक्सेस हैंडलर शेयर किया जाता है. onclick हैंडलर के अंदर, कीवर्ड 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 एलिमेंट के साथ कॉल किया जाता है, तो फ़ॉर्म एक ऑब्जेक्ट बन जाता है. इसमें फ़ील्ड के नाम, कुंजियों के तौर पर और फ़ील्ड की वैल्यू, वैल्यू के तौर पर इस्तेमाल होती हैं. फ़ाइल-इनपुट फ़ील्ड के कॉन्टेंट को छोड़कर, सभी वैल्यू को स्ट्रिंग में बदल दिया जाता है. फ़ाइल-इनपुट फ़ील्ड के कॉन्टेंट को Blob ऑब्जेक्ट में बदल दिया जाता है.

यह उदाहरण, फिर से लोड किए बिना एक फ़ॉर्म को प्रोसेस करता है, जिसमें फ़ाइल-इनपुट फ़ील्ड भी शामिल है पेज; यह फ़ाइल को Google डिस्क पर अपलोड करता है और फिर फ़ाइल को क्लाइंट-साइड पेज पर रखना चाहिए. onsubmit हैंडलर के अंदर, कीवर्ड this फ़ॉर्म से ही मेल खाता है. ध्यान दें कि पेज में सभी फ़ॉर्म लोड होने पर सबमिट करने की डिफ़ॉल्ट कार्रवाई preventFormSubmit के ज़रिए बंद की गई है. इससे ऐसा होने पर, पेज को ग़लत यूआरएल पर रीडायरेक्ट करने से रोका जा सकता है.

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(). आप किसी भी समय किसी ऐसे स्क्रिप्ट रनर पर फ़ंक्शन में बदलाव करना जिसमें पहले से ही एक वैल्यू सेट हो. नया वैल्यू, पिछली वैल्यू को बदल देती है.

यह उदाहरण सभी तीन सर्वर कॉल के लिए एक सामान्य फ़ेलियर हैंडलर सेट करता है, लेकिन दो अलग-अलग सक्सेस हैंडलर:

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में डायलॉग और साइडबार बंद करना

यदि आप Google Docs, Sheets या Sheets में डायलॉग बॉक्स या साइडबार फ़ॉर्म के लिए, आप window.close() को कॉल करके इंटरफ़ेस बंद नहीं कर सकते. इसके बजाय, आपको google.script.host.close() को कॉल करना होगा. उदाहरण के लिए, एचटीएमएल को Google Workspace यूज़र इंटरफ़ेस के तौर पर दिखाने वाला सेक्शन देखें.

Google Workspaceमें ब्राउज़र फ़ोकस को मूव करना

उपयोगकर्ता के ब्राउज़र में फ़ोकस को डायलॉग या साइडबार से वापस Google Docs, Sheets या Forms एडिटर पर स्विच करने के लिए, google.script.host.editor.focus() कोड को कॉल करें. यह तरीका खास तौर पर इन दोनों के लिए मददगार है दस्तावेज़ सेवा के तरीके Document.setCursor(position) और Document.setSelection(range).