1. Pengantar
Tujuan codelab ini adalah agar Anda memahami cara menulis Cloud Function untuk merespons upload file CSV ke Cloud Storage, membaca kontennya, dan menggunakannya untuk memperbarui Spreadsheet Google menggunakan Sheets API.

Hal ini dapat dilihat sebagai otomatisasi langkah "impor sebagai CSV" yang biasanya dilakukan secara manual. Dengan begitu, Anda dapat menganalisis data (yang mungkin dihasilkan oleh tim lain) di spreadsheet segera setelah tersedia.
Implementasinya akan terlihat seperti ini :

2. Penyiapan dan Persyaratan
Penyiapan lingkungan mandiri
- Login ke Cloud Console dan buat project baru atau gunakan kembali project yang sudah ada. (Jika belum memiliki akun Gmail atau G Suite, Anda harus membuatnya.)
Ingat project ID, nama unik di semua project Google Cloud (maaf, nama di atas telah digunakan dan tidak akan berfungsi untuk Anda!) Project ID tersebut selanjutnya akan dirujuk di codelab ini sebagai PROJECT_ID.
- Selanjutnya, Anda harus mengaktifkan penagihan di Cloud Console untuk menggunakan resource Google Cloud.
Menjalankan operasi dalam codelab ini seharusnya tidak memerlukan banyak biaya, bahkan mungkin tidak sama sekali. Pastikan untuk mengikuti petunjuk yang ada di bagian "Membersihkan" yang memberi tahu Anda cara menonaktifkan resource sehingga tidak menimbulkan penagihan di luar tutorial ini. Pengguna baru Google Cloud memenuhi syarat untuk mengikuti program Uji Coba Gratis senilai $300 USD.
3. Buat dan konfigurasi Spreadsheet Google serta aktifkan API
Pertama, buat dokumen Spreadsheet baru (spreadsheet ini dapat dimiliki oleh pengguna mana pun). Setelah dibuat, ingat ID-nya; ID ini akan digunakan sebagai variabel lingkungan untuk fungsi yang akan kita tulis :

Dari konsol GCP, aktifkan Google Sheets API di project yang baru dibuat dengan membuka bagian "APIs and Services", lalu "API Library":

Di bagian "IAM & admin", buka "Service accounts" dan catat Email untuk akun layanan default App Engine. Formatnya harus your-project-id@appspot.gserviceaccount.com. Tentu saja Anda juga dapat membuat akun layanan Anda sendiri yang dikhususkan untuk tindakan ini.

Terakhir, cukup beri akun layanan ini hak istimewa edit ke spreadsheet Anda menggunakan tombol "Bagikan":

Dengan penyiapan ini, kita sekarang dapat menulis Cloud Function dan mengonfigurasinya untuk menggunakan akun layanan ini. Aplikasi ini akan dapat menulis ke dokumen spreadsheet yang baru saja kita buat.
4. Membuat bucket penyimpanan
Mari kita buat bucket yang akan dipantau oleh fungsi cloud kita untuk mencari file CSV baru.
Di konsol, gunakan menu sebelah kiri untuk membuka "Storage"... :

... dan buat bucket baru bernama csv2sheet-POSTFIX (ganti POSTFIX dengan sesuatu yang unik) dengan semua setelan lainnya ditetapkan ke nilai defaultnya :

5. Buat Cloud Function
Sekarang kita dapat membuat Cloud Function bernama csv2sheet yang dipicu saat file diupload ke bucket Cloud Storage tertentu. Kode akan ditulis dalam Node.js 8 dengan fungsi asinkron menggunakan editor inline langsung di Cloud Console :

Pastikan untuk menyetel Pemicu ke "Cloud Storage" dan menyesuaikan nama bucket ke nama bucket yang telah Anda buat di langkah sebelumnya.
Perbarui juga titik entri untuk fungsi yang akan kita tulis ke csv2sheet :

Sekarang ubah isi fungsi menjadi :
- menggunakan Cloud Storage dan Sheets API
- tandai fungsi
csv2sheetsebagaiasync - mendapatkan
fileNamedari metadata peristiwa Cloud Storage dan mendapatkan nama untuk sheet baru yang akan kita buat :
const {google} = require("googleapis");
const {Storage} = require("@google-cloud/storage")
exports.csv2sheet = async (data, context) => {
var fileName = data.name;
// basic check that this is a *.csv file, etc...
if (!fileName.endsWith(".csv")) {
console.log("Not a .csv file, ignoring.");
return;
}
// define name of new sheet
const sheetName = fileName.slice(0, -4);
// TODO!
};
Penggunaan async di sini diperlukan untuk menggunakan await seperti yang akan kita lihat sebentar lagi.
Beberapa opsi penting saat membuat fungsi ini meliputi (klik link "Lainnya" di bagian bawah layar) :
- Gunakan menu dropdown untuk memilih akun layanan yang dibahas di atas
- Tentukan variabel lingkungan bernama
SPREADSHEET_IDyang harus cocok dengan dokumen spreadsheet yang telah Anda buat sebelumnya :

Sebagai langkah penyiapan terakhir, berikut konten package.json dengan Cloud Storage dan Google Sheet API sebagai dua dependensi yang akan kita gunakan (gunakan tab PACKAGE.JSON editor inline konsol) :
{
"name": "csv2sheet",
"version": "0.0.42",
"dependencies": {
"googleapis": "^51.0.0",
"@google-cloud/storage": "^5.0.1"
}
}
Setelah Anda mengonfigurasi semuanya seperti yang dijelaskan, lanjutkan, klik "Buat". Setelah beberapa menit, fungsi Anda akan dibuat dan di-deploy.
6. Menyiapkan autentikasi dan Sheets API
Sebelum menulis kode lebih lanjut di fungsi Cloud menggunakan editor inline, kita perlu memblokir pembuatan Google Client API dengan cakupan Storage dan Sheet yang tepat (ingat, ini adalah bagian dari fungsi async).
Di editor fungsi konsol, klik "EDIT" dan tambahkan kode berikut ke isi fungsi csv2sheet Anda :
// block on auth + getting the sheets API object
const auth = await google.auth.getClient({
scopes: [
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/devstorage.read_only"
]
});
Dari sana, kita dapat membuat klien Sheets API :
const sheetsAPI = google.sheets({version: 'v4', auth});
7. Gunakan Spreadsheet API untuk membuat spreadsheet kosong
Dengan klien Sheets API, kita dapat membuat sheet baru yang sederhana dalam dokumen, tetapi sebelum melanjutkan, berikut catatan singkat tentang kosakata:
- spreadsheet adalah dokumen sebenarnya dan dirujuk oleh ID-nya (dibahas di atas dan terlihat di URL dokumen)
- sheet adalah salah satu tab dalam dokumen dan dapat dirujuk berdasarkan namanya (nama tab) atau ID yang dibuat saat pembuatan sheet
Dengan mempertimbangkan hal ini, berikut adalah fungsi yang menggunakan klien Sheets API untuk membuat sheet kosong di posisi 2 (biasanya setelah "Sheet1" default), dengan 26 kolom, 2.000 baris, dengan baris pertama dibekukan (tambahkan ke fungsi Anda menggunakan editor inline) :
function addEmptySheet(sheetsAPI, sheetName) {
return new Promise((resolve, reject) => {
const emptySheetParams = {
spreadsheetId: process.env.SPREADSHEET_ID,
resource: {
requests: [
{
addSheet: {
properties: {
title: sheetName,
index: 1,
gridProperties: {
rowCount: 2000,
columnCount: 26,
frozenRowCount: 1
}
}
}
}
]
}
};
sheetsAPI.spreadsheets.batchUpdate( emptySheetParams, function(err, response) {
if (err) {
reject("The Sheets API returned an error: " + err);
} else {
const sheetId = response.data.replies[0].addSheet.properties.sheetId;
console.log("Created empty sheet: " + sheetId);
resolve(sheetId);
}
}
);
});
}
Perhatikan bahwa alih-alih melakukan hard code pada referensi ke spreadsheet, kita mengandalkan variabel lingkungan SPREADSHEET_ID yang dibuat sebelumnya.
Kita perlu mengingat sheetId untuk permintaan lebih lanjut yang dibuat ke sheet ini. Selain itu, nama sheet harus unik dan pembuatan akan gagal jika sudah ada sheet bernama sheetName.
Fungsi batchUpdate di Sheets API adalah cara umum untuk berinteraksi dengan dokumen dan dijelaskan di sini.
8. Membaca data dari file CSV penyimpanan
Setelah memiliki tempat untuk memindahkan data, mari kita kembangkan lebih lanjut fungsi cloud di editor inline dan gunakan Cloud Storage API untuk mengambil data sebenarnya dari file yang baru saja diupload dan menyimpannya dalam string:
function readCSVContent(sheetsAPI, file, sheetName) {
return new Promise((resolve, reject) => {
const storage = new Storage();
let fileContents = new Buffer('');
storage.bucket(file.bucket).file(file.name).createReadStream()
.on('error', function(err) {
reject('The Storage API returned an error: ' + err);
})
.on('data', function(chunk) {
fileContents = Buffer.concat([fileContents, chunk]);
})
.on('end', function() {
let content = fileContents.toString('utf8');
console.log("CSV content read as string : " + content );
resolve(content);
});
});
}
9. Mengisi sheet yang baru dibuat
Sekarang saatnya mengisi spreadsheet yang telah kita buat menggunakan Sheet client API yang sama dan data yang baru saja kita kumpulkan. Kita akan memanfaatkan kesempatan ini untuk menambahkan beberapa gaya ke kolom sheet (mengubah ukuran font baris atas dan membuatnya tebal) :
function populateAndStyle(sheetsAPI, theData, sheetId) {
return new Promise((resolve, reject) => {
// Using 'batchUpdate' allows for multiple 'requests' to be sent in a single batch.
// Populate the sheet referenced by its ID with the data received (a CSV string)
// Style: set first row font size to 11 and to Bold. Exercise left for the reader: resize columns
const dataAndStyle = {
spreadsheetId: process.env.SPREADSHEET_ID,
resource: {
requests: [
{
pasteData: {
coordinate: {
sheetId: sheetId,
rowIndex: 0,
columnIndex: 0
},
data: theData,
delimiter: ","
}
},
{
repeatCell: {
range: {
sheetId: sheetId,
startRowIndex: 0,
endRowIndex: 1
},
cell: {
userEnteredFormat: {
textFormat: {
fontSize: 11,
bold: true
}
}
},
fields: "userEnteredFormat(textFormat)"
}
}
]
}
};
sheetsAPI.spreadsheets.batchUpdate(dataAndStyle, function(err, response) {
if (err) {
reject("The Sheets API returned an error: " + err);
} else {
console.log(sheetId + " sheet populated with " + theData.length + " rows and column style set.");
resolve();
}
});
});
}
Kode ini harus ditambahkan ke fungsi Cloud kita yang kini sudah 99% selesai.
Perhatikan bagaimana data dan gaya digabungkan sebagai beberapa requests ke dalam satu panggilan Sheets API batchUpdate. Hal ini membuat update menjadi lebih efisien dan atomik.
Perhatikan juga bahwa kita menentukan rentang pengeditan yang cocok dengan ukuran sheet yang telah kita buat. Artinya, konten yang melebihi 26 kolom (nilai columnCount yang digunakan saat membuat sheet) akan gagal dengan kode ini.
Jika semuanya berjalan lancar, pada tahap ini Anda dapat:
- menyimpan fungsi yang diperbarui
- menempatkan file CSV ke dalam bucket
- Lihat data yang sesuai muncul di spreadsheet Anda.
10. Menyatukan semuanya dan menguji alur
Panggilan ke fungsi yang baru saja kita bahas dapat dilakukan sebagai panggilan pemblokiran berturut-turut dalam fungsi csv2sheet asli:
const sheetId = await addEmptySheet(sheetsAPI, sheetName);
const theData = await readCSVContent(sheetsAPI, data, sheetName);
await populateAndStyle(sheetsAPI, theData, sheetId);
Jika Anda memerlukan kode sumber fungsi lengkap, kode tersebut tersedia di sini (mungkin lebih mudah untuk mendapatkan semuanya dalam satu set).
Setelah semuanya siap, cukup upload file CSV ke bucket yang tepat dan lihat spreadsheet Anda diperbarui dengan sheet baru yang berisi konten file. Berikut contoh file CSV jika Anda belum memilikinya.

Coba upload beberapa file ke bucket untuk melihat hasilnya.
11. Selesai! Saatnya menghancurkan infrastruktur
Tidak, tidak ada infrastruktur yang perlu dihentikan, semuanya dilakukan secara serverless.
Jika mau, Anda dapat menghapus Cloud Function dan bucket yang telah dibuat, atau bahkan seluruh project.
12. Apa langkah selanjutnya?
Dengan demikian, codelab ini telah memandu Anda melalui langkah-langkah untuk memproses upload ke bucket Cloud Storage di Cloud Function guna memperbarui Spreadsheet Google menggunakan API yang sesuai.
Berikut adalah beberapa langkah tindak lanjut:
- Lihat panduan cara kerja Cloud Functions (mencakup beberapa praktik terbaik)
- Pelajari salah satu tutorial Cloud Functions
- Pelajari lebih lanjut Google Sheets API
Jika Anda mengalami masalah dengan codelab ini, jangan ragu untuk melaporkan masalah tersebut menggunakan link di pojok kiri bawah.
Masukan Anda sangat kami hargai.