สารบัญ Phayoue Widgets

Phayoune API Forms

📘 คู่มือการใช้งาน: Phayoune API Forms (V31)

🚀 1. ปลั๊กอินนี้ทำอะไรได้บ้าง? (Key Features)

นี่คือระบบฟอร์มเชื่อมต่อ Google Sheet ที่ครบเครื่องที่สุดที่เราพัฒนาร่วมกันครับ:

  • เชื่อมต่อ Google Sheet อัตโนมัติ: สร้าง Sheet ใหม่ให้เองตามชื่อที่ตั้ง ไม่ต้องสร้างล่วงหน้า

  • อัปโหลดไฟล์ (File Upload): ลูกค้าแนบสลิป/รูปภาพได้ ไฟล์จะถูกเก็บใน Google Drive และสร้างลิงก์ลง Sheet

  • แจ้งเตือนอีเมล (Auto Email): ส่งเมลหาลูกค้าทันทีพร้อม แนบไฟล์จริง (Attachment) ไปในเมล

  • ระบบตอบกลับ (Admin Reply): กดปุ่ม "📧 ตอบ" ในหน้า Admin เพื่อส่งเมลตอบกลับหาลูกค้าได้ทันที

  • ความปลอดภัย (Security): มีระบบ API Key ป้องกันคนแอบใช้ URL ของเรายิงข้อมูลขยะเข้ามา

  • ตรวจสอบสถานะจริง (Real-Check): เช็คว่าข้อมูลถึง Google จริงหรือไม่ ถ้า URL ผิดจะแจ้งเตือนทันที

  • Auto Scan: หน้า Admin มีปุ่มสแกนหาฟอร์มในเว็บให้อัตโนมัติ ไม่ต้องคอยจำ URL

  • Design: ปรับแต่งปุ่มกดได้ละเอียด (สี, เงา, เส้นขอบ, ความมน) ผ่าน Elementor


🛠️ วิธีติดตั้ง (Installation)

STEP 1: ฝั่ง Google (Back-end)

  1. ไปที่ Google Apps Script สร้างโปรเจกต์ใหม่

  2. นำโค้ด Google Apps Script นี้ ไปวาง

    
    // Google Apps Script V27 (Final)
    var SECURITY_KEY = "PhayouneKey"; // <--- ตรวจสอบรหัสตรงนี้
    
    function doGet(e) {
      if (e.parameter.key !== SECURITY_KEY) return ContentService.createTextOutput(""); 
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sendJSON = function(d) { return ContentService.createTextOutput(JSON.stringify(d)).setMimeType(ContentService.MimeType.JSON); };
    
      if (e.parameter.action == 'get_sheets') {
        var sheets = ss.getSheets();
        var names = [];
        for (var i=0; i<sheets.length; i++) names.push(sheets[i].getName()); return sendJSON({status: "success", sheets: names}); } var sheetName = e.parameter.sheet || "Sheet1"; var sheet = ss.getSheetByName(sheetName); if (!sheet) return sendJSON([]); if (e.parameter.action == 'delete') { var row = parseInt(e.parameter.row); if (row > 1) { try { sheet.deleteRow(row); return sendJSON({status: "success"}); } catch (err) { return sendJSON({status: "error", message: err.toString()}); } }
      }
    
      var data = sheet.getDataRange().getValues();
      var result = [];
      if (data.length > 1) {
        var headers = data[0];
        for (var i = 1; i < data.length; i++) {
          var rowObj = { '_row_index': i + 1 };
          for (var j = 0; j < headers.length; j++) rowObj[headers[j]] = data[i][j];
          result.push(rowObj);
        }
      }
      return sendJSON(result);
    }
    
    function doPost(e) {
      if (e.parameter.key !== SECURITY_KEY) return ContentService.createTextOutput(""); 
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      
      // *** ส่วนสำคัญ: คำสั่ง Reply ต้องมีตรงนี้ ***
      if (e.parameter.action == 'reply') {
        try {
          if(e.parameter.to && e.parameter.subject && e.parameter.message) {
            GmailApp.sendEmail(e.parameter.to, e.parameter.subject, e.parameter.message, { name: e.parameter.sender_name || "Admin" });
            return ContentService.createTextOutput("Sent");
          }
          return ContentService.createTextOutput("Error: Missing Data");
        } catch(err) { return ContentService.createTextOutput("Error: " + err); }
      }
    
      // --- SAVE ---
      var sheetName = e.parameter.sheet || "Sheet1";
      var sheet = ss.getSheetByName(sheetName);
    
      if (!sheet) {
        try {
          sheet = ss.insertSheet(sheetName);
          var h = ["Timestamp"];
          var ignore = ['action','sheet','key','file_base64','file_name','file_mime','config_email_field','config_sender_name','config_subject','reply_to','reply_subject','reply_message'];
          for (var k in e.parameter) { if (!ignore.includes(k)) h.push(k); }
          sheet.appendRow(h);
        } catch (err) { return ContentService.createTextOutput("Error Create Sheet"); }
      }
    
      if (e.parameter.action !== 'save') return ContentService.createTextOutput("Error Action"); // <--- นี่คือจุดที่แจ้ง Error ถ้าไม่เจอคำสั่ง reply ข้างบน
    
      var fileUrl = "";
      var fileBlob = null;
      if (e.parameter.file_base64 && e.parameter.file_name) {
        try {
          var folderName = "Phayoune Uploads";
          var folders = DriveApp.getFoldersByName(folderName);
          var folder = folders.hasNext() ? folders.next() : DriveApp.createFolder(folderName);
          var decoded = Utilities.base64Decode(e.parameter.file_base64);
          var mime = e.parameter.file_mime || MimeType.JPEG;
          fileBlob = Utilities.newBlob(decoded, mime, e.parameter.file_name);
          var file = folder.createFile(fileBlob);
          file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
          fileUrl = file.getUrl();
        } catch(fErr) { fileUrl = "Error Upload"; }
      }
    
      var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
      var nextRow = sheet.getLastRow() + 1;
      var newRow = [];
      var emailField = e.parameter.config_email_field || "email"; 
      var customerEmail = ""; 
      
      for (var i = 0; i < headers.length; i++) {
        var key = headers[i];
        var val = e.parameter[key] || "";
        if (key === emailField || key.toLowerCase() === 'email') customerEmail = val;
    
        if (key === 'Timestamp') newRow.push(new Date());
        else {
          if (fileUrl && (key === e.parameter.file_field_name || key.toLowerCase().includes('file') || key.toLowerCase().includes('slip'))) newRow.push(fileUrl);
          else newRow.push(val);
        }
      }
      sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow]);
    
      if (customerEmail && customerEmail.includes("@")) {
        try {
          var senderName = e.parameter.config_sender_name || "Phayoune Form";
          var subject = e.parameter.config_subject || "ยืนยันการรับข้อมูล";
          var body = "เรียนคุณลูกค้า,\n\nได้รับข้อมูลเรียบร้อยแล้ว\n\nรายละเอียด:\n";
          for (var i = 0; i < headers.length; i++) {
            var hKey = headers[i];
            if(hKey !== 'Timestamp' && !hKey.includes('file_')) {
                 var dVal = e.parameter[hKey] || "-";
                 if (fileUrl && (hKey === e.parameter.file_field_name || hKey.toLowerCase().includes('file'))) dVal = "see attach image"; 
                 body += "• " + hKey + ": " + dVal + "\n";
            }
          }
          body += "\nขอบคุณครับ\n" + senderName;
          var mailOptions = { name: senderName };
          if (fileBlob) mailOptions.attachments = [fileBlob];
          GmailApp.sendEmail(customerEmail, subject, body, mailOptions);
        } catch (e) { }
      }
    
      return ContentService.createTextOutput("Saved");
    }
    
    function askPermission() {
      // ฟังก์ชันนี้มีไว้กด Run เพื่อขอสิทธิ์เท่านั้น (ไม่ได้ใช้งานจริง)
      
      // 1. ขอสิทธิ์อีเมล
      GmailApp.getInboxThreads(0, 1);
      MailApp.getRemainingDailyQuota();
      
      // 2. ขอสิทธิ์ Google Drive (อัปโหลดรูป)
      DriveApp.getRootFolder();
      
      // 3. ขอสิทธิ์ Spreadsheet
      SpreadsheetApp.getActiveSpreadsheet();
    }
    
    
  3. สำคัญ: แก้ไขบรรทัดที่ 2 var SECURITY_KEY = "PhayouneKey"; ให้เป็นรหัสลับที่คุณต้องการ (จำรหัสนี้ไว้นะครับ)

  4. กดปุ่ม Run (เรียกใช้) 1 ครั้ง เพื่อกดอนุญาตสิทธิ์ (Authorize) ให้เข้าถึง Gmail/Drive/Sheet

  5. การ Deploy (สำคัญมาก):

    • กดปุ่ม Deploy (ทำให้ใช้งานได้) > Manage deployments (จัดการ...)

    • กดรูปดินสอ ✏️

    • ช่อง Version เลือก "New version" (เวอร์ชันใหม่) ทุกครั้งที่มีการแก้โค้ด

    • ช่อง Who has access เลือก "Anyone" (ทุกคน)

    • กด Deploy แล้วคัดลอก Web app URL เก็บไว้

STEP 2: ฝั่ง WordPress (Front-end)

  1. สร้างโฟลเดอร์ชื่อ phayoune-api-forms ใน wp-content/plugins/

  2. สร้างไฟล์ index.php แล้ววางโค้ด Plugin V31 ลงไป

  3. ไปที่หน้า Admin WordPress > Plugins > กด Activate ปลั๊กอิน "Phayoune API Forms (V31 Final Integrity)"


🎮 วิธีใช้งาน (Usage Guide)

1. การสร้างฟอร์มด้วย Elementor

  1. เปิดหน้าเว็บที่ต้องการแก้ไขด้วย Elementor

  2. ค้นหา Widget ชื่อ "Phayoune Form (V31)" แล้วลากวาง

  3. ตั้งค่า Tab 1: Fields (ข้อมูล)

    • เพิ่ม/ลบ ช่องกรอกข้อมูลตามต้องการ

    • เคล็ดลับ: ช่องที่เป็นไฟล์อัปโหลด ให้เลือก Type เป็น File Upload

  4. ตั้งค่า Tab 2: Email (อีเมล)

    • กำหนดชื่อผู้ส่ง และหัวข้ออีเมลที่จะส่งหาลูกค้า

  5. ตั้งค่า Tab 3: Connection (การเชื่อมต่อ)

    • Script URL: วาง URL ที่ได้จาก STEP 1

    • Security Key: ใส่รหัสให้ตรงกับใน Google Apps Script (เช่น PhayouneKey)

    • Sheet Name: ตั้งชื่อ Sheet ที่ต้องการเก็บข้อมูล (เช่น OrderForm2026)

  6. ตั้งค่า Tab Style:

    • ปรับสีปุ่ม, ขนาด, เส้นขอบ (Border), และเงา (Box Shadow) ให้สวยงาม

2. การดูข้อมูลและตอบกลับ (Admin Panel)

  1. ไปที่เมนู "Phayoune Data" ในหน้า Admin WordPress

  2. การดึงข้อมูล:

    • วิธีง่าย: กดปุ่ม "🚀 สแกนหาฟอร์ม" ระบบจะไปดึง URL และ Key จากหน้าเว็บมาให้เอง แล้วเลือกจาก Dropdown ได้เลย

    • วิธีกรอกเอง: ใส่ URL, Key, Sheet Name แล้วกด "ดูข้อมูล"

  3. ตารางแสดงผล:

    • ถ้ามีรูปภาพ จะแสดงเป็นรูปย่อ (Thumbnail)

    • คอลัมน์ขยะทางเทคนิคจะถูกซ่อนไว้ อัตโนมัติ

  4. การตอบกลับลูกค้า:

    • กดปุ่ม "📧 ตอบ" (ปุ่มจะขึ้นเฉพาะแถวที่มีอีเมล)

    • พิมพ์ข้อความใน Popup แล้วกดส่ง ระบบจะส่งเมลผ่าน Gmail ของคุณทันที


⚠️ ข้อควรระวัง (Troubleshooting)

  • Error Action: แปลว่า Google Apps Script ยังเป็นเวอร์ชันเก่า -> ให้ไปกด Deploy เป็น New version

  • Connection Failed: แปลว่า URL ผิด หรือใส่ Security Key ไม่ตรงกัน

  • ไม่เห็นรูปในตาราง: ตรวจสอบว่าใน Widget ตั้งชื่อ Field (Name Eng) ว่า file, slip, image หรือไม่ (ระบบจะจับคำพวกนี้เพื่อแสดงรูป)

  • ไม่ได้รับอีเมล์  ให้รัน ฟังชั่น
    askPermission ใน App script คลิก อนุญาตทั้งหมด แล้วลองดูใหม่
Media Pro Widget
ภาพจาก Canva Website

Website Design
and
Development

Crafting stunning websites that connect, engage, and inspire.

Enhanced User Experience

Increased Credibility and Brand Trust

Improved SEO and Visibility

Learn More

+123-456-7890

www.reallygreatsite.com

Studio
Shodwe

Hero Pro Widget
Your company name

Welcome to
our E-Learning project

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry standard Letraset sheets containing!
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry standard Letraset sheets containing!
Your company name

Welcome to
our E-Learning project

Your company name

Welcome to
our E-Learning project

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry standard Letraset sheets containing!

Welcome to
our E-Learning project

Peter Fademanager
Susan macathymanager
Name Tag + Slide Pro
Author
Your Full Name
Your Position

Slide #1

Description...

Slide

Slide #2

Description...

Slide
Slide
Slide

Slide #2

Description...

Slide

Slide #1

Description...

Slide
Author
Your Full Name
Your Position
This is the Title
This is the Sub Title

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

This is the Title
This is the Sub Title

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

This is the Title
This is the Sub Title

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

ChatGPT Image Dec 9, 2025, 11_19_54 AM
ChatGPT Image Dec 6, 2025, 04_05_16 PM

Shop faster with foodmart App

Phayoune App Promo. Box
Page 1 of 6
Ribbon