Webapps GAS ค้นหาข้อมูลด้วยเสียงหรือพิมพ์ข้อความ

 




ตัวอย่างเว็บแอป Google Apps Script (โค้ดฝั่งเซิร์ฟเวอร์ + หน้า HTML/JS) 

  • Code.gs — ฟังก์ชัน doGet() และ searchData(query) ที่อ่านข้อมูลจาก Google Sheet (sheet ชื่อ Data) แล้วค้นหาแบบไม่สนใจตัวพิมพ์
  • index.html — หน้า UI สำหรับพิมพ์หรือกดไมค์ใช้เสียง (Web Speech API) เพื่อรับคำพูด แล้วส่งคำค้นไปยัง searchData และแสดงผลเป็นตาราง

ขั้นตอนถัดไป (ทำเพียงครั้งเดียว):

  1. สร้างโปรเจ็กต์ Google Apps Script ใหม่ (https://script.google.com)
  2. เพิ่มไฟล์ Code.gs และ index.html แล้ววางโค้ดจาก canvas ลงไป (ผมรวมไว้เรียบร้อยใน canvas)
  3. แก้ไข Code.gs — เปลี่ยน 'SPREADSHEET_ID' เป็น ID ของ Google Sheet ของคุณ (ตัวที่มีชีตชื่อ Data)
  4. เตรียม Google Sheet: แถวแรกเป็น header (ชื่อคอลัมน์) ข้อมูลเริ่มแถวที่ 2 ขึ้นไป
  5. ติดตั้งสิทธิ์และ deploy: เลือก Deploy > New deployment > Web app ตั้งค่าให้ Execute as เป็น Me และ Who has access เป็น Anyone (หรือตามที่ต้องการ)
  6. เปิด URL ที่ได้ จะเห็นหน้าเว็บที่มีช่องพิมพ์ ไอคอนไมโครโฟน และปุ่มค้นหา

ข้อจำกัด / หมายเหตุ:

  • ฟีเจอร์เสียงใช้ Web Speech API — รองรับใน Chrome / Edge เดสก์ท็อปเป็นหลัก (บางเบราว์เซอร์/มือถืออาจไม่รองรับ)
  • ถ้าต้องการให้รองรับภาษาอื่น แก้ recognition.lang ใน index.html (ตอนนี้ตั้ง th-TH)

ด้านล่างนี้คือ โค้ดทั้งหมดแบบพร้อมใช้ สำหรับเว็บแอป Google Apps Script ค้นหาข้อมูลด้วย “เสียงหรือพิมพ์” 


📁 ไฟล์ที่ 1: Code.gs

function doGet() { return HtmlService.createHtmlOutputFromFile('index') .setTitle('ค้นหาข้อมูลด้วยเสียงหรือพิมพ์') .setFaviconUrl('https://ssl.gstatic.com/docs/script/images/logo.png'); } function searchData(query) { try { if (!query) return { success: true, results: [] }; query = String(query).trim().toLowerCase(); // 🔧 แก้ตรงนี้: ใส่ Spreadsheet ID ของคุณ var ss = SpreadsheetApp.openById('YOUR_SPREADSHEET_ID_HERE'); var sh = ss.getSheetByName('Data'); // ชื่อชีตต้องตรงกับใน Spreadsheet if (!sh) return { success: false, error: 'ไม่พบชีตชื่อ Data' }; var values = sh.getDataRange().getDisplayValues(); if (values.length <= 1) return { success: true, results: [] }; var headers = values[0]; var rows = values.slice(1); var results = rows .map((r, i) => ({ index: i + 2, row: r, joined: r.join(' ').toLowerCase() })) .filter(obj => obj.joined.includes(query)) .map(obj => ({ rowIndex: obj.index, values: obj.row })); return { success: true, results, headers }; } catch (err) { return { success: false, error: err.toString() }; } }

📁 ไฟล์ที่ 2: index.html

<!doctype html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ค้นหาข้อมูลด้วยเสียงหรือพิมพ์</title> <style> body { font-family: "Prompt", Arial, sans-serif; margin: 20px; background: #f8fafc; } .container { max-width: 800px; margin: 0 auto; background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); } h2 { text-align: center; margin-bottom: 20px; } .controls { display: flex; gap: 10px; } input[type=text] { flex: 1; padding: 10px; border-radius: 8px; border: 1px solid #ccc; } button { padding: 10px 15px; border: none; border-radius: 8px; cursor: pointer; font-weight: bold; } #micBtn { background-color: #f1f5f9; } #micBtn.mic-on { background-color: #ffe5e5; } #searchBtn { background-color: #007bff; color: white; } table { width: 100%; border-collapse: collapse; margin-top: 15px; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #f1f1f1; } .status { margin-top: 10px; font-size: 14px; color: #555; } </style> </head> <body> <div class="container"> <h2>🔍 ค้นหาข้อมูล (พูดหรือพิมพ์)</h2> <div class="controls"> <input id="q" type="text" placeholder="พิมพ์หรือพูดคำค้น เช่น ชื่อ, หมายเลข, สถานที่..."> <button id="micBtn" title="พูดคำค้น">🎤</button> <button id="searchBtn">ค้นหา</button> </div> <div class="status" id="status"></div> <div id="results"></div> </div> <script> const qInput = document.getElementById('q'); const micBtn = document.getElementById('micBtn'); const searchBtn = document.getElementById('searchBtn'); const statusDiv = document.getElementById('status'); const resultsDiv = document.getElementById('results'); let recognition; let listening = false; // ตรวจสอบว่ารองรับ SpeechRecognition หรือไม่ if (window.SpeechRecognition || window.webkitSpeechRecognition) { const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; recognition = new SpeechRecognition(); recognition.lang = 'th-TH'; recognition.interimResults = false; recognition.onstart = () => { listening = true; micBtn.classList.add('mic-on'); statusDiv.textContent = '🎙️ กำลังฟัง...'; }; recognition.onend = () => { listening = false; micBtn.classList.remove('mic-on'); statusDiv.textContent = ''; }; recognition.onerror = (e) => { listening = false; micBtn.classList.remove('mic-on'); statusDiv.textContent = '⚠️ ข้อผิดพลาด: ' + e.error; }; recognition.onresult = (evt) => { const text = evt.results[0][0].transcript; qInput.value = text; statusDiv.textContent = 'ได้ข้อความ: ' + text; doSearch(); }; } else { micBtn.disabled = true; micBtn.title = 'เบราว์เซอร์นี้ไม่รองรับคำสั่งเสียง'; } micBtn.addEventListener('click', () => { if (!recognition) return; if (listening) recognition.stop(); else recognition.start(); }); searchBtn.addEventListener('click', doSearch); qInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') doSearch(); }); function doSearch() { const q = qInput.value.trim(); if (!q) { statusDiv.textContent = '⚠️ กรุณาพิมพ์หรือพูดคำค้น'; return; } statusDiv.textContent = '🔎 กำลังค้นหา...'; resultsDiv.innerHTML = ''; google.script.run .withSuccessHandler(renderResults) .withFailureHandler((err) => statusDiv.textContent = '❌ เกิดข้อผิดพลาด: ' + err) .searchData(q); } function renderResults(res) { if (!res.success) { statusDiv.textContent = '❌ ' + res.error; return; } const count = res.results.length; statusDiv.textContent = `พบ ${count} รายการ`; if (!count) { resultsDiv.innerHTML = '<p>ไม่พบข้อมูลที่ตรงกับคำค้น</p>'; return; } let html = '<table><thead><tr>'; html += res.headers.map(h => `<th>${escapeHtml(h)}</th>`).join(''); html += '<th>แถวที่</th></tr></thead><tbody>'; res.results.forEach(r => { html += '<tr>' + r.values.map(c => `<td>${escapeHtml(c)}</td>`).join('') + `<td>${r.rowIndex}</td></tr>`; }); html += '</tbody></table>'; resultsDiv.innerHTML = html; } function escapeHtml(s) { if (s == null) return ''; return String(s) .replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;'); } </script> </body> </html>

✅ วิธีใช้งาน

    • Code.gs → วางโค้ดด้านบน
    • index.html → วางโค้ด HTML ด้านบน

  • แก้ไขใน Code.gs:

    var ss = SpreadsheetApp.openById('YOUR_SPREADSHEET_ID_HERE'); ใส่ Spreadsheet ID ของคุณ (จาก URL ของ Google Sheet)
  • ใน Google Sheet ให้มีชีตชื่อ Data และมีหัวตาราง (เช่น ชื่อ, เบอร์, ที่อยู่ ฯลฯ)
  • ไปที่เมนู Deploy > New deployment > Web app

    • Execute as: Me
    • Who has access: Anyone
    • แล้วกด Deploy
  • เปิดลิงก์ที่ได้ → ทดลองพูดหรือพิมพ์คำค้นได้เลย 🎤🔎




แสดงความคิดเห็น (0)
ใหม่กว่า เก่ากว่า