google.script.run adalah API JavaScript sisi klien asinkron yang memungkinkan halaman layanan HTML memanggil fungsi Apps Script sisi server. Contoh berikut menunjukkan fungsi
paling dasar google.script.run — memanggil fungsi di
server dari JavaScript
sisi klien.
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>Jika Anda men-deploy skrip ini sebagai aplikasi web dan membuka URL-nya, Anda tidak akan melihat apa pun, tetapi jika melihat log, Anda akan melihat bahwa fungsi server doSomething dipanggil.
Panggilan sisi klien ke fungsi sisi server bersifat asinkron: setelah browser
meminta server menjalankan fungsi doSomething, browser akan segera
melanjutkan ke baris kode berikutnya tanpa menunggu respons. Artinya, panggilan fungsi server mungkin tidak dieksekusi dalam urutan yang Anda harapkan. Jika Anda melakukan
dua panggilan fungsi secara bersamaan, tidak ada cara untuk mengetahui fungsi mana yang berjalan
terlebih dahulu; hasilnya dapat berbeda setiap kali Anda memuat halaman. Dalam situasi ini,
handler keberhasilan dan handler kegagalan
membantu mengontrol alur kode Anda.
API google.script.run memungkinkan 10 panggilan serentak ke fungsi server. Jika Anda melakukan panggilan ke-11 saat 10 panggilan masih berjalan, fungsi server akan ditunda hingga salah satu dari 10 tempat kosong. Dalam praktiknya, Anda jarang perlu memikirkan batasan ini, terutama karena sebagian besar browser sudah membatasi jumlah permintaan serentak ke server yang sama pada jumlah yang lebih rendah dari 10.
Di Firefox, misalnya, batasnya adalah 6. Sebagian besar browser juga menunda permintaan server yang berlebihan hingga salah satu permintaan yang ada selesai.
Parameter dan nilai yang ditampilkan
Panggil fungsi server dengan parameter dari klien. Demikian pula, fungsi server dapat menampilkan nilai ke klien sebagai parameter yang diteruskan ke handler keberhasilan.
Parameter resmi dan nilai yang ditampilkan adalah primitif JavaScript seperti Number,
Boolean, String, atau null, serta objek dan array JavaScript yang
terdiri dari primitif, objek, dan array. Elemen form dalam halaman
juga sah sebagai parameter, tetapi harus menjadi satu-satunya parameter fungsi, dan
tidak sah sebagai nilai yang ditampilkan. Permintaan akan gagal jika Anda mencoba meneruskan
Date, Function, elemen DOM selain form, atau jenis yang dilarang lainnya,
termasuk jenis yang dilarang di dalam objek atau array. Objek yang membuat
referensi melingkar juga akan gagal, dan kolom yang tidak ditentukan dalam array akan menjadi
null.
Perhatikan bahwa objek yang diteruskan ke server akan menjadi salinan objek asli. Jika fungsi server menerima objek dan mengubah propertinya, properti di klien tidak terpengaruh.
Handler keberhasilan
Karena panggilan google.script.run bersifat asinkron, kode sisi klien akan berlanjut
ke baris berikutnya tanpa menunggu respons. Untuk menentukan fungsi
callback yang berjalan saat server merespons, gunakan
withSuccessHandler(function).
Jika fungsi server menampilkan nilai, API akan meneruskan nilai tersebut ke fungsi callback sebagai parameter.
Contoh berikut menampilkan pemberitahuan browser saat server merespons. Contoh
kode ini memerlukan otorisasi karena fungsi sisi server mengakses
akun Gmail Anda. Untuk mengotorisasi skrip, jalankan fungsi
getUnreadEmails secara manual dari editor skrip satu kali sebelum Anda memuat
halaman. Atau, saat Anda
men-deploy aplikasi web untuk
dieksekusi sebagai "pengguna yang mengakses aplikasi web", Anda akan diminta otorisasi
saat memuat aplikasi.
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>Pengendali kegagalan
Jika server gagal merespons atau menampilkan error,
withFailureHandler(function)
memungkinkan Anda menentukan pengendali kegagalan untuk dijalankan sebagai pengganti pengendali keberhasilan.
Jika terjadi error, API akan meneruskan objek
Error
sebagai argumen ke pengendali kegagalan.
Secara default, jika Anda tidak menentukan pengendali kegagalan, kegagalan akan dicatat ke konsol JavaScript. Untuk mengganti perilaku ini, panggil withFailureHandler(null) atau berikan pengendali kegagalan yang tidak melakukan apa pun.
Sintaksis untuk pengendali kegagalan hampir sama dengan pengendali keberhasilan, seperti yang ditunjukkan contoh ini.
Code.gs
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>Objek pengguna
Untuk menggunakan kembali handler keberhasilan atau kegagalan yang sama untuk beberapa panggilan ke server, panggil withUserObject(object) untuk menentukan objek yang diteruskan ke handler sebagai parameter kedua.
"Objek pengguna" ini, yang tidak boleh disamakan dengan
kelas User, memungkinkan Anda merespons
konteks saat klien menghubungi server. Karena objek pengguna tidak dikirim ke server, objek tersebut dapat berupa apa saja, termasuk fungsi dan elemen DOM, tanpa batasan pada parameter dan nilai yang ditampilkan untuk panggilan server. Objek pengguna tidak boleh berupa objek yang dibuat dengan
operator new.
Dalam contoh ini, mengklik salah satu dari dua tombol akan memperbarui tombol tersebut dengan
nilai dari server, sementara tombol lainnya tidak berubah, meskipun keduanya
berbagi satu pengendali keberhasilan. Di dalam handler onclick, kata kunci this
merujuk ke button itu sendiri.
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>Formulir
Jika Anda memanggil fungsi server dengan elemen form sebagai parameter, formulir
akan menjadi satu objek dengan nama kolom sebagai kunci dan nilai kolom sebagai nilai. Semua nilai dikonversi menjadi string, kecuali konten kolom input file, yang menjadi objek Blob.
Contoh ini memproses formulir, termasuk kolom input file, tanpa memuat ulang
halaman; contoh ini mengupload file ke Google Drive, lalu mencetak URL untuk
file di halaman sisi klien. Di dalam handler onsubmit, kata kunci this
merujuk ke formulir itu sendiri. Perhatikan bahwa saat memuat, semua formulir di halaman memiliki
tindakan pengiriman default yang dinonaktifkan oleh preventFormSubmit. Hal ini mencegah
halaman dialihkan ke URL yang tidak akurat jika terjadi pengecualian.
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>Runner skrip
Anggap google.script.run sebagai builder untuk "pelaku skrip". Jika Anda
menambahkan pengendali yang berhasil, pengendali yang gagal, atau objek pengguna ke pelaksana skrip, Anda
tidak mengubah pelaksana yang ada; sebagai gantinya, Anda akan mendapatkan kembali pelaksana skrip baru
dengan perilaku baru.
Gunakan kombinasi dan urutan withSuccessHandler, withFailureHandler, dan withUserObject. Panggil juga salah satu
fungsi pengubah pada pelaksana skrip yang sudah memiliki nilai yang ditetapkan. Nilai baru akan menggantikan nilai sebelumnya.
Contoh ini menetapkan pengendali kegagalan umum untuk ketiga panggilan server, tetapi dua pengendali keberhasilan terpisah:
var myRunner = google.script.run.withFailureHandler(onFailure);
var myRunner1 = myRunner.withSuccessHandler(onSuccess);
var myRunner2 = myRunner.withSuccessHandler(onDifferentSuccess);
myRunner1.doSomething();
myRunner1.doSomethingElse();
myRunner2.doSomething();
Fungsi pribadi
Fungsi server yang namanya diakhiri dengan garis bawah dianggap pribadi.
Fungsi ini tidak dapat dipanggil oleh google.script dan namanya tidak pernah
dikirim ke klien. Anda dapat menggunakannya untuk menyembunyikan detail implementasi yang
harus dirahasiakan di server. google.script juga tidak dapat melihat
fungsi dalam library atau fungsi yang tidak
dideklarasikan di tingkat teratas skrip.
Dalam contoh ini, fungsi getBankBalance tersedia di kode klien; pengguna yang memeriksa kode sumber Anda dapat menemukan namanya meskipun Anda tidak memanggilnya. Namun, fungsi deepSecret_ dan obj.objectMethod
sama sekali tidak terlihat oleh
klien.
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>Mengubah ukuran dialog di aplikasi Google Workspace
Kotak dialog kustom di Google Dokumen, Google Spreadsheet, atau Formulir dapat diubah ukurannya dengan memanggil metode
google.script.host
setWidth(width) atau
setHeight(height) dalam
kode sisi klien. (Untuk menetapkan ukuran awal dialog, gunakan metode HtmlOutput
setWidth(width)
dan
setHeight(height).)
Perhatikan bahwa dialog tidak dipusatkan kembali di jendela induk saat diubah ukurannya, dan sidebar tidak dapat diubah ukurannya.
Menutup dialog dan sidebar di Google Workspace
Jika Anda menggunakan layanan HTML untuk menampilkan dialog atau
sidebar di Google Dokumen, Spreadsheet,
atau Formulir, Anda tidak dapat menutup antarmuka dengan memanggil
window.close. Sebagai gantinya, Anda harus memanggil
google.script.host.close.
Untuk melihat contohnya, lihat bagian tentang menayangkan HTML sebagai antarmuka pengguna Google Workspace.
Memindahkan fokus browser di Google Workspace
Untuk mengalihkan fokus di browser pengguna dari dialog atau sidebar kembali ke editor Google Dokumen, Spreadsheet, atau Formulir, panggil metode
google.script.host.editor.focus.
Metode ini sangat berguna jika digabungkan dengan metode Document
service Document.setCursor(position)
dan
Document.setSelection(range).