google.script.run হলো একটি অ্যাসিঙ্ক্রোনাস ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্ট এপিআই, যা এইচটিএমএল-সার্ভিস পেজগুলোকে সার্ভার-সাইড অ্যাপস স্ক্রিপ্ট ফাংশন কল করার সুযোগ দেয়। নিচের উদাহরণটি google.script.run এর সবচেয়ে মৌলিক কার্যকারিতা প্রদর্শন করে — অর্থাৎ ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্ট থেকে সার্ভারের একটি ফাংশন কল করা ।
কোড.জিএস
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 এপিআই সার্ভার ফাংশনে একই সাথে ১০টি কল করার অনুমতি দেয়। যদি ১০টি কল চালু থাকা অবস্থায় আপনি ১১তম কলটি করেন, তবে ১০টি স্থানের মধ্যে একটি খালি না হওয়া পর্যন্ত সার্ভার ফাংশনটি বিলম্বিত হয়। বাস্তবে, এই সীমাবদ্ধতা নিয়ে আপনাকে খুব কমই ভাবতে হবে, বিশেষ করে যেহেতু বেশিরভাগ ব্রাউজার ইতিমধ্যেই একই সার্ভারে একই সাথে ১০-এর কম সংখ্যক অনুরোধের মধ্যে সীমাবদ্ধ রাখে। উদাহরণস্বরূপ, ফায়ারফক্সে এই সীমা হলো ৬। একইভাবে, বেশিরভাগ ব্রাউজার বিদ্যমান অনুরোধগুলোর মধ্যে একটি সম্পূর্ণ না হওয়া পর্যন্ত অতিরিক্ত সার্ভার অনুরোধগুলো বিলম্বিত করে।
প্যারামিটার এবং রিটার্ন মান
ক্লায়েন্ট থেকে প্যারামিটারসহ একটি সার্ভার ফাংশন কল করুন। একইভাবে, একটি সার্ভার ফাংশন সাকসেস হ্যান্ডলারে প্যারামিটার হিসেবে একটি মান ক্লায়েন্টকে ফেরত দিতে পারে।
বৈধ প্যারামিটার এবং রিটার্ন ভ্যালু হলো জাভাস্ক্রিপ্ট প্রিমিটিভ যেমন Number , Boolean , String , বা null , সেইসাথে জাভাস্ক্রিপ্ট অবজেক্ট এবং অ্যারে যা প্রিমিটিভ, অবজেক্ট এবং অ্যারে দ্বারা গঠিত। পেজের মধ্যে থাকা একটি form এলিমেন্টও প্যারামিটার হিসেবে বৈধ, কিন্তু এটি অবশ্যই ফাংশনের একমাত্র প্যারামিটার হতে হবে এবং এটি রিটার্ন ভ্যালু হিসেবে বৈধ নয়। আপনি যদি Date , Function , form ছাড়া অন্য কোনো DOM এলিমেন্ট, বা অন্য কোনো নিষিদ্ধ টাইপ পাস করার চেষ্টা করেন, তাহলে রিকোয়েস্ট ব্যর্থ হবে; এর মধ্যে অবজেক্ট বা অ্যারের ভেতরের নিষিদ্ধ টাইপও অন্তর্ভুক্ত। যে অবজেক্টগুলো সার্কুলার রেফারেন্স তৈরি করে, সেগুলোও ব্যর্থ হয় এবং অ্যারের ভেতরের অনির্ধারিত ফিল্ড null হয়ে যায়।
মনে রাখবেন যে, সার্ভারে পাঠানো একটি অবজেক্ট মূলটির একটি অনুলিপি হয়ে যায়। যদি কোনো সার্ভার ফাংশন একটি অবজেক্ট গ্রহণ করে এবং তার প্রোপার্টিগুলো পরিবর্তন করে, তবে ক্লায়েন্টের প্রোপার্টিগুলো প্রভাবিত হয় না।
সফলতার পরিচালকরা
যেহেতু google.script.run কলগুলো অ্যাসিঙ্ক্রোনাস, তাই ক্লায়েন্ট-সাইড কোড কোনো প্রতিক্রিয়ার জন্য অপেক্ষা না করেই পরবর্তী লাইনে চলে যায়। সার্ভার সাড়া দিলে যে কলব্যাক ফাংশনটি চলবে, তা নির্দিষ্ট করতে withSuccessHandler(function) ব্যবহার করুন। যদি সার্ভার ফাংশনটি কোনো ভ্যালু রিটার্ন করে, তাহলে API সেই ভ্যালুটি প্যারামিটার হিসেবে কলব্যাক ফাংশনে পাঠিয়ে দেয়।
নিম্নলিখিত উদাহরণটি সার্ভার সাড়া দিলে একটি ব্রাউজার অ্যালার্ট প্রদর্শন করে। এই কোড স্যাম্পলটির জন্য অনুমোদনের প্রয়োজন, কারণ সার্ভার-সাইড ফাংশনটি আপনার জিমেইল অ্যাকাউন্ট অ্যাক্সেস করে। স্ক্রিপ্টটিকে অনুমোদন করতে, পৃষ্ঠাটি লোড করার আগে স্ক্রিপ্ট এডিটর থেকে getUnreadEmails ফাংশনটি ম্যানুয়ালি একবার চালান। বিকল্পভাবে, যখন আপনি "ওয়েব অ্যাপ অ্যাক্সেসকারী ব্যবহারকারী" হিসাবে চালানোর জন্য ওয়েব অ্যাপটি ডেপ্লয় করবেন , তখন অ্যাপটি লোড করার সময় আপনাকে অনুমোদনের জন্য অনুরোধ করা হবে।
কোড.জিএস
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 অবজেক্টটিকে একটি আর্গুমেন্ট হিসেবে ব্যর্থতা হ্যান্ডলারে পাঠিয়ে দেয়।
ডিফল্টরূপে, আপনি যদি কোনো ফেইলর হ্যান্ডলার নির্দিষ্ট না করেন, তাহলে ব্যর্থতাগুলো জাভাস্ক্রিপ্ট কনসোলে লগ করা হয়। এটি পরিবর্তন করতে, withFailureHandler(null) কল করুন অথবা এমন একটি ফেইলর হ্যান্ডলার দিন যা কোনো কাজ করে না।
এই উদাহরণটি যেমন দেখায়, ফেইলর হ্যান্ডলারের সিনট্যাক্স সাকসেস হ্যান্ডলারের সিনট্যাক্সের প্রায় অনুরূপ।
কোড.জিএস
function doGet() {
return HtmlService.createHtmlOutputFromFile('Index');
}
function getUnreadEmails() {
// 'got' instead of 'get' throws 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 নির্দেশ করে।
কোড.জিএস
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 এলিমেন্ট দিয়ে একটি সার্ভার ফাংশন কল করেন, তাহলে ফর্মটি একটি একক অবজেক্টে পরিণত হয়, যেখানে ফিল্ডের নামগুলো কী (key) এবং ফিল্ডের মানগুলো ভ্যালু (value) হিসেবে থাকে। ফাইল-ইনপুট ফিল্ডের বিষয়বস্তু ছাড়া বাকি সব ভ্যালু স্ট্রিং-এ রূপান্তরিত হয়; ফাইল-ইনপুট ফিল্ডের বিষয়বস্তুগুলো Blob ) অবজেক্টে পরিণত হয়।
এই উদাহরণটি পৃষ্ঠাটি রিলোড না করেই একটি ফাইল-ইনপুট ফিল্ড সহ একটি ফর্ম প্রসেস করে; এটি ফাইলটিকে গুগল ড্রাইভে আপলোড করে এবং তারপর ক্লায়েন্ট-সাইড পৃষ্ঠায় ফাইলটির 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();
}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 ফাংশনগুলো ক্লায়েন্টের কাছে সম্পূর্ণ অদৃশ্য থাকে।
কোড.জিএস
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 Docs, Google Sheets, বা Forms-এর কাস্টম ডায়ালগ বক্সগুলো ক্লায়েন্ট-সাইড কোডে google.script.host এর setWidth(width) বা setHeight(height) মেথড কল করে রিসাইজ করা যায়। (একটি ডায়ালগের প্রাথমিক আকার সেট করতে, HtmlOutput এর setWidth(width) এবং setHeight(height) মেথডগুলো ব্যবহার করুন।) মনে রাখবেন যে, রিসাইজ করার সময় ডায়ালগগুলো প্যারেন্ট উইন্ডোতে পুনরায় কেন্দ্রে আসে না এবং সাইডবার রিসাইজ করা সম্ভব নয়।
গুগল ওয়ার্কস্পেসে ডায়ালগ এবং সাইডবার বন্ধ করুন
আপনি যদি Google Docs, Sheets, বা Forms-এ কোনো ডায়ালগ বা সাইডবার দেখানোর জন্য HTML সার্ভিস ব্যবহার করেন, তাহলে আপনি window.close কল করে ইন্টারফেসটি বন্ধ করতে পারবেন না। এর পরিবর্তে, আপনাকে অবশ্যই google.script.host.close কল করতে হবে। একটি উদাহরণের জন্য, Google Workspace ইউজার ইন্টারফেস হিসেবে HTML পরিবেশন করার অংশটি দেখুন।
গুগল ওয়ার্কস্পেসে ব্রাউজার ফোকাস সরান
ব্যবহারকারীর ব্রাউজারে কোনো ডায়ালগ বা সাইডবার থেকে ফোকাস পরিবর্তন করে গুগল ডক্স, শীটস বা ফর্মস এডিটরে ফিরিয়ে আনতে, google.script.host.editor.focus মেথডটি কল করুন। এই মেথডটি Document সার্ভিস মেথড Document.setCursor(position) এবং Document.setSelection(range) এর সাথে একত্রে ব্যবহার করলে বিশেষভাবে কার্যকর হয়।