Ocriva Logo

Documents

เชื่อมต่อ Google Sheets

บันทึกข้อมูลที่ดึงจากเอกสารลง Google Sheets โดยอัตโนมัติ

integrationsgoogle-sheetsspreadsheetautomation

Published: 4/5/2026

เชื่อมต่อ Google Sheets

เพิ่มข้อมูลที่ดึงได้จากเอกสารลงใน Google Sheet เป็นแถวใหม่โดยอัตโนมัติทุกครั้งที่ Ocriva ประมวลผลเอกสาร การเชื่อมต่อนี้เหมาะอย่างยิ่งสำหรับทีมที่ต้องการบันทึกรายการไฟล์ที่ประมวลผลแล้ว ค่าที่ดึงได้ และ Confidence Score อย่างต่อเนื่อง โดยไม่ต้องสร้าง Backend Infrastructure เพิ่มเติม — Google Apps Script จัดการทุกอย่างได้เองทั้งหมด


สิ่งที่ต้องเตรียม

  • บัญชี Google ที่เข้าถึง Google Drive และ Google Sheets ได้
  • Google Sheet ที่จะใช้เขียนข้อมูล
  • Organization ใน Ocriva ที่มี Webhook Quota เหลืออยู่

หลักการทำงาน

Ocriva ส่ง JSON Payload แบบ Flatten ไปยัง Google Apps Script Web App ที่คุณ Deploy จากภายใน Spreadsheet ของคุณ ฟังก์ชัน Apps Script รับ POST Request แยกวิเคราะห์ Payload และเรียก appendRow() เพื่อเขียนข้อมูลเป็นแถวใหม่ เนื่องจาก Web App URL ถูกสร้างโดย Google และประกอบด้วย String แบบสุ่มขนาดยาว จึงทำหน้าที่เป็น Endpoint ที่ไม่สามารถเดาได้ — ไม่ต้องใช้ Authentication Layer เพิ่มเติม

Ocriva event fires
      |

POST JSON payload → Apps Script web app URL
      |

doPost() parses payload
      |

appendRow() writes data to Google Sheet

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

  1. ไปที่ Google Sheets และสร้าง Spreadsheet ใหม่
  2. ตั้งชื่อให้สื่อความหมาย เช่น Ocriva Document Log
  3. ในแถวที่ 1 เพิ่ม Header ของคอลัมน์ที่ตรงกับข้อมูลที่ต้องการบันทึก:
| Timestamp | Event Type | File Name | Status | Confidence | Extracted Data |

ลำดับของ Header เหล่านี้ต้องตรงกับลำดับที่ Apps Script เขียนข้อมูล (ดูขั้นตอนที่ 2) คุณสามารถเพิ่ม ลบ หรือเรียงลำดับคอลัมน์ใหม่ได้ — เพียงแต่ต้องอัปเดต Script ให้สอดคล้องกัน

TIP

Freeze แถวที่ 1 (View → Freeze → 1 row) เพื่อให้ Header ยังคงมองเห็นได้เมื่อข้อมูลเพิ่มขึ้น คุณสามารถจัดรูปแบบแถว Header เป็นตัวหนาเพื่อให้อ่าน Sheet ได้ง่ายขึ้น


ขั้นตอนที่ 2: สร้าง Apps Script Web App

  1. ใน Google Sheet ของคุณ ไปที่ Extensions → Apps Script
  2. Project Apps Script ใหม่จะเปิดในแท็บเบราว์เซอร์ พร้อมฟังก์ชัน myFunction ว่างเปล่า
  3. ลบโค้ดที่มีอยู่ทั้งหมดแล้วแทนที่ด้วยโค้ดต่อไปนี้:
function doPost(e) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = JSON.parse(e.postData.contents);
 
  sheet.appendRow([
    new Date().toISOString(),          // Timestamp — when the row was written
    data.eventType,                    // e.g. "document.processed"
    data.fileName,                     // Original file name
    data.status,                       // "success" or "failed"
    data.confidence,                   // Confidence score (0–1)
    JSON.stringify(data.extractedData) // Full extracted data as a JSON string
  ]);
 
  return ContentService
    .createTextOutput(JSON.stringify({ success: true }))
    .setMimeType(ContentService.MimeType.JSON);
}

อธิบายแต่ละบรรทัด

บรรทัดวัตถุประสงค์
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()เปิด Sheet ที่ผูกกับ Script นี้และเลือกแท็บแรก (Active)
JSON.parse(e.postData.contents)แยกวิเคราะห์ POST Body แบบดิบที่ Ocriva ส่งมาให้เป็น JavaScript Object
sheet.appendRow([...])เพิ่มแถวใหม่ที่ด้านล่างของข้อมูลที่มีอยู่ทั้งหมด — ไม่เขียนทับข้อมูลเดิม
new Date().toISOString()บันทึกเวลาที่เขียนแถว (เวลา Server) ไม่ใช่เวลาที่ Event เกิดขึ้น
JSON.stringify(data.extractedData)แปลง Object ข้อมูลที่ดึงได้แบบซ้อนชั้นเป็น String ที่อ่านได้ เพื่อบันทึกในเซลล์เดียว
ContentService.createTextOutput(...)ส่งคำตอบ 200 OK แบบ JSON เพื่อให้ Ocriva บันทึก Delivery ว่าสำเร็จ
  1. คลิก Save (ไอคอนแผ่นดิสก์หรือ Ctrl+S) แล้วตั้งชื่อ Project เช่น Ocriva Webhook Receiver

ขั้นตอนที่ 3: Deploy เป็น Web App

  1. ใน Apps Script Editor คลิก Deploy → New deployment
  2. คลิกไอคอน Gear ถัดจาก Type แล้วเลือก Web app
  3. ตั้งค่าการ Deploy:
    • Description: Ocriva webhook receiver (ไม่บังคับ สำหรับบันทึกของคุณ)
    • Execute as: Me — Script รันด้วยสิทธิ์บัญชี Google ของคุณเพื่อเขียน Sheet
    • Who has access: Anyone — จำเป็นเพื่อให้ Server ของ Ocriva เข้าถึง Endpoint ได้โดยไม่ต้อง Authentication
  4. คลิก Deploy
  5. หากระบบขอ ให้คลิก Authorize access และทำตาม OAuth Consent Screen เพื่อให้สิทธิ์ Script แก้ไข Spreadsheet
  6. หลังจาก Authorize Google จะแสดง Web app URL ในรูปแบบ:
https://script.google.com/macros/s/AKfycb.../exec
  1. คลิก Copy ถัดจาก URL — คุณจะนำไปวางใน Ocriva ในขั้นตอนถัดไป

WARNING

การตั้งค่า "Who has access" เป็น Anyone จำเป็นสำหรับการส่ง Webhook ของ Ocriva URL ประกอบด้วย String แบบสุ่มขนาดยาว (AKfycb...) ที่ทำหน้าที่เป็น Shared Secret — เฉพาะผู้ที่มี URL นี้เท่านั้นจึงสามารถ POST ไปยัง Endpoint ได้ ห้ามเผยแพร่ URL นี้หรือ Commit ลง Source Control


ขั้นตอนที่ 4: ตั้งค่าใน Ocriva

  1. ในแดชบอร์ด Ocriva ไปที่ Integrations ในแถบด้านซ้าย
  2. ค้นหาการ์ด Template ของ Google Sheets แล้วคลิก
  3. วาง Apps Script Web App URL ลงในช่อง URL
  4. ใต้ Events เลือก Event ที่ต้องการบันทึก (ค่าเริ่มต้น: document.processed)
  5. ตรวจสอบ Payload Template ที่กรอกไว้ล่วงหน้า — ถูก Flatten แล้วสำหรับการใช้งาน Spreadsheet (ดู Payload Template)
  6. คลิก Create Endpoint

Ocriva จะเริ่มส่ง Event ไปยัง Spreadsheet ของคุณทันที อัปโหลดเอกสารทดสอบเพื่อยืนยันว่ามีแถวใหม่ปรากฏ


Payload Template

Payload Template เริ่มต้นของ Google Sheets จะ Flatten Ocriva Event เป็น Key ระดับบนสุด เพื่อให้ Apps Script เข้าถึงได้โดยตรงโดยไม่ต้องค้นหาแบบซ้อนชั้น:

{
  "eventType": "{{eventType}}",
  "fileName": "{{payload.fileName}}",
  "status": "{{payload.status}}",
  "extractedData": "{{payload.extractedData}}",
  "processedAt": "{{payload.processedAt}}",
  "confidence": "{{payload.confidence}}"
}

อ้างอิง Variable

Variableคำอธิบายตัวอย่าง
{{eventType}}Event ที่เกิดขึ้นdocument.processed
{{payload.fileName}}ชื่อไฟล์ต้นฉบับinvoice-2026-03.pdf
{{payload.status}}ผลการประมวลผลsuccess หรือ failed
{{payload.extractedData}}Object ที่ประกอบด้วย Field ที่ AI ดึงได้{"total": "1200", "vendor": "Acme"}
{{payload.processedAt}}Timestamp แบบ ISO 8601 จาก API2026-04-05T09:30:00Z
{{payload.confidence}}ค่า Confidence ของ Model0.94

โครงสร้างแบบ Flat นี้ทำให้ Apps Script อ่าน data.fileName แทน data.payload.fileName ซึ่งทำให้โค้ด Script เรียบง่ายขึ้น

NOTE

ตัวแปรใน Payload Template ของ Webhook จะถูกส่งมาในรูปแบบ String ทั้งหมด ซึ่งหมายความว่า data.confidence จะเป็น String เช่น "0.94" แทนที่จะเป็นตัวเลข 0.94 หากคุณใช้สูตร Google Sheets เช่น =AVERAGE() กับคอลัมน์ Confidence ค่าเหล่านั้นต้องเป็นตัวเลข ให้เรียก parseFloat(data.confidence) ใน Apps Script ก่อนเขียนค่าลง Sheet (ดูส่วนขั้นสูงด้านล่าง)


ขั้นสูง: แยกข้อมูลที่ดึงได้ออกเป็นหลายคอลัมน์

Script เริ่มต้นจะบันทึก extractedData เป็น JSON String เดียว หากต้องการให้แต่ละ Field ที่ดึงได้อยู่ในคอลัมน์ของตัวเอง ซึ่งมีประโยชน์สำหรับการกรอง เรียงลำดับ และสร้าง Chart ให้แทนที่ฟังก์ชัน doPost ด้วยเวอร์ชันนี้:

function doPost(e) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = JSON.parse(e.postData.contents);
  var extracted = data.extractedData || {};
 
  sheet.appendRow([
    new Date().toISOString(),
    data.fileName,
    extracted.invoice_number || '',
    extracted.vendor        || '',
    extracted.total_amount  || '',
    extracted.currency      || '',
    parseFloat(data.confidence)
  ]);
 
  return ContentService
    .createTextOutput(JSON.stringify({ success: true }))
    .setMimeType(ContentService.MimeType.JSON);
}

อัปเดต Header ของ Sheet ให้ตรงกัน:

| Timestamp | File Name | Invoice Number | Vendor | Total Amount | Currency | Confidence |

แทนที่ชื่อ Field (invoice_number, vendor ฯลฯ) ด้วย Key ที่ Ocriva Template ของคุณดึงจริง ๆ ในการหา Key เหล่านี้ ให้เปิดเอกสารที่ประมวลผลแล้วใน Ocriva ไปที่แท็บ Result และสังเกต Key ที่แน่นอนใน Object ข้อมูลที่ดึงได้

NOTE

หลังจากแก้ไข Script คุณต้องสร้าง Deployment ใหม่ (Deploy → New deployment) การแก้ไขโค้ดของ Deployment ที่มีอยู่โดยไม่ Re-deploy จะไม่มีผล คัดลอก URL ใหม่และอัปเดต Endpoint ใน Ocriva


การแก้ไขปัญหา

Script Error — ไม่มีการเพิ่มแถว

  1. ใน Apps Script Editor เปิดแท็บ Executions (แถบด้านซ้าย ไอคอนนาฬิกา)
  2. ค้นหา Execution ล่าสุดแล้วคลิกเพื่อดู Stack Trace ทั้งหมด
  3. สาเหตุทั่วไป: Field ที่หายไปใน data ที่ Script พยายามอ่าน หรือ JSON Parse Error หาก Payload มีรูปแบบไม่ถูกต้อง

HTTP 403 Forbidden ใน Ocriva Delivery Logs

Web App ถูก Deploy ด้วย "Who has access" ที่ตั้งเป็นอะไรบางอย่างนอกเหนือจาก Anyone ให้ Re-deploy: Deploy → New deployment → Who has access: Anyone จากนั้นอัปเดต URL ใน Ocriva ด้วย Deployment URL ใหม่

ข้อมูลไม่ปรากฏใน Sheet ที่ถูกต้อง

getActiveSheet() คืนค่าแท็บที่ Active ล่าสุดเมื่อ Script รันครั้งล่าสุด หากมีหลายแท็บ ให้เรียก Sheet เป้าหมายด้วยชื่อโดยตรงเพื่อความชัดเจน:

var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Document Log");

แทนที่ "Document Log" ด้วยชื่อแท็บที่แน่นอน (Case-sensitive)

อัปเดต Script หลังจาก Deploy ครั้งแรก

การดำเนินการผลลัพธ์
แก้ไขโค้ด คลิก Save ไม่ Re-deployโค้ดเก่ายังคงรัน — การเปลี่ยนแปลง ไม่มีผล
แก้ไขโค้ด, Deploy → Manage deployments → Edit (ไอคอนดินสอ) → เปลี่ยน Version เป็น "New version" → DeployURL เดิม อัปเดตเป็นโค้ดล่าสุด — ใช้วิธีนี้สำหรับการแก้ไขทุกครั้ง
Deploy → New deploymentURL ใหม่ — อัปเดต Ocriva Endpoint ด้วย URL ใหม่

หลังจากแก้ไข Script ให้ไปที่ Deploy → Manage deployments → Edit (ไอคอนดินสอ) → เปลี่ยน Version เป็น "New version" → Deploy วิธีนี้จะอัปเดต URL เดิมให้ใช้โค้ดล่าสุดของคุณ การบันทึก Script โดยไม่สร้าง Version ใหม่จะไม่มีผลกับ Web App ที่ Deploy ไว้แล้ว

สำหรับการเปลี่ยนแปลงสำคัญ (เพิ่มคอลัมน์ เปลี่ยน Field Mapping) การสร้าง Deployment ใหม่และอัปเดต Ocriva เป็นวิธีที่ปลอดภัยที่สุด

แถวปรากฏแต่บางเซลล์ว่าง

ชื่อ Field ใน extracted.field_name ไม่ตรงกับ Key ใน Payload จริง เปิด Executions Log ของ Apps Script แล้วเพิ่มบรรทัด Logger.log(JSON.stringify(data)) ชั่วคราวก่อน appendRow เพื่อตรวจสอบ Payload ที่เข้ามาทั้งหมด


เคล็ดลับ

  • แยก Sheet ตามประเภทเอกสาร: สร้าง Sheet หนึ่งสำหรับใบแจ้งหนี้ หนึ่งสำหรับใบเสร็จ หนึ่งสำหรับสัญญา ใช้ Ocriva Endpoint แยกกันต่อ Template โดยชี้แต่ละ Endpoint ไปยัง Sheet ที่ต้องการ
  • ใช้สูตร Google Sheets: เมื่อข้อมูลเริ่มไหลเข้ามา ให้เพิ่มเซลล์ =AVERAGE(G2:G) เพื่อติดตาม Confidence เฉลี่ยตามเวลา หรือ =COUNTIF(D2:D,"failed") เพื่อนับเอกสารที่ล้มเหลว
  • Conditional Formatting: ไฮไลต์แถวที่ status เป็น failed ด้วยสีแดง เลือกคอลัมน์ Status → Format → Conditional formatting → "Text is exactly" → failed → พื้นหลังสีแดง
  • IMPORTRANGE สำหรับการรายงาน: ดึงข้อมูล Log ไปยัง Sheet รายงานแยกต่างหากด้วย =IMPORTRANGE("spreadsheet_url", "Document Log!A:G") เพื่อให้ Log ดิบสะอาดและการวิเคราะห์แยกออกจากกัน
  • ป้องกัน Header Row: คลิกขวาที่แถวที่ 1 → Protect range → จำกัดการแก้ไขให้กับตัวคุณเองเท่านั้น เพื่อป้องกัน Script เขียนทับ Header โดยไม่ตั้งใจ

แหล่งข้อมูลเพิ่มเติม