n8n
Google Sheets
Automation
Spreadsheet
Data
Workflow

Automate Google Sheets ด้วย n8n: คู่มือฉบับสมบูรณ์

เรียนรู้วิธี Automate Google Sheets ด้วย n8n ตั้งแต่พื้นฐานจนถึงขั้นสูง พร้อมตัวอย่าง Workflow สำหรับ Lead Management และ Reporting

AI Unlocked Team
26/01/2568
Automate Google Sheets ด้วย n8n: คู่มือฉบับสมบูรณ์

Automate Google Sheets ด้วย n8n: คู่มือฉบับสมบูรณ์

Google Sheets เป็นเครื่องมือที่หลายองค์กรใช้เก็บข้อมูลและจัดการงาน เมื่อรวมกับ n8n คุณสามารถทำให้ทุกอย่างเป็นอัตโนมัติได้ ไม่ว่าจะเป็นการรับ Lead, สร้าง Report, หรือ Sync ข้อมูลระหว่างระบบ

สารบัญ

  1. การตั้งค่า Google Sheets Credentials
  2. Operations พื้นฐาน
  3. Workflow: Lead Capture
  4. Workflow: Daily Report
  5. Workflow: Data Sync
  6. Workflow: Inventory Alert
  7. Advanced Techniques
  8. Best Practices

การตั้งค่า Credentials

วิธีที่ 1: OAuth2 (แนะนำ)

ขั้นตอนที่ 1: สร้าง Google Cloud Project

  1. ไปที่ console.cloud.google.com
  2. สร้าง Project ใหม่
  3. เปิดใช้ Google Sheets API
    • APIs & Services → Enable APIs
    • ค้นหา "Google Sheets API"
    • คลิก Enable

ขั้นตอนที่ 2: สร้าง OAuth Credentials

  1. APIs & Services → Credentials
  2. Create Credentials → OAuth Client ID
  3. Application type: Web application
  4. Authorized redirect URIs: เพิ่ม URL จาก n8n
{
  "redirect_uri_format": "https://your-n8n.com/rest/oauth2-credential/callback"
}

ขั้นตอนที่ 3: เพิ่มใน n8n

  1. Credentials → Add Credential
  2. ค้นหา "Google Sheets OAuth2 API"
  3. ใส่ Client ID และ Client Secret
  4. คลิก Sign in with Google

วิธีที่ 2: Service Account

สำหรับการใช้งานที่ไม่ต้องการ User Interaction

{
  "service_account_setup": {
    "step_1": "สร้าง Service Account ใน Google Cloud",
    "step_2": "ดาวน์โหลด JSON key",
    "step_3": "Share Sheet กับ Service Account email",
    "step_4": "ใส่ JSON key ใน n8n Credentials"
  }
}

Operations พื้นฐาน

Google Sheets Node Operations

OperationDescription
Appendเพิ่มแถวใหม่
Clearล้างข้อมูลใน Range
Createสร้าง Spreadsheet ใหม่
Deleteลบแถว
Readอ่านข้อมูล
Updateอัปเดตแถวที่มีอยู่
Get Allดึงข้อมูลทั้งหมด
Lookupค้นหาแถวตามเงื่อนไข

ตัวอย่าง: Append Row

{
  "parameters": {
    "operation": "append",
    "documentId": "your-spreadsheet-id",
    "sheetName": "Sheet1",
    "columns": {
      "mappingMode": "defineBelow",
      "value": {
        "Name": "={{ $json.name }}",
        "Email": "={{ $json.email }}",
        "Date": "={{ new Date().toLocaleDateString('th-TH') }}"
      }
    }
  }
}

ตัวอย่าง: Read Rows

{
  "parameters": {
    "operation": "read",
    "documentId": "your-spreadsheet-id",
    "sheetName": "Sheet1",
    "range": "A:D",
    "options": {
      "rawData": false
    }
  }
}

Workflow 1: Lead Capture

สถานการณ์

เมื่อมีคนกรอกฟอร์มบนเว็บไซต์ → บันทึกลง Google Sheets → แจ้งเตือนทีมขาย

Workflow Structure

Webhook → Validate → Google Sheets → Slack → Response

JSON Workflow

{
  "name": "Lead Capture to Sheets",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "lead-form",
        "responseMode": "responseNode"
      },
      "name": "Form Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [250, 300]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.email }}",
              "operation": "isNotEmpty"
            },
            {
              "value1": "={{ $json.name }}",
              "operation": "isNotEmpty"
            }
          ]
        }
      },
      "name": "Validate Data",
      "type": "n8n-nodes-base.if",
      "position": [450, 300]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": "your-sheet-id",
        "sheetName": "Leads",
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Name": "={{ $json.name }}",
            "Email": "={{ $json.email }}",
            "Phone": "={{ $json.phone || 'N/A' }}",
            "Company": "={{ $json.company || 'N/A' }}",
            "Source": "={{ $json.source || 'Website' }}",
            "Date": "={{ new Date().toISOString() }}",
            "Status": "New"
          }
        }
      },
      "name": "Save to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [650, 200]
    },
    {
      "parameters": {
        "channel": "#sales-leads",
        "text": "=*New Lead!*\n\nName: {{ $json.name }}\nEmail: {{ $json.email }}\nCompany: {{ $json.company || 'N/A' }}\n\n<https://docs.google.com/spreadsheets/d/your-sheet-id|View in Sheets>",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "name": "Notify Slack",
      "type": "n8n-nodes-base.slack",
      "position": [850, 200]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: true, message: 'Thank you for your submission!' }) }}"
      },
      "name": "Success Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [1050, 200]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: false, message: 'Please fill in required fields' }) }}",
        "options": {
          "responseCode": 400
        }
      },
      "name": "Error Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [650, 400]
    }
  ],
  "connections": {
    "Form Webhook": {
      "main": [[{"node": "Validate Data"}]]
    },
    "Validate Data": {
      "main": [
        [{"node": "Save to Sheets"}],
        [{"node": "Error Response"}]
      ]
    },
    "Save to Sheets": {
      "main": [[{"node": "Notify Slack"}]]
    },
    "Notify Slack": {
      "main": [[{"node": "Success Response"}]]
    }
  }
}

ทดสอบ Workflow

curl -X POST \
  http://localhost:5678/webhook/lead-form \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "john@example.com",
    "phone": "0891234567",
    "company": "ABC Corp",
    "source": "Google Ads"
  }'

อ่านเพิ่มเติมเกี่ยวกับ Webhooks: Webhook Triggers ใน n8n

Workflow 2: Daily Report

สถานการณ์

ทุกวันเช้า 8:00 น. → ดึงข้อมูลจาก Sheet → สรุปด้วย AI → ส่งรายงานไป Email

JSON Workflow

{
  "name": "Daily Sales Report",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 1-5"
            }
          ]
        }
      },
      "name": "Every Weekday 8AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [250, 300]
    },
    {
      "parameters": {
        "operation": "read",
        "documentId": "your-sheet-id",
        "sheetName": "Sales",
        "range": "A:F",
        "options": {
          "rawData": false
        }
      },
      "name": "Get Sales Data",
      "type": "n8n-nodes-base.googleSheets",
      "position": [450, 300]
    },
    {
      "parameters": {
        "jsCode": "const data = items;\nconst today = new Date();\nconst yesterday = new Date(today);\nyesterday.setDate(yesterday.getDate() - 1);\nconst yesterdayStr = yesterday.toISOString().split('T')[0];\n\nconst yesterdaySales = data.filter(item => \n  item.json.Date && item.json.Date.startsWith(yesterdayStr)\n);\n\nconst totalSales = yesterdaySales.reduce((sum, item) => \n  sum + (parseFloat(item.json.Amount) || 0), 0\n);\n\nconst orderCount = yesterdaySales.length;\n\nreturn [{\n  json: {\n    date: yesterdayStr,\n    totalSales: totalSales.toFixed(2),\n    orderCount: orderCount,\n    averageOrder: orderCount > 0 ? (totalSales / orderCount).toFixed(2) : 0,\n    rawData: yesterdaySales.map(s => s.json)\n  }\n}];"
      },
      "name": "Calculate Summary",
      "type": "n8n-nodes-base.code",
      "position": [650, 300]
    },
    {
      "parameters": {
        "model": "gpt-4-turbo-preview",
        "messages": {
          "values": [
            {
              "role": "user",
              "content": "=สร้างสรุปรายงานยอดขายประจำวัน:\n\nวันที่: {{ $json.date }}\nยอดขายรวม: {{ $json.totalSales }} บาท\nจำนวนออเดอร์: {{ $json.orderCount }}\nออเดอร์เฉลี่ย: {{ $json.averageOrder }} บาท\n\nสรุปเป็นภาษาไทย กระชับ 2-3 ประโยค พร้อมข้อเสนอแนะ"
            }
          ]
        }
      },
      "name": "AI Summary",
      "type": "n8n-nodes-base.openAi",
      "position": [850, 300]
    },
    {
      "parameters": {
        "fromEmail": "reports@yourcompany.com",
        "toEmail": "team@yourcompany.com",
        "subject": "=Daily Sales Report - {{ $node['Calculate Summary'].json.date }}",
        "html": "=<h2>รายงานยอดขายประจำวัน</h2>\n<p><strong>วันที่:</strong> {{ $node['Calculate Summary'].json.date }}</p>\n<p><strong>ยอดขายรวม:</strong> {{ $node['Calculate Summary'].json.totalSales }} บาท</p>\n<p><strong>จำนวนออเดอร์:</strong> {{ $node['Calculate Summary'].json.orderCount }}</p>\n<p><strong>ออเดอร์เฉลี่ย:</strong> {{ $node['Calculate Summary'].json.averageOrder }} บาท</p>\n<hr>\n<h3>AI Summary:</h3>\n<p>{{ $json.message.content }}</p>"
      },
      "name": "Send Email",
      "type": "n8n-nodes-base.emailSend",
      "position": [1050, 300]
    }
  ],
  "connections": {
    "Every Weekday 8AM": {
      "main": [[{"node": "Get Sales Data"}]]
    },
    "Get Sales Data": {
      "main": [[{"node": "Calculate Summary"}]]
    },
    "Calculate Summary": {
      "main": [[{"node": "AI Summary"}]]
    },
    "AI Summary": {
      "main": [[{"node": "Send Email"}]]
    }
  }
}

เรียนรู้เพิ่มเติมเกี่ยวกับ AI: เชื่อมต่อ n8n กับ AI

Workflow 3: Data Sync

สถานการณ์

Sync ข้อมูลระหว่าง Google Sheets กับ CRM

Two-Way Sync Strategy

{
  "sync_strategy": {
    "sheets_to_crm": "ทุก 15 นาที ดึง New/Updated rows จาก Sheets → สร้าง/อัปเดต CRM",
    "crm_to_sheets": "ทุก 15 นาที ดึง New/Updated records จาก CRM → อัปเดต Sheets",
    "conflict_resolution": "ใช้ Last Modified timestamp"
  }
}

JSON Workflow (Sheets to CRM)

{
  "name": "Sheets to CRM Sync",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [{"field": "minutes", "minutesInterval": 15}]
        }
      },
      "name": "Every 15 Minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [250, 300]
    },
    {
      "parameters": {
        "operation": "read",
        "documentId": "your-sheet-id",
        "sheetName": "Contacts",
        "options": {}
      },
      "name": "Read Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [450, 300]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.SyncStatus }}",
              "operation": "notEqual",
              "value2": "Synced"
            }
          ]
        }
      },
      "name": "Filter Unsynced",
      "type": "n8n-nodes-base.if",
      "position": [650, 300]
    },
    {
      "parameters": {
        "resource": "contact",
        "operation": "upsert",
        "email": "={{ $json.Email }}",
        "additionalFields": {
          "firstName": "={{ $json.FirstName }}",
          "lastName": "={{ $json.LastName }}",
          "phone": "={{ $json.Phone }}"
        }
      },
      "name": "Upsert to CRM",
      "type": "n8n-nodes-base.hubspot",
      "position": [850, 200]
    },
    {
      "parameters": {
        "operation": "update",
        "documentId": "your-sheet-id",
        "sheetName": "Contacts",
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "SyncStatus": "Synced",
            "LastSync": "={{ new Date().toISOString() }}"
          }
        },
        "options": {
          "lookupColumn": "Email",
          "lookupValue": "={{ $json.Email }}"
        }
      },
      "name": "Update Sync Status",
      "type": "n8n-nodes-base.googleSheets",
      "position": [1050, 200]
    }
  ]
}

Workflow 4: Inventory Alert

สถานการณ์

ตรวจสอบ Stock ใน Sheet → แจ้งเตือนถ้าต่ำกว่า Threshold

JSON Workflow

{
  "name": "Low Stock Alert",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [{"field": "hours", "hoursInterval": 2}]
        }
      },
      "name": "Every 2 Hours",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [250, 300]
    },
    {
      "parameters": {
        "operation": "read",
        "documentId": "your-inventory-sheet",
        "sheetName": "Inventory"
      },
      "name": "Get Inventory",
      "type": "n8n-nodes-base.googleSheets",
      "position": [450, 300]
    },
    {
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{ parseInt($json.CurrentStock) }}",
              "operation": "smallerEqual",
              "value2": "={{ parseInt($json.MinStock) }}"
            }
          ]
        }
      },
      "name": "Low Stock?",
      "type": "n8n-nodes-base.if",
      "position": [650, 300]
    },
    {
      "parameters": {
        "channel": "#inventory-alerts",
        "text": "=*Low Stock Alert!*\n\nProduct: {{ $json.ProductName }}\nSKU: {{ $json.SKU }}\nCurrent Stock: {{ $json.CurrentStock }}\nMin Stock: {{ $json.MinStock }}\n\nPlease reorder immediately!",
        "additionalFields": {
          "attachments": [
            {
              "color": "#ff0000"
            }
          ]
        }
      },
      "name": "Alert Slack",
      "type": "n8n-nodes-base.slack",
      "position": [850, 200]
    }
  ]
}

Advanced Techniques

1. Batch Operations

เมื่อต้องอัปเดตหลายแถว ใช้ Batch เพื่อประหยัด API Calls:

{
  "parameters": {
    "operation": "update",
    "documentId": "sheet-id",
    "sheetName": "Data",
    "options": {
      "valueInputMode": "RAW"
    },
    "dataMode": "autoMapInputData"
  }
}

2. Dynamic Sheet Selection

// ใช้ Expression เลือก Sheet ตามเดือน
const month = new Date().toLocaleString('default', { month: 'long' });
return `Sales_${month}`;

3. Lookup และ Update

{
  "parameters": {
    "operation": "update",
    "options": {
      "lookupColumn": "ID",
      "lookupValue": "={{ $json.recordId }}"
    }
  }
}

4. การจัดการ Large Data

{
  "large_data_tips": {
    "use_ranges": "อ่านเฉพาะ Range ที่ต้องการ",
    "pagination": "แบ่งอ่านทีละ batch",
    "filter_early": "กรองข้อมูลก่อน process",
    "use_formulas": "ใช้ Sheet Formulas ช่วยคำนวณ"
  }
}

Best Practices

1. Sheet Structure

{
  "recommended_columns": [
    "ID (unique identifier)",
    "CreatedAt",
    "UpdatedAt",
    "SyncStatus",
    "Notes"
  ]
}

2. Error Handling

{
  "error_scenarios": {
    "sheet_not_found": "ตรวจสอบ Sheet ID และ Name",
    "permission_denied": "ตรวจสอบ Share settings",
    "rate_limit": "เพิ่ม delay ระหว่าง requests",
    "invalid_data": "Validate ก่อน append"
  }
}

อ่านเพิ่มเติม: จัดการ Error ใน n8n

3. Performance Tips

  • ใช้ range จำกัดข้อมูลที่อ่าน
  • Cache ข้อมูลที่ไม่เปลี่ยนบ่อย
  • ใช้ Batch operations เมื่อเป็นไปได้
  • หลีกเลี่ยงการอ่าน Sheet บ่อยเกินไป

4. Security

{
  "security_tips": [
    "ใช้ Service Account สำหรับ Production",
    "จำกัด Scope ของ OAuth",
    "อย่าเก็บ Sensitive data ใน Sheets",
    "ตรวจสอบ Share settings เป็นประจำ"
  ]
}

Troubleshooting

ปัญหาที่พบบ่อย

1. "Spreadsheet not found"

{
  "solutions": [
    "ตรวจสอบ Spreadsheet ID ถูกต้อง",
    "ตรวจสอบ Sheet ถูก Share กับ Account",
    "ลอง Re-authorize Credentials"
  ]
}

2. "Request rate limit exceeded"

{
  "solutions": [
    "เพิ่ม Wait Node ระหว่าง requests",
    "ลดความถี่ของ Schedule",
    "ใช้ Batch operations"
  ]
}

3. "Data format errors"

{
  "solutions": [
    "ตรวจสอบ Column names ตรงกับ Sheet",
    "ใช้ rawData: false สำหรับ formatted data",
    "Validate data ก่อน append"
  ]
}

สรุป

Google Sheets + n8n สามารถทำได้:

  • Lead Management: รับและจัดการ Leads อัตโนมัติ
  • Reporting: สร้างรายงานและส่งทุกวัน
  • Data Sync: ซิงค์ข้อมูลระหว่างระบบ
  • Alerts: แจ้งเตือนเมื่อเกิดเงื่อนไข

ขั้นตอนถัดไป

  1. Webhooks: Webhook Triggers ใน n8n
  2. Telegram Bot: สร้าง Telegram Bot
  3. Error Handling: จัดการ Error
  4. Advanced: 5 Advanced Workflows

พร้อม Automate Google Sheets แล้วหรือยัง?

ติดตามบทความเพิ่มเติมและรับคำปรึกษาที่ AI Unlocked


เขียนโดย

AI Unlocked Team