วิธีสร้าง LINE Bot สำหรับวิเคราะห์โรคผิวหนังด้วย Roboflow
เป้าหมาย
สร้าง LINE Bot ที่ให้ผู้ใช้ส่งภาพผิวหนังผ่านแชท LINE แล้ว Bot จะวิเคราะห์ภาพโดยใช้ Roboflow เพื่อบอกว่าเป็นโรคผิวหนังอะไร พร้อมคำอธิบายและวิธีการรักษาเบื้องต้น ผลลัพธ์จะส่งกลับไปยังผู้ใช้ในรูปแบบข้อความที่เข้าใจง่าย
อุปกรณ์และสิ่งที่ต้องเตรียม
- คอมพิวเตอร์ที่มีอินเทอร์เน็ต
- บัญชี LINE Developers (ฟรี) เพื่อสร้าง LINE Bot
- บัญชี Roboflow (ฟรีสำหรับเริ่มต้น) เพื่อใช้โมเดลวิเคราะห์ภาพ
- Google Account เพื่อใช้ Google Apps Script และ Google Drive
- ความรู้พื้นฐานเกี่ยวกับการเขียนโค้ด (JavaScript เบื้องต้น)
ขั้นตอนการทำ
ขั้นตอนที่ 1: สร้าง LINE Bot
- สมัครบัญชี LINE Developers
- เข้าไปที่ LINE Developers
- สร้าง Provider และ Messaging API Channel (เลือกประเภท Bot)
- รับ Channel Access Token (คัดลอกเก็บไว้ ใช้ในโค้ด)
- ตั้งค่า Webhook
- ใน LINE Developers ไปที่แท็บ “Messaging API”
- เปิดใช้งาน Webhook และตั้งค่า URL (จะได้ในขั้นตอน Google Apps Script)
- เปิด “Allow bot to reply” เพื่อให้ Bot ตอบกลับได้
สิ่งที่ได้: LINE Bot ที่พร้อมเชื่อมต่อกับโค้ดของเรา
ขั้นตอนที่ 2: สร้างโมเดลใน Roboflow
- สมัครบัญชี Roboflow
- เข้าไปที่ Roboflow และสมัครฟรี
- สร้างโปรเจกต์ใหม่ ชื่อเช่น “Skin Diseases”
- อัปโหลดภาพและฝึกโมเดล
- รวบรวมภาพตัวอย่างโรคผิวหนัง (เช่น ภาพของหูด, กลาก, มะเร็งผิวหนัง)
- อัปโหลดภาพไปยัง Roboflow และกำหนดชื่อคลาส (เช่น BCC, Molluscum, Warts)
- ฝึกโมเดล (Roboflow จะจัดการให้อัตโนมัติ)
- รับ API URL และ API Key จากแท็บ “Deploy” ใน Roboflow
สิ่งที่ได้: โมเดล AI ที่วิเคราะห์ภาพและบอกว่าเป็นโรคอะไร
ขั้นตอนที่ 3: เขียนโค้ดใน Google Apps Script
- สร้างโปรเจกต์ใน Google Apps Script
- เข้าไปที่ Google Apps Script
- คลิก “New Project” และตั้งชื่อ เช่น “Skin Disease Bot”
- คัดลอกโค้ด
- ใช้โค้ดด้านล่าง (ปรับจากโค้ดก่อนหน้าให้เหมาะกับการสอน)
- แทนที่ 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]
})
});
}
- อธิบายส่วนสำคัญของโค้ด
- การเชื่อมต่อ LINE: ใช้ CHANNEL_ACCESS_TOKEN เพื่อเชื่อมกับ LINE API
- ดึงภาพ: ฟังก์ชัน getImageUrl ดึงภาพจาก LINE และอัปโหลดไป Google Drive เพื่อให้ Roboflow ใช้งาน
- วิเคราะห์ภาพ: ฟังก์ชัน processImageWithRoboflow ส่งภาพไป Roboflow และรับผลลัพธ์ (เช่น โรคและความมั่นใจ)
- ส่งผลลัพธ์: ฟังก์ชัน replyToLine ส่งข้อความกลับไปยังผู้ใช้พร้อมคำอธิบายโรค
- เผยแพร่โค้ด
- ใน 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: ทดสอบระบบ
- เพิ่ม Bot เป็นเพื่อนใน LINE
- สแกน QR Code จาก LINE Developers เพื่อเพิ่ม Bot
- ส่งภาพทดสอบ
- ส่งภาพผิวหนังที่มีรอยโรคไปยัง Bot
- ตรวจสอบว่าผลลัพธ์ที่ได้มีชื่อโรค ความมั่นใจ และคำอธิบาย
- แก้ไขข้อผิดพลาด
- หาก Bot ไม่ตอบ ตรวจสอบ:
- CHANNEL_ACCESS_TOKEN และ ROBOFLOW_API_KEY ถูกต้องหรือไม่
- Webhook URL ถูกตั้งค่าใน LINE Developers หรือไม่
- Roboflow ส่งผลลัพธ์ JSON ในรูปแบบที่คาดไว้หรือไม่
- หาก Bot ไม่ตอบ ตรวจสอบ:
สิ่งที่ได้: ระบบที่ทำงานได้จริง ผู้ใช้ส่งภาพแล้วได้ผลลัพธ์ทันที
ขั้นตอนที่ 5: นำไปเผยแพร่บนเว็บไซต์
- เขียนคำอธิบายสำหรับเว็บไซต์
- อธิบายว่า Bot นี้ทำอะไรได้ (เช่น วิเคราะห์ภาพโรคผิวหนังและให้คำแนะนำ)
- ใส่ขั้นตอนการใช้งาน เช่น “เพิ่มเพื่อนใน LINE แล้วส่งภาพผิวหนัง”
- เน้นว่าเป็นเครื่องมือช่วยเหลือเบื้องต้น ต้องพบแพทย์เพื่อยืนยัน