CSV verilerinin Google E-Tablolar'a aktarılmasını otomatikleştiren Cloud Functions işlevi

1. Giriş

Bu codelab'in amacı, Cloud Functions işlevi yazarak Cloud Storage'a yüklenen bir CSV dosyasına nasıl yanıt vereceğinizi, içeriğini nasıl okuyacağınızı ve Sheets API'yi kullanarak bir Google E-Tablosu'nu güncellemek için nasıl kullanacağınızı anlamanızı sağlamaktır.

e9c78061022a6760.png

Bu, aksi takdirde manuel olarak gerçekleştirilecek "CSV olarak içe aktar" adımının otomasyonu olarak görülebilir. Bu sayede, başka bir ekip tarafından oluşturulmuş olabilecek verileri kullanılabilir hale gelir gelmez bir e-tabloda analiz edebilirsiniz.

Uygulama şu şekilde görünür :

52df703605ae4bd3.png

2. Kurulum ve Gereksinimler

Yönlendirmesiz ortam kurulumu

  1. Cloud Console'da oturum açın ve yeni bir proje oluşturun veya mevcut bir projeyi yeniden kullanın. (Gmail veya G Suite hesabınız yoksa hesap oluşturmanız gerekir.)

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

Proje kimliğini unutmayın. Bu kimlik, tüm Google Cloud projelerinde benzersiz bir addır (Yukarıdaki ad zaten alınmış olduğundan sizin için çalışmayacaktır). Bu codelab'in ilerleyen kısımlarında PROJECT_ID olarak adlandırılacaktır.

  1. Ardından, Google Cloud kaynaklarını kullanmak için Cloud Console'da faturalandırmayı etkinleştirmeniz gerekir.

Bu codelab'i tamamlamak neredeyse hiç maliyetli değildir. Bu eğitimin ötesinde faturalandırma ücreti alınmaması için kaynakları nasıl kapatacağınız konusunda size tavsiyelerde bulunan "Temizleme" bölümündeki talimatları uyguladığınızdan emin olun. Google Cloud'un yeni kullanıcıları 300 ABD doları değerinde ücretsiz deneme programından yararlanabilir.

3. Google E-Tablosu oluşturma ve yapılandırma, API'yi etkinleştirme

Öncelikle yeni bir E-Tablolar dokümanı oluşturalım (bu sayfa herhangi bir kullanıcıya ait olabilir). Oluşturduktan sonra tanımlayıcısını unutmayın. Bu tanımlayıcı, yazacağımız işlev için ortam değişkeni olarak kullanılacaktır :

dd77d5fc1364ad3e.png

GCP konsolunda, "API'ler ve Hizmetler" bölümüne, ardından "API Kitaplığı" bölümüne giderek yeni oluşturduğunuz projede Google E-Tablolar API'sini etkinleştirin :

c64e2e98b8b55f16.png

"IAM ve yönetici" bölümünde "Hizmet hesapları"na gidin ve App Engine varsayılan hizmet hesabının e-posta adresini not edin. your-project-id@appspot.gserviceaccount.com biçiminde olmalıdır. Elbette bu işleme özel kendi hizmet hesabınızı da oluşturabilirsiniz.

6e279d7e07d4febf.png

Son olarak, "Paylaş" düğmesini kullanarak bu hizmet hesabına e-tablonuzda düzenleme ayrıcalıkları verin :

c334062465ddf928.png

Bu kurulumla artık Cloud Function'ımızı yazabilir ve bu hizmet hesabını kullanacak şekilde yapılandırabiliriz. Bu e-tablo dokümanına yazabilir.

4. Storage paketi oluşturma

Cloud işlevimizin yeni CSV dosyaları için izleyeceği paketi oluşturalım.

Konsolda, soldaki menüyü kullanarak "Depolama"ya gidin... :

2ddcb54423979d25.png

... ve diğer tüm ayarlar varsayılan değerlerine ayarlanmış şekilde csv2sheet-POSTFIX (POSTFIX'i benzersiz bir şeyle değiştirin) adlı yeni bir paket oluşturun :

dd637080ade62e81.png

5. Cloud Functions işlevini oluşturma

Artık belirli bir Cloud Storage paketine yapılan dosya yüklemelerinde tetiklenen csv2sheet adlı bir Cloud Function oluşturabiliriz. Kod, doğrudan Cloud Console'daki satır içi düzenleyici kullanılarak async işlevleriyle Node.js 8'de yazılacaktır :

6ee1a5ce63174ae8.png

Tetikleyici'yi"Cloud Storage" olarak ayarladığınızdan ve paket adını önceki adımda oluşturduğunuz adla eşleştirdiğinizden emin olun.

Ayrıca, yazacağımız işlevin giriş noktasını csv2sheet olarak güncelleyin :

446e7c7c992c2d8a.png

Şimdi işlev gövdesini şu şekilde değiştirin :

  1. Cloud Storage ve E-Tablolar API'lerini kullanma
  2. csv2sheet işlevini async olarak işaretleyin.
  3. Cloud Storage etkinlik meta verilerinden fileName değerini alın ve oluşturacağımız yeni sayfa için bir ad türetin :
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!
};

Biraz sonra göreceğimiz gibi, await öğesini kullanmak için burada async öğesinin kullanılması gerekir.

Bu işlevi oluştururken kullanabileceğiniz birkaç önemli seçenek şunlardır (ekranın alt kısmındaki "Diğer" bağlantısını tıklayın) :

  • Açılır menüyü kullanarak yukarıda bahsedilen hizmet hesabını seçin.
  • Daha önce oluşturduğunuz e-tablo dokümanıyla eşleşmesi gereken SPREADSHEET_ID adlı bir ortam değişkeni tanımlayın :

fd22d1873bcb8c66.png

Son kurulum adımı olarak, kullanacağımız iki bağımlılık olan Cloud Storage ve Google E-Tablolar API'lerini içeren package.json içeriğini aşağıda bulabilirsiniz (konsolun satır içi düzenleyicisindeki PACKAGE.JSON sekmesini kullanın) :

{
    "name": "csv2sheet",
    "version": "0.0.42",
    "dependencies": {
        "googleapis": "^51.0.0",
        "@google-cloud/storage": "^5.0.1"
    }
}

Her şeyi açıklandığı şekilde yapılandırdıktan sonra "Oluştur"u tıklayın. İşleviniz kısa bir süre içinde oluşturulup dağıtılır.

6. Kimlik doğrulama ve Sheets API'yi ayarlama

Satır içi düzenleyiciyi kullanarak Cloud işlevimizde başka kod yazmadan önce uygun Storage ve Sheet kapsamlarıyla bir Google Client API oluşturulmasını engellememiz gerekir (bunun bir async işlevinin parçası olduğunu unutmayın).

Konsolun işlev düzenleyicisinde "DÜZENLE"yi tıklayın ve csv2sheet işlevinizin gövdesine aşağıdaki kodu ekleyin :

// 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"
  ]
});

Buradan bir Sheets API istemcisi oluşturabiliriz :

const sheetsAPI = google.sheets({version: 'v4', auth});

7. Boş bir sayfa oluşturmak için Sheets API'yi kullanma

E-Tablolar API istemcisiyle dokümanımızda basit bir yeni sayfa oluşturabiliriz. Ancak devam etmeden önce kelime dağarcığıyla ilgili kısa bir not:

  • E-tablo, gerçek dokümandır ve tanımlayıcısıyla (yukarıda bahsedilmiş olup doküman URL'sinde görünür) referans verilir.
  • Sayfa, dokümandaki sekmelerden biridir ve adına (sekme adı) veya sayfa oluşturulurken oluşturulan bir tanımlayıcıya göre referans verilebilir.

Bu nedenle, 2. konumda (genellikle varsayılan "Sayfa1"den sonra) 26 sütun ve 2.000 satır içeren, ilk satırı dondurulmuş boş bir sayfa oluşturmak için Sheets API istemcisini kullanan bir işlev aşağıda verilmiştir (satır içi düzenleyiciyi kullanarak işlevinize ekleyin) :

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);
        }
      }
    );
  });
}

E-tabloya referansı sabit kodlamak yerine, daha önce oluşturulan SPREADSHEET_ID ortam değişkenini kullandığımıza dikkat edin.

Bu belirli sayfaya yapılan sonraki istekler için sheetId hatırlamamız gerekir. Ayrıca, sayfa adı benzersiz olmalıdır. sheetName adlı bir sayfa zaten varsa oluşturma işlemi başarısız olur.

E-Tablolar API'sindeki batchUpdate işlevi, dokümanlarla etkileşim kurmanın yaygın bir yoludur ve burada açıklanmıştır.

8. Verileri depolama CSV dosyasından okuma

Verilerimizi boşaltabileceğimiz bir yer olduğuna göre, satır içi düzenleyicide bulut işlevimizi daha da geliştirelim ve Cloud Storage API'yi kullanarak yeni yüklenen dosyadan gerçek verileri alıp bir dizede saklayalım:

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. Yeni oluşturulan sayfayı doldurma

Şimdi, aynı Sheet istemci API'sini ve az önce topladığımız verileri kullanarak oluşturduğumuz sayfayı doldurma zamanı. Bu fırsattan yararlanarak, sayfanın sütunlarına stil ekleyeceğiz (üst satırın yazı tipi boyutunu değiştirip kalınlaştıracağız) :

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();
      }
    });    
  });
}

Bu kod, şu anda% 99'u tamamlanmış olan Cloud Functions işlevimize eklenmelidir.

Hem verilerin hem de stilin birden fazla requests olarak tek bir Sheets API batchUpdate çağrısında nasıl birleştirildiğine dikkat edin. Bu sayede daha verimli ve atomik bir güncelleme yapılır.

Ayrıca, oluşturduğumuz sayfanın boyutuna uygun bir düzenleme aralığı tanımladığımızı da unutmayın. Bu, 26 sütunu aşan içeriklerin (sayfa oluşturulurken kullanılan columnCount değeri) bu kodla başarısız olacağı anlamına gelir.

Her şey yolunda giderse bu noktada şunları yapabilirsiniz:

  1. güncellenen işlevi kaydetme
  2. CSV dosyasını pakete bırakın
  3. E-tablonuzda ilgili verilerin görünmesini sağlayabilirsiniz.

10. Tüm bilgileri bir araya getirme ve akışı test etme

Az önce bahsettiğimiz işlevlere yapılan çağrılar, orijinal csv2sheet işlevinde birbirini engelleyen ardışık çağrılar olarak yapılabilir:

  const sheetId = await addEmptySheet(sheetsAPI, sheetName);
  const theData = await readCSVContent(sheetsAPI, data, sheetName);
  await populateAndStyle(sheetsAPI, theData, sheetId);

İşlevin kaynak kodunun tamamına ihtiyacınız varsa buradan erişebilirsiniz (muhtemelen hepsini tek bir sette almak daha kolaydır).

Her şey hazır olduğunda, CSV dosyasını doğru pakete yüklemeniz yeterlidir. E-tablonuz, dosyanın içeriğini içeren yeni bir sayfayla güncellenir. Elinizde yoksa örnek bir CSV dosyası.

1efae021942e64fa.png

Neler olacağını görmek için pakete birkaç dosya yüklemeyi deneyin.

11. İşte bu kadar. Altyapıyı kaldırma zamanı

Şaka yapıyorum, yıkılacak bir altyapı yok. Her şey sunucusuz olarak yapıldı.

İsterseniz oluşturduğunuz Cloud Function'ı ve paketi, hatta projenin tamamını silebilirsiniz.

12. Sırada ne var?

Bu codelab'de, uygun API'yi kullanarak bir Google E-Tablosu'nu güncellemek için Cloud Function'da Cloud Storage paketine yapılan yüklemeleri dinleme adımları açıklanmıştır.

Buradan sonra aşağıdaki adımlarla devam edebilirsiniz :

Bu codelab ile ilgili sorun yaşadıysanız sol alt köşedeki bağlantıyı kullanarak sorunları bildirebilirsiniz.

Geri bildiriminiz bizim için önemli.