https://universe.roboflow.com/tungro-tqtks/rice-disease-rwuhc
const LINE_TOKEN = 'xxxxxx';
const ROBOFLOW_API_URL = 'https://serverless.roboflow.com/rice-disease-rwuhc/3';
const ROBOFLOW_API_KEY = '4NvR9g70FGKwuhk6zmiG';
function doPost(e) {
const data = JSON.parse(e.postData.contents);
const event = data.events[0];
if (event.type === 'message') {
const replyToken = event.replyToken;
let botReply = 'ไม่สามารถประมวลผลได้ในตอนนี้';
try {
if (event.message.type === 'image') {
const base64Image = getLineImageBase64(event.message.id);
const roboflowResult = processImageWithRoboflowForm(base64Image);
botReply = roboflowResult || 'ไม่พบข้อมูลที่ตรวจจับได้';
} else {
botReply = 'กรุณาส่งภาพมาเพื่อตรวจสอบ';
}
} catch (err) {
Logger.log('Roboflow Error: ' + err);
botReply = 'เกิดข้อผิดพลาดในการติดต่อ Roboflow';
}
sendMessage(replyToken, { type: 'text', text: botReply.substring(0, 2000) });
}
}
function sendMessage(replyToken, message) {
UrlFetchApp.fetch('https://api.line.me/v2/bot/message/reply', {
method: 'post',
contentType: 'application/json',
headers: { Authorization: 'Bearer ' + LINE_TOKEN },
payload: JSON.stringify({ replyToken, messages: [message] })
});
}
function getLineImageBase64(messageId) {
const url = `https://api-data.line.me/v2/bot/message/${messageId}/content`;
const response = UrlFetchApp.fetch(url, {
headers: { Authorization: 'Bearer ' + LINE_TOKEN },
muteHttpExceptions: true
});
if (response.getResponseCode() !== 200) {
throw new Error('ไม่สามารถดึงข้อมูลรูปภาพได้');
}
return Utilities.base64Encode(response.getBlob().getBytes());
}
function processImageWithRoboflowForm(base64Image) {
const url = `${ROBOFLOW_API_URL}?api_key=${ROBOFLOW_API_KEY}`;
const response = UrlFetchApp.fetch(url, {
method: 'post',
contentType: 'application/x-www-form-urlencoded',
payload: base64Image,
muteHttpExceptions: true
});
Logger.log(response.getContentText());
const data = JSON.parse(response.getContentText());
const predictions = data.predictions || [];
if (predictions.length === 0) {
return 'ไม่พบข้อมูลในภาพ';
}
// หา prediction ที่มีค่า confidence สูงที่สุด
const bestPrediction = predictions.reduce((max, current) =>
current.confidence > max.confidence ? current : max
);
// แมปชื่อ class เป็นคำอธิบายภาษาไทย
const classNames = {
'Brown Spot Disease': 'โรคใบจุดสีน้ำตาล',
'Dirty Panicle Disease': 'โรครวงข้าวสกปรก',
'Groundnut_Late_leaf_spot': 'โรคใบจุดปลายใบถั่วลิสง',
'Groundnut_Rust': 'โรคราสนิมถั่วลิสง',
'Narrow Brown Spot Disease': 'โรคใบขีดสีน้ำตาล',
'Rice Blast Disease': 'โรคไหม้ข้าว',
'Rice Blast Disease-': 'โรคไหม้ข้าว',
'Rice-Blast-Disease': 'โรคไหม้ข้าว',
'Rice_Bacterial_Blight': 'โรคขอบใบแห้ง (แบคทีเรีย)',
'Rice_Brown_spot': 'โรคใบจุดสีน้ำตาล',
'Tomato_Botrytis': 'โรคราเทาในมะเขือเทศ',
'Tomato_Early_Blight': 'โรคใบไหม้มะเขือเทศระยะต้น',
'Wheat_Loose_mut': 'โรคเมล็ดดำในข้าวสาลี',
'Wheat_Steam_rust': 'โรคราสนิมลำต้นข้าวสาลี',
'bercak_coklat': 'โรคใบจุดสีน้ำตาล',
'blas': 'โรคไหม้ข้าว',
'brown_spot_disease': 'โรคใบจุดสีน้ำตาล',
'dirty_panicle_disease': 'โรครวงข้าวสกปรก',
'early stage': 'ระยะเริ่มต้นของโรค'
};
const diseaseName = classNames[bestPrediction.class] || bestPrediction.class;
const confidencePercent = (bestPrediction.confidence * 100).toFixed(2);
return `ผลการวิเคราะห์: ${diseaseName}\nความมั่นใจ: ${confidencePercent}%`;
}