ตัวอย่างโค้ด
Node.js
บอทตอบอัตโนมัติแบบครบ ใช้ Express เปลี่ยนฟังก์ชัน askAi เป็น AI ที่คุณใช้
bash
npm install expressbot.mjs
import crypto from 'node:crypto';
import express from 'express';
const BASE = 'https://office.takkub.com/api/v1';
const AUTH = { Authorization: `Bearer ${process.env.TAKKUB_API_KEY}` };
const SECRET = process.env.TAKKUB_WEBHOOK_SECRET;
// เรียก AI ของคุณ รับประวัติ คืนข้อความตอบ
async function askAi(history) {
throw new Error('ใส่โค้ดเรียก AI ตรงนี้');
}
function verify(raw, timestamp, signature) {
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = 'v1=' + crypto.createHmac('sha256', SECRET).update(`${timestamp}.${raw}`).digest('hex');
const a = Buffer.from(expected);
const b = Buffer.from(signature || '');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
async function handle(event) {
const threadId = event.thread.id;
const thread = await (await fetch(`${BASE}/threads/${threadId}`, { headers: AUTH })).json();
// คนในร้านกำลังดูแลอยู่ บอทไม่แทรก
if (thread.data.state === 'working' || !thread.data.can_reply) return;
const list = await (await fetch(`${BASE}/threads/${threadId}/messages?limit=30`, { headers: AUTH })).json();
const history = list.data.messages.filter((m) => m.text).map((m) => ({
role: m.from === 'customer' ? 'user' : 'assistant',
content: m.text,
}));
const answer = await askAi(history);
await fetch(`${BASE}/threads/${threadId}/messages`, {
method: 'POST',
headers: { ...AUTH, 'Content-Type': 'application/json' },
body: JSON.stringify({ text: answer, client_id: `reply-${event.id}` }),
});
}
const app = express();
app.post('/takkub', express.raw({ type: 'application/json' }), (req, res) => {
const raw = req.body.toString('utf8');
if (!verify(raw, req.get('x-takkub-timestamp'), req.get('x-takkub-signature'))) {
return res.sendStatus(401);
}
// ตอบก่อน แล้วค่อยเรียก AI เพราะต้องตอบภายใน 5 วินาที
res.sendStatus(200);
const event = JSON.parse(raw);
if (event.event === 'message.received') handle(event).catch(console.error);
});
app.listen(3000);