วิธีสร้าง LINE Bot สำหรับวิเคราะห์โรคผิวหนังด้วย Roboflow

วิธีสร้าง LINE Bot สำหรับวิเคราะห์โรคผิวหนังด้วย Roboflow

เป้าหมาย

สร้าง LINE Bot ที่ให้ผู้ใช้ส่งภาพผิวหนังผ่านแชท LINE แล้ว Bot จะวิเคราะห์ภาพโดยใช้ Roboflow เพื่อบอกว่าเป็นโรคผิวหนังอะไร พร้อมคำอธิบายและวิธีการรักษาเบื้องต้น ผลลัพธ์จะส่งกลับไปยังผู้ใช้ในรูปแบบข้อความที่เข้าใจง่าย


อุปกรณ์และสิ่งที่ต้องเตรียม

  1. คอมพิวเตอร์ที่มีอินเทอร์เน็ต
  2. บัญชี LINE Developers (ฟรี) เพื่อสร้าง LINE Bot
  3. บัญชี Roboflow (ฟรีสำหรับเริ่มต้น) เพื่อใช้โมเดลวิเคราะห์ภาพ
  4. Google Account เพื่อใช้ Google Apps Script และ Google Drive
  5. ความรู้พื้นฐานเกี่ยวกับการเขียนโค้ด (JavaScript เบื้องต้น)

ขั้นตอนการทำ

ขั้นตอนที่ 1: สร้าง LINE Bot

  1. สมัครบัญชี LINE Developers
    • เข้าไปที่ LINE Developers
    • สร้าง Provider และ Messaging API Channel (เลือกประเภท Bot)
    • รับ Channel Access Token (คัดลอกเก็บไว้ ใช้ในโค้ด)
  2. ตั้งค่า Webhook
    • ใน LINE Developers ไปที่แท็บ “Messaging API”
    • เปิดใช้งาน Webhook และตั้งค่า URL (จะได้ในขั้นตอน Google Apps Script)
    • เปิด “Allow bot to reply” เพื่อให้ Bot ตอบกลับได้

สิ่งที่ได้: LINE Bot ที่พร้อมเชื่อมต่อกับโค้ดของเรา


ขั้นตอนที่ 2: สร้างโมเดลใน Roboflow

  1. สมัครบัญชี Roboflow
    • เข้าไปที่ Roboflow และสมัครฟรี
    • สร้างโปรเจกต์ใหม่ ชื่อเช่น “Skin Diseases”
  2. อัปโหลดภาพและฝึกโมเดล
    • รวบรวมภาพตัวอย่างโรคผิวหนัง (เช่น ภาพของหูด, กลาก, มะเร็งผิวหนัง)
    • อัปโหลดภาพไปยัง Roboflow และกำหนดชื่อคลาส (เช่น BCC, Molluscum, Warts)
    • ฝึกโมเดล (Roboflow จะจัดการให้อัตโนมัติ)
    • รับ API URL และ API Key จากแท็บ “Deploy” ใน Roboflow

สิ่งที่ได้: โมเดล AI ที่วิเคราะห์ภาพและบอกว่าเป็นโรคอะไร


ขั้นตอนที่ 3: เขียนโค้ดใน Google Apps Script

  1. สร้างโปรเจกต์ใน Google Apps Script
    • เข้าไปที่ Google Apps Script
    • คลิก “New Project” และตั้งชื่อ เช่น “Skin Disease Bot”
  2. คัดลอกโค้ด
    • ใช้โค้ดด้านล่าง (ปรับจากโค้ดก่อนหน้าให้เหมาะกับการสอน)
    • แทนที่ CHANNEL_ACCESS_TOKEN, ROBOFLOW_API_URL, และ ROBOFLOW_API_KEY ด้วยค่าจริงที่ได้จากขั้นตอนที่ 1 และ 2

// Channel Access Token จาก LINE
const CHANNEL_ACCESS_TOKEN = '######';

// Roboflow API
const ROBOFLOW_API_URL = 'https://serverless.roboflow.com/skin-diseases-dfyfz/2';
const ROBOFLOW_API_KEY = 'kPUMWSZnttvttboPNusd';

// ข้อมูลคำอธิบายโรคผิวหนัง
const DISEASE_DESCRIPTIONS = {
  'BCC': {
    name: 'มะเร็งผิวหนังชนิด Basal Cell',
    description: 'มะเร็งผิวหนังที่พบบ่อย เกิดจากเซลล์ basal มักไม่แพร่กระจายแต่ทำลายเนื้อเยื่อรอบ ๆ ได้',
    treatment: 'ปรึกษาแพทย์เพื่อผ่าตัดหรือใช้ยาทาเฉพาะ หลีกเลี่ยงแสงแดดและใช้ครีมกันแดด'
  },
  'BKL': {
    name: 'รอยโรคคล้าย Keratosis ที่ไม่ร้ายแรง',
    description: 'รอยโรคที่ไม่ใช่มะเร็ง เช่น Seborrheic Keratosis เป็นตุ่มขรุขระคล้ายหูด',
    treatment: 'ไม่ต้องรักษาถ้าไม่รบกวน อาจจี้เย็นหรือเลเซอร์โดยแพทย์'
  },
  'NV': {
    name: 'ไฝ (Melanocytic Nevi)',
    description: 'ไฝหรือจุดสีบนผิวหนัง มักไม่ร้ายแรงแต่บางครั้งอาจกลายเป็นมะเร็ง',
    treatment: 'เฝ้าสังเกตการเปลี่ยนแปลง ปรึกษาแพทย์หากไฝเปลี่ยนขนาด สี หรือมีอาการผิดปกติ'
  },
  'Atopic': {
    name: 'ผื่นภูมิแพ้ผิวหนัง (Atopic Dermatitis)',
    description: 'ผื่นเรื้อรังที่ทำให้ผิวแห้ง คัน และแดง มักพบในผู้ที่มีประวัติภูมิแพ้',
    treatment: 'ใช้มอยส์เจอไรเซอร์, ยาทาคอร์ติโคสเตียรอยด์ และหลีกเลี่ยงสิ่งกระตุ้น เช่น สบู่แรง'
  },
  'Basal': {
    name: 'มะเร็งผิวหนังชนิด Basal Cell',
    description: 'เหมือน BCC เป็นมะเร็งผิวหนังที่เติบโตช้า มักเกิดจากแสงแดด',
    treatment: 'ปรึกษาแพทย์เพื่อผ่าตัดหรือรักษาด้วยเลเซอร์ ใช้ครีมกันแดดป้องกัน'
  },
  'Benign': {
    name: 'รอยโรคที่ไม่ร้ายแรง',
    description: 'รอยโรคผิวหนังที่ไม่ใช่มะเร็ง เช่น ไฝหรือก้อนไขมัน',
    treatment: 'ไม่ต้องรักษาเว้นแต่รบกวน อาจผ่าตัดเล็กหรือเลเซอร์'
  },
  'Candidiasis': {
    name: 'การติดเชื้อยีสต์ (Candidiasis)',
    description: 'การติดเชื้อราที่ผิวหนัง ทำให้เกิดผื่นแดง คัน มักพบในที่อับชื้น',
    treatment: 'ใช้ยาต้านเชื้อรา (เช่น Clotrimazole) รักษาความสะอาดและแห้ง'
  },
  'Carcinoma': {
    name: 'มะเร็งผิวหนัง',
    description: 'มะเร็งผิวหนังที่อาจเป็น BCC หรือ SCC เกิดจากเซลล์ผิวที่ผิดปกติ',
    treatment: 'ต้องพบแพทย์เพื่อผ่าตัดหรือรักษาด้วยรังสี หลีกเลี่ยงแสงแดด'
  },
  'Cell': {
    name: 'รอยโรคจากเซลล์ผิดปกติ',
    description: 'รอยโรคที่อาจเกี่ยวข้องกับการเปลี่ยนแปลงของเซลล์ผิว มักต้องตรวจเพิ่มเติม',
    treatment: 'ปรึกษาแพทย์เพื่อตรวจชิ้นเนื้อและวินิจฉัย'
  },
  'Dermatitis': {
    name: 'ผื่นผิวหนังอักเสบ',
    description: 'ผื่นที่เกิดจากการระคายเคืองหรือภูมิแพ้ ทำให้ผิวแดง คัน หรือลอก',
    treatment: 'ใช้มอยส์เจอไรเซอร์, ยาทาคอร์ติโคสเตียรอยด์ และหลีกเลี่ยงสิ่งกระตุ้น'
  },
  'Eczema': {
    name: 'โรคเรื้อนกวาง (Eczema)',
    description: 'ผื่นเรื้อรังที่ทำให้ผิวแห้ง คัน และแดง มักสัมพันธ์กับภูมิแพ้',
    treatment: 'ใช้ครีมบำรุงผิว, ยาทาคอร์ติโคสเตียรอยด์ และควบคุมสิ่งกระตุ้น'
  },
  'Fungal': {
    name: 'การติดเชื้อรา',
    description: 'เกิดจากเชื้อราที่ผิวหนัง เช่น กลากหรือน้ำกัดเท้า ทำให้คันและมีผื่นวง',
    treatment: 'ใช้ยาต้านเชื้อรา (เช่น Miconazole) และรักษาผิวให้แห้งสะอาด'
  },
  'Infections': {
    name: 'การติดเชื้อที่ผิวหนัง',
    description: 'เกิดจากเชื้อแบคทีเรีย ไวรัส หรือเชื้อรา ทำให้เกิดรอยแดง บวม หรือหนอง',
    treatment: 'ใช้ยาทาต้านเชื้อ (เช่น Bacitracin หรือ Clotrimazole) และปรึกษาแพทย์'
  },
  'Keratoses': {
    name: 'รอยโรค Keratosis',
    description: 'ตุ่มหรือแผ่นหนาคล้ายขี้ผึ้ง มักเกิดจากอายุหรือแสงแดด เช่น Actinic Keratosis',
    treatment: 'จี้เย็นหรือใช้ยาทา (เช่น Fluorouracil) ปรึกษาแพทย์เพื่อป้องกันมะเร็ง'
  },
  'Keratosis-like': {
    name: 'รอยโรคคล้าย Keratosis',
    description: 'รอยโรคที่คล้าย Keratosis แต่ไม่ร้ายแรง มักเป็นตุ่มขรุขระ',
    treatment: 'ไม่ต้องรักษาเว้นแต่รบกวน อาจจี้เย็นหรือเลเซอร์'
  },
  'Lesions': {
    name: 'รอยโรคผิวหนัง',
    description: 'รอยผิดปกติที่ผิวหนัง อาจเป็นได้ทั้งร้ายและไม่ร้าย ต้องตรวจเพิ่ม',
    treatment: 'ปรึกษาแพทย์เพื่อตรวจชิ้นเนื้อและวินิจฉัย'
  },
  'Lichen': {
    name: 'ไลเคน (Lichen Planus หรือ Lichen Simplex)',
    description: 'ผื่นที่เกิดจากการอักเสบเรื้อรัง ทำให้เกิดตุ่มแบนสีม่วงหรือผื่นหนาคัน',
    treatment: 'ใช้ยาคอร์ติโคสเตียรอยด์ และหลีกเลี่ยงการเกา ปรึกษาแพทย์'
  },
  'Melanocytic': {
    name: 'รอยโรคจากเซลล์เมลาโนไซต์',
    description: 'รอยโรคที่เกี่ยวข้องกับเซลล์สร้างเม็ดสี เช่น ไฝหรือเนื้องอก',
    treatment: 'เฝ้าสังเกตหรือผ่าตัดหากสงสัยมะเร็ง ปรึกษาแพทย์'
  },
  'Melanoma': {
    name: 'มะเร็งผิวหนังชนิด Melanoma',
    description: 'มะเร็งผิวหนังร้ายแรง เกิดจากเซลล์เม็ดสี มักเป็นจุดสีดำหรือน้ำตาลที่เปลี่ยนแปลง',
    treatment: 'ต้องผ่าตัดและรักษาต่อเนื่องโดยแพทย์ หลีกเลี่ยงแสงแดด'
  },
  'Molluscum': {
    name: 'หูดข้าวสุก',
    description: 'เกิดจากไวรัส ทำให้เกิดตุ่มเล็กสีเนื้อหรือขาว มีรอยบุ๋มตรงกลาง ติดต่อง่าย',
    treatment: 'อาจหายเองใน 6-12 เดือน หรือจี้เย็นโดยแพทย์ รักษาความสะอาด'
  },
  'Nevi': {
    name: 'ไฝ (Nevi)',
    description: 'จุดหรือตุ่มสีบนผิวหนัง มักไม่ร้ายแรงแต่บางครั้งอาจพัฒนาเป็นมะเร็ง',
    treatment: 'เฝ้าสังเกต หากเปลี่ยนขนาดหรือสีให้พบแพทย์เพื่อตรวจ'
  },
  'Planus': {
    name: 'ไลเคนแพลนัส (Lichen Planus)',
    description: 'ผื่นสีม่วงหรือแดง เป็นตุ่มแบน คัน มักพบที่ข้อมือหรือข้อเท้า',
    treatment: 'ใช้ยาคอร์ติโคสเตียรอยด์ และหลีกเลี่ยงการเกา ปรึกษาแพทย์'
  },
  'Psoriasis': {
    name: 'โรคสะเก็ดเงิน (Psoriasis)',
    description: 'ผื่นเรื้อรังที่ทำให้ผิวแดง เป็นสะเก็ดสีเงิน มักพบที่ข้อศอกหรือเข่า',
    treatment: 'ใช้ยาทาคอร์ติโคสเตียรอยด์หรือยารับประทาน ปรึกษาแพทย์'
  },
  'Ringworm': {
    name: 'กลาก (Ringworm)',
    description: 'การติดเชื้อราที่ทำให้เกิดผื่นวงแดง คัน มีขอบชัด',
    treatment: 'ใช้ยาต้านเชื้อรา (เช่น Clotrimazole) และรักษาผิวให้แห้ง'
  },
  'Seborrheic': {
    name: 'รอยโรค Seborrheic Keratosis',
    description: 'ตุ่มหรือแผ่นสีน้ำตาล ดำ หรือขาว คล้ายขี้ผึ้ง ไม่ร้ายแรง',
    treatment: 'ไม่ต้องรักษาเว้นแต่รบกวน อาจจี้เย็นหรือเลเซอร์'
  },
  'Tinea': {
    name: 'การติดเชื้อรา Tinea',
    description: 'การติดเชื้อราที่ผิวหนัง เช่น กลากหรือน้ำกัดเท้า ทำให้เกิดผื่นแดงคัน',
    treatment: 'ใช้ยาต้านเชื้อรา (เช่น Terbinafine) และรักษาความแห้งสะอาด'
  },
  'Tumors': {
    name: 'เนื้องอกผิวหนัง',
    description: 'ก้อนเนื้อที่อาจเป็นมะเร็งหรือไม่ร้ายแรง ต้องตรวจเพิ่มเติม',
    treatment: 'ปรึกษาแพทย์เพื่อตรวจชิ้นเนื้อและรักษาตามสาเหตุ'
  },
  'Viral': {
    name: 'โรคผิวหนังจากไวรัส',
    description: 'เกิดจากไวรัส เช่น หูดหรือเริม ทำให้เกิดตุ่มแข็งหรือตุ่มน้ำ',
    treatment: 'ใช้ยาทาต้านไวรัส (เช่น Acyclovir) หรือกรดซาลิไซลิก ปรึกษาแพทย์'
  },
  'Warts': {
    name: 'หูด',
    description: 'เกิดจากไวรัส HPV เป็นก้อนเนื้อแข็ง สีผิวหรือเทา ติดต่อผ่านการสัมผัส',
    treatment: 'ใช้กรดซาลิไซลิกหรือจี้เย็น รักษาความสะอาดและหลีกเลี่ยงการสัมผัส'
  }
};

// ฟังก์ชันหลักที่รับ webhook จาก LINE
function doPost(e) {
  try {
    const replyToken = JSON.parse(e.postData.contents).events[0].replyToken;
    const messageType = JSON.parse(e.postData.contents).events[0].message.type;
    const messageId = JSON.parse(e.postData.contents).events[0].message.id;

    if (messageType === 'image') {
      // ดึง URL ของภาพจาก LINE
      const imageUrl = getImageUrl(messageId);
      
      // ส่งภาพไปประมวลผลที่ Roboflow
      const roboflowResult = processImageWithRoboflow(imageUrl);
      
      // สร้างข้อความตอบกลับ
      const replyMessage = {
        type: 'text',
        text: roboflowResult
      };
      
      // ส่งข้อความตอบกลับ
      replyToLine(replyToken, replyMessage);
    }
    
    return ContentService.createTextOutput(JSON.stringify({status: 'success'})).setMimeType(ContentService.MimeType.JSON);
  } catch (error) {
    Logger.log('Error: ' + error);
    return ContentService.createTextOutput(JSON.stringify({status: 'error', message: error.toString()})).setMimeType(ContentService.MimeType.JSON);
  }
}

// ฟังก์ชันดึง URL รูปภาพจาก LINE
function getImageUrl(messageId) {
  const url = 'https://api-data.line.me/v2/bot/message/' + messageId + '/content';
  const response = UrlFetchApp.fetch(url, {
    headers: {
      'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN
    }
  });
  
  // อัปโหลดภาพไป Google Drive เพื่อใช้ใน Roboflow
  const blob = response.getBlob();
  const file = DriveApp.createFile(blob);
  file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
  return file.getDownloadUrl();
}

// ฟังก์ชันประมวลผลภาพด้วย Roboflow และวิเคราะห์โรคผิวหนัง
function processImageWithRoboflow(imageUrl) {
  const url = ROBOFLOW_API_URL + '?api_key=' + ROBOFLOW_API_KEY + '&image=' + encodeURIComponent(imageUrl);
  
  const response = UrlFetchApp.fetch(url, {
    method: 'POST',
    muteHttpExceptions: true
  });
  
  const data = JSON.parse(response.getContentText());
  const predictions = data.predictions;
  
  // เก็บผลการตรวจจับโรคที่มี confidence >= 0.60
  let detectedDiseases = [];
  
  for (let disease in predictions) {
    const confidence = predictions[disease].confidence;
    if (confidence >= 0.60) {
      detectedDiseases.push({
        name: disease,
        confidence: (confidence * 100).toFixed(2)
      });
    }
  }
  
  // สร้างข้อความผลลัพธ์
  let resultMessage = 'ผลการวิเคราะห์ภาพโรคผิวหนัง\n\n';
  
  if (detectedDiseases.length === 0) {
    resultMessage += 'ไม่พบโรคผิวหนังที่มีความน่าเชื่อถือสูง (ความมั่นใจ >= 60%)\n';
  } else {
    detectedDiseases.forEach(disease => {
      const diseaseInfo = DISEASE_DESCRIPTIONS[disease.name] || {
        name: disease.name,
        description: 'ไม่พบข้อมูลโรคนี้ในระบบ',
        treatment: 'กรุณาปรึกษาแพทย์เพื่อวินิจฉัยเพิ่มเติม'
      };
      resultMessage += `โรค: ${diseaseInfo.name}\n`;
      resultMessage += `ความมั่นใจ: ${disease.confidence}%\n`;
      resultMessage += `คำอธิบาย: ${diseaseInfo.description}\n`;
      resultMessage += `การรักษาเบื้องต้น: ${diseaseInfo.treatment}\n\n`;
    });
  }
  
  resultMessage += 'คำแนะนำ: ผลการวิเคราะห์นี้เป็นเพียงการประเมินเบื้องต้น โปรดปรึกษาแพทย์ผิวหนังเพื่อการวินิจฉัยที่แม่นยำ';
  
  return resultMessage;
}

// ฟังก์ชันส่งข้อความตอบกลับไปยัง LINE
function replyToLine(replyToken, message) {
  const url = 'https://api.line.me/v2/bot/message/reply';
  UrlFetchApp.fetch(url, {
    headers: {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN
    },
    method: 'POST',
    payload: JSON.stringify({
      replyToken: replyToken,
      messages: [message]
    })
  });
}

  1. อธิบายส่วนสำคัญของโค้ด
    • การเชื่อมต่อ LINE: ใช้ CHANNEL_ACCESS_TOKEN เพื่อเชื่อมกับ LINE API
    • ดึงภาพ: ฟังก์ชัน getImageUrl ดึงภาพจาก LINE และอัปโหลดไป Google Drive เพื่อให้ Roboflow ใช้งาน
    • วิเคราะห์ภาพ: ฟังก์ชัน processImageWithRoboflow ส่งภาพไป Roboflow และรับผลลัพธ์ (เช่น โรคและความมั่นใจ)
    • ส่งผลลัพธ์: ฟังก์ชัน replyToLine ส่งข้อความกลับไปยังผู้ใช้พร้อมคำอธิบายโรค
  2. เผยแพร่โค้ด
    • ใน Google Apps Script คลิก “Deploy” > “New Deployment” > เลือก “Web app”
    • ตั้งค่า:
      • Execute as: Me
      • Who has access: Anyone
    • คัดลอก URL ที่ได้ (เช่น https://script.google.com/macros/s/…/exec)
    • ไปที่ LINE Developers ตั้งค่า Webhook URL เป็น URL นี้

สิ่งที่ได้: โค้ดที่เชื่อม LINE กับ Roboflow และพร้อมใช้งาน


ขั้นตอนที่ 4: ทดสอบระบบ

  1. เพิ่ม Bot เป็นเพื่อนใน LINE
    • สแกน QR Code จาก LINE Developers เพื่อเพิ่ม Bot
  2. ส่งภาพทดสอบ
    • ส่งภาพผิวหนังที่มีรอยโรคไปยัง Bot
    • ตรวจสอบว่าผลลัพธ์ที่ได้มีชื่อโรค ความมั่นใจ และคำอธิบาย
  3. แก้ไขข้อผิดพลาด
    • หาก Bot ไม่ตอบ ตรวจสอบ:
      • CHANNEL_ACCESS_TOKEN และ ROBOFLOW_API_KEY ถูกต้องหรือไม่
      • Webhook URL ถูกตั้งค่าใน LINE Developers หรือไม่
      • Roboflow ส่งผลลัพธ์ JSON ในรูปแบบที่คาดไว้หรือไม่

สิ่งที่ได้: ระบบที่ทำงานได้จริง ผู้ใช้ส่งภาพแล้วได้ผลลัพธ์ทันที


ขั้นตอนที่ 5: นำไปเผยแพร่บนเว็บไซต์

  1. เขียนคำอธิบายสำหรับเว็บไซต์
    • อธิบายว่า Bot นี้ทำอะไรได้ (เช่น วิเคราะห์ภาพโรคผิวหนังและให้คำแนะนำ)
    • ใส่ขั้นตอนการใช้งาน เช่น “เพิ่มเพื่อนใน LINE แล้วส่งภาพผิวหนัง”
    • เน้นว่าเป็นเครื่องมือช่วยเหลือเบื้องต้น ต้องพบแพทย์เพื่อยืนยัน

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *