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

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

কোড.জিএস

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function doSomething() {
  Logger.log('I was called!');
}

ইনডেক্স.এইচটিএমএল

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      google.script.run.doSomething();
    </script>
  </head>
</html>

যদি আপনি এই স্ক্রিপ্টটি একটি ওয়েব অ্যাপ হিসেবে স্থাপন করেন এবং এর URL টি দেখেন, তাহলে আপনি কিছুই দেখতে পাবেন না, কিন্তু যদি আপনি লগগুলি দেখেন, তাহলে আপনি দেখতে পাবেন যে সার্ভার ফাংশন doSomething() কল করা হয়েছে।

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

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

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

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

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

মনে রাখবেন যে সার্ভারে পাঠানো একটি বস্তু মূল বস্তুর একটি অনুলিপি হয়ে যায়। যদি একটি সার্ভার ফাংশন একটি বস্তু গ্রহণ করে এবং তার বৈশিষ্ট্য পরিবর্তন করে, তাহলে ক্লায়েন্টের বৈশিষ্ট্যগুলি প্রভাবিত হয় না।

সাফল্য হ্যান্ডলার

যেহেতু ক্লায়েন্ট-সাইড কোড সার্ভার কল সম্পূর্ণ হওয়ার জন্য অপেক্ষা না করেই পরবর্তী লাইনে চলে যায়, withSuccessHandler(function) আপনাকে সার্ভারের প্রতিক্রিয়া জানালে চালানোর জন্য একটি ক্লায়েন্ট-সাইড কলব্যাক ফাংশন নির্দিষ্ট করতে দেয়। যদি সার্ভার ফাংশন একটি মান ফেরত দেয়, তাহলে API মানটি একটি প্যারামিটার হিসাবে নতুন ফাংশনে প্রেরণ করে।

সার্ভার সাড়া দিলে নিচের উদাহরণটি একটি ব্রাউজার সতর্কতা প্রদর্শন করে। মনে রাখবেন যে এই কোড নমুনার অনুমোদন প্রয়োজন কারণ সার্ভার-সাইড ফাংশনটি আপনার Gmail অ্যাকাউন্ট অ্যাক্সেস করছে। স্ক্রিপ্টটি অনুমোদন করার সবচেয়ে সহজ উপায় হল পৃষ্ঠাটি লোড করার আগে একবার স্ক্রিপ্ট এডিটর থেকে getUnreadEmails() ফাংশনটি ম্যানুয়ালি চালানো। বিকল্পভাবে, যখন আপনি ওয়েব অ্যাপটি স্থাপন করেন , তখন আপনি এটি "ওয়েব অ্যাপ অ্যাক্সেসকারী ব্যবহারকারী" হিসাবে চালানো বেছে নিতে পারেন, এই ক্ষেত্রে আপনি অ্যাপটি লোড করার সময় অনুমোদনের জন্য অনুরোধ করা হবে।

কোড.জিএস

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function getUnreadEmails() {
  return GmailApp.getInboxUnreadCount();
}

ইনডেক্স.এইচটিএমএল

<!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 অবজেক্ট (যদি থাকে) একটি আর্গুমেন্ট হিসেবে পাস করে।

ডিফল্টরূপে, যদি আপনি একটি ব্যর্থতা হ্যান্ডলার নির্দিষ্ট না করেন, তাহলে ব্যর্থতাগুলি জাভাস্ক্রিপ্ট কনসোলে লগ করা হয়। এটিকে ওভাররাইড করতে, withFailureHandler(null) কল করুন অথবা এমন একটি ব্যর্থতা হ্যান্ডলার সরবরাহ করুন যা কিছুই করে না।

এই উদাহরণে দেখানো হয়েছে যে, ব্যর্থতা হ্যান্ডলারের সিনট্যাক্স প্রায় সাফল্য হ্যান্ডলারের মতোই।

কোড.জিএস

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function getUnreadEmails() {
  // 'got' instead of 'get' will throw an error.
  return GmailApp.gotInboxUnreadCount();
}

ইনডেক্স.এইচটিএমএল

<!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 object" - User ক্লাসের সাথে বিভ্রান্ত না হয়ে - আপনাকে ক্লায়েন্ট সার্ভারের সাথে যে প্রসঙ্গে যোগাযোগ করেছে তার প্রতিক্রিয়া জানাতে দেয়। যেহেতু ব্যবহারকারীর অবজেক্টগুলি সার্ভারে পাঠানো হয় না, সেগুলি প্রায় যেকোনো কিছু হতে পারে, যার মধ্যে ফাংশন, DOM উপাদান ইত্যাদি অন্তর্ভুক্ত, সার্ভার কলের জন্য প্যারামিটার এবং রিটার্ন মানের উপর কোনও বিধিনিষেধ ছাড়াই। তবে ব্যবহারকারীর অবজেক্টগুলি new অপারেটর দিয়ে তৈরি অবজেক্ট হতে পারে না।

এই উদাহরণে, দুটি বোতামের যেকোনো একটিতে ক্লিক করলে সার্ভার থেকে একটি মান সহ সেই বোতামটি আপডেট হবে এবং অন্য বোতামটি অপরিবর্তিত থাকবে, যদিও তারা একটি সাফল্য হ্যান্ডলার ভাগ করে নেয়। onclick হ্যান্ডলারের ভিতরে, this কীওয়ার্ডটি button নির্দেশ করে।

কোড.জিএস

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function getEmail() {
  return Session.getActiveUser().getEmail();
}

ইনডেক্স.এইচটিএমএল

<!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-এ পুনঃনির্দেশিত হতে বাধা দেয়।

কোড.জিএস

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function processForm(formObject) {
  var formBlob = formObject.myFile;
  var driveFile = DriveApp.createFile(formBlob);
  return driveFile.getUrl();
}

ইনডেক্স.এইচটিএমএল

<!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() ফাংশনগুলি ক্লায়েন্টের কাছে সম্পূর্ণ অদৃশ্য।

কোড.জিএস

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
  }
};

ইনডেক্স.এইচটিএমএল

<!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, অথবা Forms-এ একটি ডায়ালগ বক্স বা সাইডবার প্রদর্শনের জন্য HTML পরিষেবা ব্যবহার করেন, তাহলে window.close() কল করে ইন্টারফেসটি বন্ধ করতে পারবেন না। পরিবর্তে, আপনাকে google.script.host.close() কল করতে হবে। উদাহরণস্বরূপ, Google Workspace ব্যবহারকারী ইন্টারফেস হিসেবে HTML পরিবেশন করার বিভাগটি দেখুন।

গুগল ওয়ার্কস্পেসে ব্রাউজারের ফোকাস সরানো হচ্ছে

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