Model
https://universe.roboflow.com/kittikun/thai-coins-model/model/4
💡 ภาพรวมการทำงาน
- ผู้ใช้ส่งภาพเหรียญให้ LINE Bot
- Bot ดึงภาพจาก LINE API → แปลงเป็น Base64
- ส่งภาพไปให้ Roboflow วิเคราะห์
- Roboflow ส่งข้อมูลการตรวจจับกลับมา (class และ confidence)
- Bot สรุปผลและส่งกลับไปให้ผู้ใช้
const LINE_TOKEN = 'xxxxxxx';
const ROBOFLOW_API_URL = 'https://serverless.roboflow.com/thai-coins-model/4';
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 || [];
let coinCount = {
'1 bahts': 0,
'10 bahts': 0,
'2 bahts': 0,
'5 bahts': 0
};
predictions.forEach(prediction => {
if (prediction.confidence >= 0.60 && coinCount.hasOwnProperty(prediction.class)) {
coinCount[prediction.class]++;
}
});
const totalAmount =
coinCount['1 bahts'] * 1 +
coinCount['10 bahts'] * 10 +
coinCount['2 bahts'] * 2 +
coinCount['5 bahts'] * 5;
const totalCoins =
coinCount['1 bahts'] +
coinCount['10 bahts'] +
coinCount['2 bahts'] +
coinCount['5 bahts'];
let resultMessage = 'ผลการนับเหรียญ\n';
resultMessage += `1 บาท: ${coinCount['1 bahts']} เหรียญ\n`;
resultMessage += `10 บาท: ${coinCount['10 bahts']} เหรียญ\n`;
resultMessage += `2 บาท: ${coinCount['2 bahts']} เหรียญ\n`;
resultMessage += `5 บาท: ${coinCount['5 bahts']} เหรียญ\n`;
resultMessage += `จำนวนเหรียญทั้งหมด: ${totalCoins} เหรียญ\n`;
resultMessage += `จำนวนเงินทั้งหมด: ${totalAmount} บาท`;
return resultMessage;
}