Cloud Function untuk Mengotomatiskan impor data CSV ke Google Spreadsheet

1. Pengantar

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

e9c78061022a6760.png

Hal ini dapat dilihat sebagai otomatisasi "impor sebagai CSV" manual langkah waktu ini. Hal ini akan memastikan bahwa Anda dapat menganalisis data (mungkin dihasilkan oleh tim lain) dalam {i>spreadsheet<i} segera setelah tersedia.

Seperti inilah implementasinya :

52df703605ae4bd3.pngS

2. Penyiapan dan Persyaratan

Penyiapan lingkungan mandiri

  1. 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.)

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

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.

  1. 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. Membuat dan mengonfigurasi Spreadsheet Google serta mengaktifkan API

Pertama, mari buat dokumen Spreadsheet baru (sheet ini bisa milik pengguna mana pun). Setelah dibuat, ingat ID-nya; itu akan digunakan sebagai variabel lingkungan untuk fungsi yang akan kita tulis :

dd77d5fc1364ad3e.png

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

c64e2e98b8b55f16.png

Pada menu "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 sendiri yang didedikasikan untuk tindakan ini.

6e279d7e07d4febf.pngS

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

c334062465ddf928.png

Dengan penyiapan ini, kita sekarang dapat menulis Cloud Function dan mengonfigurasinya untuk menggunakan akun layanan ini. Aplikasi ini dapat menulis ke dokumen {i>spreadsheet <i}yang baru saja kita buat.

4. Membuat bucket penyimpanan

Mari kita buat bucket yang akan dipantau oleh fungsi cloud untuk menemukan file CSV baru.

Di konsol, gunakan menu sebelah kiri untuk membuka "Storage"... :

2ddcb54423979d25.png

... dan membuat bucket baru bernama csv2sheet-POSTFIX (ganti POSTFIX dengan sesuatu yang unik) dengan semua setelan lain yang disetel ke nilai defaultnya :

dd637080ade62e81.png

5. Membuat Cloud Function

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

6ee1a5ce63174ae8.pngS

Pastikan untuk menetapkan Pemicu ke "Cloud Storage" dan menyesuaikan nama bucket dengan nama yang telah Anda buat di langkah sebelumnya.

Update juga titik entri untuk fungsi yang akan kita tulis ke csv2sheet :

446e7c7c992c2d8a.pngS

Sekarang ubah isi fungsi menjadi :

  1. menggunakan Cloud Storage dan Sheets API
  2. tandai fungsi csv2sheet sebagai async
  3. mendapatkan fileName dari metadata peristiwa Cloud Storage dan memberi 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 tautan "Lainnya" di bagian bawah layar) :

  • Gunakan menu dropdown untuk memilih akun layanan yang dibahas di atas
  • Tentukan variabel lingkungan bernama SPREADSHEET_ID yang harus cocok dengan dokumen sheet yang telah Anda buat sebelumnya :

fd22d1873bcb8c66.png

Sebagai langkah penyiapan terakhir, berikut adalah konten package.json dengan Cloud Storage dan Google Sheet API sebagai dua dependensi yang akan kita gunakan (gunakan tab editor inline PACKAGE.JSON pada 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 dalam fungsi Cloud menggunakan editor inline, kita harus memblokir pembuatan Google Client API dengan cakupan Storage dan Spreadsheet 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. Menggunakan Sheets API untuk membuat sheet kosong

Dengan klien Sheets API, kita dapat membuat sheet baru yang sederhana dalam dokumen, tetapi sebelum melangkah lebih jauh, berikut catatan singkat tentang kosakata:

  • spreadsheet adalah dokumen aktual dan dirujuk oleh ID-nya (yang dibahas di atas dan dapat dilihat di URL dokumen)
  • sheet adalah salah satu tab dalam dokumen dan dapat dirujuk berdasarkan namanya (nama tab) atau ID yang dihasilkan saat pembuatan sheet

Dengan mengingat hal ini, berikut adalah fungsi yang menggunakan klien Sheets API untuk membuat sheet kosong di posisi 2 (biasanya setelah "Sheet1" default"), dengan 26 kolom, 2000 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 bagaimana alih-alih melakukan hard coding pada referensi ke spreadsheet, kita mengandalkan variabel lingkungan SPREADSHEET_ID yang dibuat sebelumnya.

Kita perlu mengingat sheetId untuk permintaan lebih lanjut yang dibuat pada sheet khusus 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 kita memiliki tempat untuk membuang data, mari kembangkan lebih lanjut fungsi cloud di editor inline dan menggunakan 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 sheet yang telah kita buat menggunakan API klien Sheet yang sama dan data yang baru saja kita kumpulkan. Kita akan mengambil kesempatan ini untuk juga menambahkan beberapa gaya ke kolom lembar (mengubah ukuran font baris teratas 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 akan ditambahkan ke Cloud function kita yang kini 99% selesai.

Perhatikan bagaimana data dan gaya visual digabungkan sebagai beberapa requests menjadi satu panggilan batchUpdate Sheets API. Hal ini membuat update atomik dan lebih efisien.

Perhatikan juga bahwa kita menentukan rentang edit yang sesuai dengan ukuran lembar yang telah kita buat. Artinya, konten yang melebihi 26 kolom (nilai columnCount yang digunakan saat membuat sheet) akan gagal dengan kode khusus ini.

Jika semua berjalan lancar, pada tahap ini Anda dapat:

  1. menyimpan fungsi yang diperbarui
  2. menempatkan file CSV ke dalam bucket
  3. melihat data yang sesuai muncul di {i>spreadsheet<i} Anda!

10. Menggabungkan semuanya dan menguji alurnya

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 sumber 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 tersebut. Berikut contoh file CSV jika Anda tidak memilikinya.

1efae021942e64fa.pngS

Coba upload beberapa file ke bucket untuk melihat apa yang terjadi.

11. Selesai. Saatnya untuk menghancurkan infrastruktur

Bercanda, tidak ada infrastruktur yang perlu dihancurkan. Semuanya dapat dilakukan tanpa server.

Jika ingin, Anda dapat menghapus fungsi cloud dan bucket yang telah dibuat, atau bahkan seluruh project.

12. Apa langkah selanjutnya?

Bagian ini mengakhiri codelab ini untuk memandu Anda melakukan 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:

Jika Anda mengalami masalah dengan codelab ini, jangan ragu untuk melaporkan masalah apa pun menggunakan link di sudut kiri bawah.

Masukan Anda sangat berharga.