HTML পরিষেবা: সার্ভার ফাংশনের সাথে যোগাযোগ করুন

google.script.run হল একটি অ্যাসিঙ্ক্রোনাস ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্ট API যা HTML-পরিষেবা পৃষ্ঠাগুলিকে সার্ভার-সাইড অ্যাপস স্ক্রিপ্ট ফাংশনগুলিকে কল করার অনুমতি দেয়৷ নিম্নলিখিত উদাহরণটি google.script.run এর সবচেয়ে মৌলিক কার্যকারিতা দেখায় — ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্ট থেকে সার্ভারে একটি ফাংশন কল করা

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() চালায়, ব্রাউজারটি প্রতিক্রিয়ার জন্য অপেক্ষা না করে অবিলম্বে কোডের পরবর্তী লাইনে চলে যায়। এর মানে হল যে সার্ভার ফাংশন কলগুলি আপনার প্রত্যাশা অনুযায়ী কার্যকর নাও হতে পারে। আপনি যদি একই সময়ে দুটি ফাংশন কল করেন তবে কোন ফাংশনটি প্রথমে চলবে তা জানার কোন উপায় নেই; প্রতিবার পৃষ্ঠা লোড করার সময় ফলাফল ভিন্ন হতে পারে। এই পরিস্থিতিতে, সফল হ্যান্ডলার এবং ব্যর্থতা হ্যান্ডলার আপনার কোডের প্রবাহ নিয়ন্ত্রণ করতে সাহায্য করে।

google.script.run API সার্ভার ফাংশনে 10টি সমসাময়িক কলের অনুমতি দেয়। 10টি চালু থাকা অবস্থায় আপনি যদি 11 তম কল করেন, 10টি স্পটগুলির মধ্যে একটি মুক্ত না হওয়া পর্যন্ত সার্ভার ফাংশনটি বিলম্বিত হবে৷ অনুশীলনে, আপনাকে খুব কমই এই সীমাবদ্ধতা সম্পর্কে ভাবতে হবে, বিশেষ করে যেহেতু বেশিরভাগ ব্রাউজার ইতিমধ্যেই একই সার্ভারে 10 এর কম সংখ্যায় সমকালীন অনুরোধের সংখ্যা সীমাবদ্ধ করে। ফায়ারফক্সে, উদাহরণস্বরূপ, সীমাটি 6। বেশিরভাগ ব্রাউজার একইভাবে বিলম্ব করে। বিদ্যমান অনুরোধগুলির একটি সম্পূর্ণ না হওয়া পর্যন্ত অতিরিক্ত সার্ভার অনুরোধ।

পরামিতি এবং রিটার্ন মান

আপনি ক্লায়েন্ট থেকে পরামিতি সহ একটি সার্ভার ফাংশন কল করতে পারেন। একইভাবে, একটি সার্ভার ফাংশন ক্লায়েন্টকে একটি মান ফেরত দিতে পারে একটি সফল হ্যান্ডলারের কাছে পাস করা একটি প্যারামিটার হিসাবে।

আইনি প্যারামিটার এবং রিটার্ন মান হল জাভাস্ক্রিপ্টের আদিম যেমন একটি Number , Boolean , String , বা null , সেইসাথে জাভাস্ক্রিপ্ট অবজেক্ট এবং অ্যারে যা আদিম, বস্তু এবং অ্যারে নিয়ে গঠিত। পৃষ্ঠার মধ্যে একটি form উপাদানও একটি প্যারামিটার হিসাবে আইনী, তবে এটি অবশ্যই ফাংশনের একমাত্র প্যারামিটার হতে হবে এবং এটি ফেরত মান হিসাবে বৈধ নয়৷ আপনি যদি কোনো Date , Function , একটি form ছাড়াও DOM উপাদান পাস করার চেষ্টা করেন বা অবজেক্ট বা অ্যারের মধ্যে নিষিদ্ধ প্রকারগুলি সহ অন্যান্য নিষিদ্ধ টাইপ পাস করার চেষ্টা করেন তাহলে অনুরোধগুলি ব্যর্থ হয়৷ বৃত্তাকার রেফারেন্স তৈরি করে এমন বস্তুগুলিও ব্যর্থ হবে এবং অ্যারেগুলির মধ্যে অনির্ধারিত ক্ষেত্রগুলি 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>

ব্যর্থ হ্যান্ডলার

যদি সার্ভার প্রতিক্রিয়া জানাতে ব্যর্থ হয় বা একটি ত্রুটি ছুড়ে দেয়, 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 ড্রাইভে ফাইল আপলোড করে এবং তারপর ক্লায়েন্ট-সাইড পৃষ্ঠায় ফাইলটির URL প্রিন্ট করে। onsubmit হ্যান্ডলারের ভিতরে, 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() এর যেকোনো সমন্বয় এবং যেকোনো অর্ডার ব্যবহার করতে পারেন। আপনি একটি স্ক্রিপ্ট রানারে যেকোন পরিবর্তন করার ফাংশনকে কল করতে পারেন যার ইতিমধ্যে একটি মান সেট রয়েছে। নতুন মান কেবল আগের মানটিকে ওভাররাইড করে।

এই উদাহরণটি তিনটি সার্ভার কলের জন্য একটি সাধারণ ব্যর্থতা হ্যান্ডলার সেট করে, তবে দুটি পৃথক সফল হ্যান্ডলার:

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.script.host পদ্ধতি setWidth(width) বা setHeight(height) কল করে Google Docs, Sheets বা Forms-এ কাস্টম ডায়ালগ বক্সের আকার পরিবর্তন করা যেতে পারে। (একটি ডায়ালগের প্রাথমিক আকার সেট করতে, HtmlOutput পদ্ধতিগুলি ব্যবহার করুন setWidth(width) এবং setHeight(height)

Google Workspaceএ ডায়ালগ এবং সাইডবার বন্ধ করা হচ্ছে

আপনি যদি Google ডক্স, পত্রক বা ফর্মগুলিতে একটি ডায়ালগ বাক্স বা সাইডবার প্রদর্শন করতে HTML পরিষেবা ব্যবহার করেন, তাহলে আপনি window.close() কল করে ইন্টারফেসটি বন্ধ করতে পারবেন না। পরিবর্তে, আপনাকে অবশ্যই google.script.host.close() কল করতে হবে। একটি উদাহরণের জন্য, Google Workspace ব্যবহারকারী ইন্টারফেস হিসাবে HTML পরিবেশন করার বিভাগটি দেখুন।

Google Workspaceএ ব্রাউজার ফোকাস সরানো

ব্যবহারকারীর ব্রাউজারে একটি ডায়ালগ বা সাইডবার থেকে Google ডক্স, পত্রক বা ফর্ম এডিটরে ফোকাস পরিবর্তন করতে, কেবল পদ্ধতিটি কল করুন google.script.host.editor.focus() ৷ এই পদ্ধতিটি ডকুমেন্ট পরিষেবা পদ্ধতি Document.setCursor(position) এবং Document.setSelection(range) এর সংমিশ্রণে বিশেষভাবে কার্যকর।