Materi 20: Workflow 1 - Menggabungkan Data (Enrichment)

Di materi ini, kita akan membangun workflow pertama dari tiga workflow yang direncanakan. Tugas workflow ini adalah mengambil data pelanggan dari Airtable dan melengkapinya dengan data geografis dari API eksternal.

Skenario Masalah

Perusahaan Nathan menyimpan data pelanggan di Airtable. Data ini berisi ID, negara, email, dan tanggal bergabung. Namun, data ini kurang lengkap: tidak ada informasi mengenai Region (Wilayah) dan Subregion.

Untuk membuat laporan penjualan regional, kita harus mengisi kekosongan tersebut secara otomatis.

Langkah 1: Persiapan Airtable

Sebelum masuk ke n8n, kita perlu menyiapkan tabel di Airtable.

  1. Buat tabel baru bernama customers.
  2. Buat kolom-kolom berikut (Pastikan penulisan huruf besar/kecil SAMA PERSIS):
    • CustomerID (Number)
    • CustomerCountry (Single line text)
    • email (Email)
    • customerSince (Date) - PENTING: Aktifkan opsi "Include time". Hapus centang "Use same time zone..." jika ada.
    • region (Single line text) - Biarkan kosong.
    • subregion (Single line text) - Biarkan kosong.
Data Sampel (Wajib Copy-Paste):
Salin data di bawah ini dan tempelkan ke dalam tabel Airtable Anda (mulai dari kolom pertama, baris pertama).
CustomerID CustomerCountry email customerSince
1 India customer1@mail.in 12/10/2021
2 Japan customer2@mail.jp 17/6/2021
3 France customer3@mail.com 7/8/2021
4 Brazil customer4@mail.com 29/7/2021
5 Canada customer5@mail.com 6/9/2021
6 Sweden customer6@mail.com 9/9/2021
7 Australia customer7@mail.com 9/8/2021
8 Germany customer8@mail.de 3/10/2021
9 Ukraine customer9@mail.com 13/9/2021
10 Cuba customer10@mail.com 15/6/2021

Langkah 2: Mengambil Data Pelanggan (Airtable)

Sekarang, mari mulai membangun di n8n.

  1. Buat workflow baru.
  2. Tambahkan node Airtable.
  3. Operation: List (atau Get All).
  4. Base: Pilih base latihan Anda.
  5. Table: customers.
  6. Klik Execute Node. Anda akan melihat daftar pelanggan yang belum memiliki region.
Output node Airtable menampilkan daftar pelanggan.

Data awal dari Airtable (Region masih kosong).

Langkah 3: Mengambil Data Negara (HTTP Request)

Kita butuh "kamus" untuk menerjemahkan Negara menjadi Region. Kita akan menggunakan API publik REST Countries.

  1. Tambahkan node HTTP Request (jangan sambungkan ke Airtable dulu, biarkan terpisah atau paralel).
  2. URL: https://restcountries.com/v3.1/all
  3. Method: GET.
  4. Tambahkan Query Parameter agar data tidak terlalu besar:
    • Name: fields
    • Value: name,region,subregion
  5. Klik Execute Node.
Output HTTP Request menampilkan daftar negara dan region.

Data referensi dari REST Countries API.

Langkah 4: Menggabungkan Data (Merge Node)

Sekarang kita punya dua aliran data: Pelanggan (Input 1) dan Negara (Input 2). Kita akan menggabungkannya.

  1. Tambahkan node Merge.
  2. Hubungkan Airtable ke Input 1.
  3. Hubungkan HTTP Request ke Input 2.
  4. Mode: Combine > Merge By Fields.
  5. Fields to Match:
    • Input 1 Field: CustomerCountry (Sesuaikan dengan kolom Airtable Anda).
    • Input 2 Field: name.common (Nama negara di API).
Tips Dot Notation:
Karena struktur data API bersarang (nested) di dalam objek name, kita menulis name.common untuk mengakses nama negaranya.
Konfigurasi Merge Node mencocokkan customerCountry dengan name.common.

Mengawinkan data pelanggan dengan data wilayah.

Langkah 5: Update Airtable

Terakhir, kita simpan data Region dan Subregion yang baru kita dapatkan kembali ke Airtable.

  1. Tambahkan node Airtable baru setelah Merge Node.
  2. Operation: Update.
  3. Table: customers.
  4. Columns to Update (Mapping):
    • region: {{ $json.region }} (dari API)
    • subregion: {{ $json.subregion }} (dari API)
    • customerSince: {{ $json.customerSince }} (Tanggal).
  5. PENTING: Aktifkan "Typecast"
    Scroll ke bagian bawah node Airtable > Options > Klik Add Option > Pilih Typecast > Aktifkan (Toggle ON).
Kenapa harus Typecast?
Format tanggal di n8n (ISO) dan Airtable sering berbeda. Fitur Typecast memaksa Airtable untuk "menerjemahkan" format tanggal apa pun yang kita kirim agar sesuai dengan kolom Date di databasenya. Tanpa ini, akan muncul error!
Detail node dari Airtable Update dengan field region dan subregion.

Detail update Airtable dengan field region dan subregion.

Flow keseluruhan dari workflow 1 (Sub-workflow).

Flow keseluruhan dari workflow 1 (Sub-workflow).

Data akhir region dan subregion telah terisi.

Data akhir dari Airtable setelah update (Region dan Subregion sudah terisi).

Kode Workflow Lengkap (JSON)

Agar lebih mudah dan memastikan konfigurasi (seperti Typecast) benar, Anda bisa menyalin kode di bawah ini dan langsung menempelkannya (Paste/Ctrl+V) ke kanvas n8n Anda.

📄 Klik untuk melihat/menyalin JSON Workflow

{
  "nodes": [
    {
      "parameters": {},
      "id": "2d57f671-b9f7-41ae-9dd0-82bc8175ec6d",
      "name": "When clicking \"Execute workflow\"",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        336,
        336
      ]
    },
    {
      "parameters": {
        "url": "https://restcountries.com/v3.1/all",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "fields",
              "value": "name,region,subregion"
            }
          ]
        },
        "options": {}
      },
      "id": "c40d19b4-7e06-417e-b966-fca062746983",
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        544,
        432
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "N248dgARXFPjXLRA",
          "name": "Header Auth account"
        }
      }
    },
    {
      "parameters": {
        "operation": "search",
        "base": {
          "__rl": true,
          "value": "appzgiK89L202rUE3",
          "mode": "list",
          "cachedResultName": "Beginner Course",
          "cachedResultUrl": "https://airtable.com/appzgiK89L202rUE3"
        },
        "table": {
          "__rl": true,
          "value": "tblmECBN2BZsUHNjX",
          "mode": "list",
          "cachedResultName": "customers",
          "cachedResultUrl": "https://airtable.com/appzgiK89L202rUE3/tblmECBN2BZsUHNjX"
        },
        "options": {}
      },
      "id": "b9d58639-8583-4d3d-9980-adf739a3c011",
      "name": "Airtable",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2,
      "position": [
        544,
        256
      ],
      "credentials": {
        "airtableTokenApi": {
          "id": "xwKF32ZJ0C3iAfpA",
          "name": "Airtable Personal Access Token account"
        }
      }
    },
    {
      "parameters": {
        "operation": "update",
        "base": {
          "__rl": true,
          "value": "appzgiK89L202rUE3",
          "mode": "list",
          "cachedResultName": "Beginner Course",
          "cachedResultUrl": "https://airtable.com/appzgiK89L202rUE3"
        },
        "table": {
          "__rl": true,
          "value": "tblmECBN2BZsUHNjX",
          "mode": "list",
          "cachedResultName": "customers",
          "cachedResultUrl": "https://airtable.com/appzgiK89L202rUE3/tblmECBN2BZsUHNjX"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "customerID": "={{ $json.customerID }}",
            "customerCountry": "={{ $json.customerCountry }}",
            "email": "={{ $json.email }}",
            "customerSince": "={{ $json.customerSince }}",
            "region": "={{ $json.region }}",
            "subregion": "={{ $json.subregion }}"
          },
          "matchingColumns": [
            "customerID"
          ],
          "schema": [
            {
              "id": "id",
              "displayName": "id",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "readOnly": true,
              "removed": false
            },
            {
              "id": "customerID",
              "displayName": "customerID",
              "required": false,
              "defaultMatch": false,
              "canBeUsedToMatch": true,
              "display": true,
              "type": "number",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "customerCountry",
              "displayName": "customerCountry",
              "required": false,
              "defaultMatch": false,
              "canBeUsedToMatch": true,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "email",
              "displayName": "email",
              "required": false,
              "defaultMatch": false,
              "canBeUsedToMatch": true,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "customerSince",
              "displayName": "customerSince",
              "required": false,
              "defaultMatch": false,
              "canBeUsedToMatch": true,
              "display": true,
              "type": "dateTime",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "region",
              "displayName": "region",
              "required": false,
              "defaultMatch": false,
              "canBeUsedToMatch": true,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "subregion",
              "displayName": "subregion",
              "required": false,
              "defaultMatch": false,
              "canBeUsedToMatch": true,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "typecast": true
        }
      },
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.1,
      "position": [
        976,
        336
      ],
      "id": "e00fdad5-8427-4b09-9d1f-9ca4864ebd9a",
      "name": "Update record",
      "credentials": {
        "airtableTokenApi": {
          "id": "xwKF32ZJ0C3iAfpA",
          "name": "Airtable Personal Access Token account"
        }
      }
    },
    {
      "parameters": {
        "mode": "combine",
        "advanced": true,
        "mergeByFields": {
          "values": [
            {
              "field1": "customerCountry",
              "field2": "name.common"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        784,
        336
      ],
      "id": "0365e4c3-258c-47a3-999d-e93ecf17584b",
      "name": "Merge"
    }
  ],
  "connections": {
    "When clicking \"Execute workflow\"": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          },
          {
            "node": "Airtable",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Airtable": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Update record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "a612ce3732177191df67c49cdd165a9944332142dec2e0997de31bff5658a964"
  }
}
              
Catatan Penting:
Setelah menempelkan (Paste) kode ini, node Airtable dan HTTP Request mungkin akan berwarna merah karena ID Credential berbeda.
Silakan buka node tersebut dan pilih kembali Credential milik Anda sendiri di bagian Credential.

Kuis Pemahaman

Coba jawab pertanyaan berikut berdasarkan hasil eksekusi workflow Anda:

❓ Berapa item yang dikembalikan oleh node HTTP Request?

Jumlahnya sekitar 250 item (tergantung jumlah negara yang diakui saat ini di API restcountries).

❓ Berapa item yang dikembalikan oleh Merge Node?

Jumlahnya harus sama dengan jumlah pelanggan di Airtable Anda (karena kita menggunakan mode Keep Matches secara default, dan kita berasumsi semua negara pelanggan valid).

❓ Berapa banyak region unik di tabel customers?

Anda bisa mengeceknya di Airtable setelah update. Biasanya ada region seperti Americas, Europe, Asia, dll.

❓ Apa subregion untuk CustomerID 10?

Untuk CustomerID 10 (Cuba), subregion-nya adalah Caribbean.

Langkah Selanjutnya

Workflow 1 (Sub-workflow) selesai! Data pelanggan kita sekarang sudah kaya dan lengkap.

Selanjutnya, kita akan membangun Workflow 2 (Utama) yang akan memanggil workflow ini, membuat laporan Excel, dan mengirimkannya via email.