google.script.run
adalah model asinkron
JavaScript API sisi klien yang memungkinkan halaman layanan HTML memanggil sisi server
Fungsi Apps Script. Contoh berikut menunjukkan fungsi yang paling dasar
dari 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 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 agar server menjalankan fungsi doSomething()
, browser akan melanjutkan
langsung ke baris kode berikutnya
tanpa menunggu respons. Artinya,
panggilan fungsi server mungkin tidak dieksekusi dalam urutan yang Anda harapkan. Jika Anda membuat
dua panggilan fungsi secara bersamaan, tidak ada cara untuk mengetahui fungsi mana
jalankan terlebih dahulu; hasilnya mungkin berbeda setiap kali Anda memuat halaman. Dalam situasi ini,
pengendali keberhasilan dan pengendali kegagalan
membantu mengontrol alur kode Anda.
google.script.run
API memungkinkan 10 panggilan serentak ke fungsi server. Jika
Anda melakukan panggilan ke-11 saat 10 masih berjalan, fungsi server akan
ditunda sampai salah satu
dari 10 titik kosong. Dalam praktiknya, Anda jarang harus memikirkan
batasan ini, terutama karena sebagian besar browser sudah membatasi
jumlah permintaan serentak ke server yang sama dengan jumlah yang lebih rendah dari 10.
Di Firefox, misalnya, batasnya adalah 6. Sebagian besar browser juga menunda permintaan server yang berlebih hingga salah satu permintaan yang ada selesai.
Parameter dan nilai yang ditampilkan
Anda dapat memanggil fungsi server dengan parameter dari klien. Demikian pula, fungsi server dapat mengembalikan nilai ke klien sebagai parameter yang diteruskan ke pengendali 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
di dalam halaman
juga legal sebagai parameter, tetapi harus menjadi satu-satunya parameter fungsi, dan
itu tidak sah sebagai nilai hasil. Permintaan akan gagal jika Anda mencoba meneruskan
Date
, Function
, elemen DOM selain form
, atau jenis terlarang 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 menjadi
null
.
Perhatikan bahwa objek yang diteruskan ke server menjadi salinan dari objek asli. Jika server menerima objek dan mengubah propertinya, properti pada klien tidak terpengaruh.
Pengendali berhasil
Karena kode sisi klien berlanjut ke baris berikutnya tanpa menunggu server
untuk menyelesaikan panggilan,
withSuccessHandler(function)
memungkinkan Anda menentukan fungsi callback sisi klien yang akan dijalankan saat
merespons. Jika fungsi server menampilkan nilai, API akan meneruskan nilai tersebut ke
fungsi baru sebagai parameter.
Contoh berikut menampilkan peringatan browser saat server merespons. Catatan
bahwa contoh kode ini memerlukan otorisasi
karena fungsi sisi server
yang mengakses akun Gmail Anda. Cara paling sederhana untuk memberikan otorisasi pada skrip adalah dengan menjalankan
fungsi getUnreadEmails()
secara manual dari editor skrip satu kali sebelum Anda
memuat halaman. Atau, ketika Anda
men-deploy aplikasi web, Anda dapat memilih
untuk menjalankannya sebagai "pengguna yang mengakses aplikasi web," dalam hal ini Anda akan
akan diminta untuk melakukan otorisasi
saat Anda 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 pesan {i>error<i},
withFailureHandler(function)
memungkinkan Anda menentukan pengendali kegagalan, alih-alih pengendali berhasil, dengan
Error
(jika ada) yang diteruskan sebagai argumen.
Secara default, jika Anda tidak menetapkan pengendali kegagalan, kegagalan akan dicatat ke
Konsol JavaScript. Untuk menggantinya, 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' 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>
Objek pengguna
Anda bisa menggunakan kembali pengendali yang berhasil atau gagal yang sama untuk beberapa panggilan ke
server dengan memanggil
withUserObject(object)
untuk menentukan objek yang akan diteruskan ke pengendali sebagai parameter kedua.
“Objek pengguna” ini — jangan tertukar dengan
User
— memungkinkan Anda merespons
di mana klien menghubungi server. Karena objek pengguna tidak
dikirim ke server, mereka bisa apa saja, termasuk fungsi, DOM
elemen, dan seterusnya, tanpa batasan parameter dan nilai yang ditampilkan
untuk panggilan server. Namun, 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 tanpa mengubah tombol lainnya, meskipun tombol tersebut
memiliki satu pengendali yang berhasil. Di dalam pengendali onclick
, kata kunci this
merujuk pada 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
menjadi objek tunggal dengan nama kolom sebagai kunci dan nilai kolom sebagai nilai. Tujuan
semua nilai dikonversi menjadi string, kecuali untuk isi input
kolom, yang menjadi objek Blob
.
Contoh ini memproses formulir, termasuk kolom input file, tanpa memuat ulang
halaman; file diupload ke Google Drive dan kemudian
mencetak URL untuk
di halaman sisi klien. Di dalam pengendali onsubmit
, kata kunci this
mengacu pada formulir itu sendiri. Perhatikan bahwa setelah memuat,
semua formulir di halaman memiliki
tindakan kirim default dinonaktifkan oleh preventFormSubmit
. Hal ini mencegah
halaman agar tidak mengarah 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
Anda dapat menganggap google.script.run
sebagai builder untuk "pelari skrip". Jika Anda
menambahkan pengendali berhasil, pengendali kegagalan, atau objek pengguna ke runner skrip,
tidak mengubah runner yang ada; sebagai gantinya, Anda mendapatkan kembali runner skrip baru
dengan perilaku baru.
Anda dapat menggunakan kombinasi apa pun dan berapa pun urutan withSuccessHandler()
,
withFailureHandler()
, dan withUserObject()
. Anda juga dapat memanggil
memodifikasi fungsi pada runner skrip yang sudah memiliki nilai yang ditetapkan. Yang baru
mengganti 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. Dengan demikian, Anda dapat menggunakannya untuk menyembunyikan detail implementasi yang
perlu dirahasiakan di server. google.script
juga tidak dapat melihat
fungsi dalam library dan fungsi yang tidak
yang dideklarasikan di tingkat atas skrip.
Dalam contoh ini, fungsi getBankBalance()
tersedia di klien
kode; pengguna yang memeriksa kode program Anda
dapat menemukan namanya bahkan jika Anda
jangan menyebutnya. 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 Google Workspace aplikasi
Kotak dialog kustom di Google Dokumen, Spreadsheet, atau
Formulir dapat diubah ukurannya dengan memanggil
Metode google.script.host
setWidth(width)
atau
setHeight(height)
dalam
kode sisi klien. (Untuk menyetel ukuran awal dialog, gunakan HtmlOutput
metode
setWidth(width)
dan
setHeight(height)
.)
Perhatikan, dialog tidak dipusatkan lagi di jendela induk saat diubah ukurannya, dan
tidak mungkin mengubah ukuran sidebar.
Menutup dialog dan sidebar di Google Workspace
Jika Anda menggunakan layanan HTML untuk menampilkan
kotak dialog atau sidebar di Google Dokumen, Spreadsheet, atau
Formulir, Anda tidak dapat menutup antarmuka dengan memanggil window.close()
. Sebaliknya, Anda dapat
harus memanggil
google.script.host.close()
Untuk contohnya, lihat bagian tentang
menayangkan HTML sebagai Google Workspace antarmuka pengguna.
Memindahkan fokus browser di Google Workspace
Untuk mengalihkan fokus di browser pengguna dari dialog atau sidebar kembali ke
Editor Google Dokumen, Spreadsheet, atau Formulir, cukup panggil metode
google.script.host.editor.focus()
Metode ini sangat berguna jika dikombinasikan dengan
Metode Layanan dokumen
Document.setCursor(position)
dan
Document.setSelection(range)