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

1. Giriş

Bu codelab'in amacı, Cloud Storage'a yüklenen bir CSV dosyasına tepki vermek amacıyla Cloud Functions işlevi yazmayı, bu dosyanın içeriğini okumayı ve E-Tablolar API'yi kullanarak bir Google E-Tablosunu güncellemek için kullanmayı öğrenmenizi sağlamaktır.

e9c78061022a6760.png

Bu, aksi takdirde manuel olarak yapılan bir "CSV olarak içe aktarma" işleminin otomasyonu olarak görülebilir. adımına geçelim. Bu sayede, bir e-tablodaki verileri (başka bir ekip tarafından oluşturulmuş olabilir) en kısa sürede analiz edebilirsiniz.

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

52df703605ae4bd3.png

2. Kurulum ve Gereksinimler

Kendi hızınızda ortam kurulumu

  1. Cloud Console'da oturum açıp 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

Tüm Google Cloud projelerinde benzersiz bir ad olan proje kimliğini unutmayın (yukarıdaki ad zaten alınmış ve size uygun olmayacaktır!). Bu kod laboratuvarın ilerleyen bölümlerinde PROJECT_ID olarak adlandırılacaktır.

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

Bu codelab'i çalıştırmanın maliyeti, yüksek değildir. "Temizleme" bölümündeki talimatları izlediğinizden emin olun. bölümünde, bu eğiticinin dışında faturalandırmayla karşılaşmamanız için kaynakları nasıl kapatacağınız konusunda tavsiyelerde bulunuyoruz. Yeni Google Cloud kullanıcıları 300 ABD doları ücretsiz deneme programından yararlanabilir.

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

İlk olarak 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 değişken, yazacağımız fonksiyon için bir ortam değişkeni olarak kullanılır :

dd77d5fc1364ad3e.png

GCP konsolunda "API'ler ve Hizmetler" bölümüne giderek yeni oluşturulan projenizde Google Sheets API'yi etkinleştirin ve "API Kitaplığı" bölüm :

c64e2e98b8b55f16.png

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

6e279d7e07d4febf.png

Son olarak, "Paylaş" düğmesini kullanarak bu hizmet hesabına e-tablonuz için düzenleme ayrıcalıkları vermeniz yeterlidir düğme :

c334062465ddf928.png

Bu kurulumla artık Cloud Functions işlevimizi yazabilir ve bu hizmet hesabını kullanacak şekilde yapılandırmasını sağlayabiliriz. Yeni oluşturduğumuz e-tablo dokümanına yazabilecek.

4. Storage paketi oluşturma

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

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

2ddcb54423979d25.png

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

dd637080ade62e81.png

5. Cloud Functions işlevini oluşturma

Artık belirli bir Cloud Storage paketine dosya yüklendiğinde tetiklenen csv2sheet adlı bir Cloud Functions işlevi oluşturabiliriz. Kod, doğrudan Cloud Console'daki satır içi düzenleyici kullanılarak eş zamansız işlevlerle Node.js 8'e yazılır :

6ee1a5ce63174ae8.png

Tetikleyiciyi "Cloud Storage" olarak ayarladığınızdan emin olun ve paket adını önceki adımda oluşturduğunuz ada ayarlayın.

csv2sheet alanına yazmak üzere olduğumuz işlevin giriş noktasını da güncelleyin :

446e7c7c992c2d8a.png

Şimdi, fonksiyon 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 öğesini tutun ve oluşturacağımız yeni sayfa için bir ad elde edin :
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!
};

await kullanılabilmesi için burada async kullanılması gereklidir.

Bu işlevi oluştururken yararlanabileceğiniz bazı önemli seçenekler şunlardır (ekranın altındaki "Diğer" bağlantısını tıklayın) :

  • Yukarıda açıklanan hizmet hesabını seçmek için açılır menüyü kullanın
  • Daha önce oluşturduğunuz sayfa belgesiyle eşleşmesi gereken, SPREADSHEET_ID adında bir ortam değişkeni tanımlayın :

fd22d1873bcb8c66.png

Son kurulum adımı olarak kullanacağımız iki bağımlı olarak Cloud Storage ve Google Sheet API'lerine sahip package.json içeriğini aşağıda bulabilirsiniz (konsolun satır içi düzenleyicisi 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ığı gibi yapılandırdıktan sonra "Oluştur"u tıklayın. ! Kısa bir süre sonra işleviniz oluşturulup dağıtılacaktır.

6. Kimlik doğrulama ve Sheets API kurulumu

Satır içi düzenleyiciyi kullanarak Cloud işlevimizde başka bir kod yazmadan önce, uygun Storage ve E-Tablolar kapsamlarına sahip 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 fonksiyonunuzun 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. E-Tablolar API'sini kullanarak boş bir sayfa oluşturma

E-Tablolar API istemcisiyle dokümanımızda basit bir yeni sayfa oluşturabiliriz ancak ilerlemeye devam etmeden önce sözlükle ilgili kısa bir not düşelim:

  • e-tablo gerçek dokümandır ve tanımlayıcısı tarafından referans verilir (yukarıda açıklandığı ve doküman URL'sinde görülebilir)
  • sayfa, dokümandaki sekmelerden biridir ve adıyla (sekme adı) veya sayfa oluşturulduktan sonra oluşturulan bir tanımlayıcıyla referans verilebilir.

Bunu göz önünde bulundurarak, E-Tablolar API istemcisini kullanarak 2. konumda boş bir sayfa (genellikle varsayılan "Sheet1"den sonra), 26 sütunlu ve 2.000 satırlık bir sayfa oluşturur ve ilk satır dondurulmuş olarak (satır içi düzenleyiciyi kullanarak işlevinize ekleyebilirsiniz) :

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 olarak kodlamak yerine daha önce oluşturulan SPREADSHEET_ID ortam değişkeninden nasıl yararlandığımıza dikkat edin.

Bu sayfaya yapılacak diğer istekler için sheetId öğesini hatırlamamız gerekir. Ayrıca, sayfa adının benzersiz olması gerekir. sheetName adında bir sayfa zaten varsa oluşturma işlemi başarısız olur.

Sheets API'deki batchUpdate işlevi, belgelerle etkileşim kurmak için yaygın olarak kullanılan bir yöntemdir ve burada açıklanmıştır.

8. Depolama alanı CSV dosyasından veri okuma

Artık verilerimizi döküm alanımız olduğuna göre satır içi düzenleyicide Cloud Functions işlevimizi daha da geliştirelim ve az önce yüklenen dosyadaki gerçek verileri alıp bir dizede depolamak için Cloud Storage API'yi kullanalı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 e-tabloyu doldur

Şimdi sıra, aynı Sheet Client API'yi ve az önce topladığımız verileri kullanarak oluşturduğumuz e-tabloyu doldurmaya geldi. Bu fırsatı değerlendirerek e-tablo sütunlarına da bazı stil özellikleri ekleme (üst satırın yazı tipi boyutunu değiştirme ve kalın hale getirme) yapacağı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, %99 oranında tamamlanmış olan Cloud işlevimize eklenmelidir.

Hem veri hem de stilin tek bir E-Tablolar API'si batchUpdate çağrısında birden fazla requests halinde nasıl birleştirildiğine dikkat edin. Bu da daha verimli ve atomik bir güncelleme yapılmasını sağlar.

Oluşturduğumuz sayfanın boyutuyla eşleşen bir düzenleme aralığı tanımladığımızı da unutmayın. Bu, 26 sütunu (sayfayı oluştururken kullanılan columnCount değeri) aşan içeriğin, söz konusu kodla başarısız olacağı anlamına gelir.

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

  1. güncellenen işlevi kaydedin
  2. pakete CSV dosyası bırakma
  3. ilgili veri pop-up'ını e-tablonuzda görebilirsiniz!

10. Her şeyi bir araya getirmek ve akışı test etmek

Az önce açıkladığımız işlevlere yapılan çağrılar, orijinal csv2sheet işlevinde arka arkaya engelleme çağrıları olarak yapılabilir:

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

İşlevsel kaynak kodunun tamamına ihtiyacınız varsa buradan edinebilirsiniz (büyük olasılıkla hepsini tek bir grupta toplamak daha kolaydır).

Her şey tamamlandığında, doğru pakete bir CSV dosyası yükleyin ve e-tablonuzun dosya içeriğini içeren yeni bir sayfayla güncellendiğini izleyin. Elinizde hazır değilse örnek CSV dosyasını burada bulabilirsiniz.

1efae021942e64fa.png

Ne olduğunu görmek için pakete birkaç dosya yüklemeyi deneyin.

11. İşte bu kadar. Altyapıyı yıkma zamanı

Şaka şaka, yıkılacak bir altyapı yok, tüm bunlar sunucusuz olarak yapıldı !

Dilerseniz bulut işlevini ve oluşturduğunuz paketi, hatta projenin tamamını silebilirsiniz.

12. Sırada ne var?

Böylece, uygun API'yi kullanarak bir Google E-Tablosu'nu güncellemek için Cloud Functions işlevindeki bir Cloud Storage paketine yapılan yüklemeleri dinlemeyle ilgili adımların anlatıldığı bu codelab'in sonuna gelmiş bulunuyoruz.

Aşağıda bazı takip adımları verilmiştir :

Bu codelab'de sorunlarla karşılaştıysanız sol alt köşedeki bağlantıyı kullanarak sorunları bildirebilirsiniz.

Geri bildirimleriniz bizim için çok değerli.