1. Giới thiệu dự án: Chuyển đổi số điện thoại WhatsApp của bạn thành trợ lý AI
Nếu bạn đang tìm kiếm cách biến số điện thoại WhatsApp của mình thành một trợ lý thông minh có thể hiểu văn bản, hình ảnh hay thậm chí cả tin nhắn thoại mà không cần viết mã nguồn từ đầu, thì dự án này chính là lựa chọn phù hợp cho bạn. Về bản chất, đây là một chương trình điều phối được xây dựng trên nền tảng Node.js, kết nối một đầu với số điện thoại WhatsApp qua API của Wassenger và đầu kia gọi tới mô hình GPT của OpenAI để xử lý và phân tích nội dung tin nhắn người dùng. Sau vài ngày triển khai và kiểm thử, tôi nhận thấy giá trị lớn nhất của giải pháp này nằm ở khả năng cung cấp một khuôn khổ dễ tùy chỉnh, sẵn sàng sử dụng, giúp bạn nhanh chóng tạo ra một trợ lý AI phù hợp với nhu cầu kinh doanh của mình, dù đó là hỗ trợ sản phẩm, xử lý đặt lịch hay đơn giản là trả lời các câu hỏi thông tin.
Ý tưởng cốt lõi của giải pháp rất rõ ràng: nó lắng nghe các tin nhắn WhatsApp được chuyển tiếp qua Wassenger, sử dụng khả năng đa phương tiện mạnh mẽ của OpenAI (GPT-4o hoặc GPT-4 Turbo) để hiểu ý định của người dùng, bất kể là văn bản, âm thanh hay hình ảnh, sau đó tạo ra phản hồi phù hợp rồi gửi lại qua Wassenger. Quá trình hoàn toàn tự động hóa, bạn chỉ cần cấu hình một lần duy nhất. Với các doanh nghiệp vừa và nhỏ, lập trình viên độc lập hoặc cá nhân muốn thử nghiệm quy trình tự động hóa AI, đây là điểm khởi đầu có chi phí tương đối kiểm soát và tính năng đầy đủ.
2. Kiến trúc và nguyên lý hoạt động
Trước khi bắt đầu, việc hiểu rõ cách thức hoạt động của toàn bộ hệ thống là rất quan trọng. Điều này sẽ giúp bạn nhanh chóng xác định lỗi nếu gặp sự cố và hiểu rõ mục đích của từng phần cấu hình, từ đó tùy chỉnh hiệu quả hơn.
2.1 Công nghệ sử dụng và cách hoạt động
Toàn bộ dự án có thể xem như một pipeline gồm ba thành phần cốt lõi:
- Lớp nhận tin nhắn (Wassenger): Đây là cổng giao tiếp hợp lệ với API chính thức của WhatsApp. Wassenger, một nhà cung cấp dịch vụ API WhatsApp Business thương mại, đảm nhiệm việc xử lý giao tiếp phức tạp với máy chủ Meta, quản lý phiên làm việc và hàng đợi tin nhắn. Chương trình robot của bạn không trực tiếp kết nối với API của Meta (cần thẩm định và tư cách phức tạp), mà thay vào đó sử dụng webhook do Wassenger cung cấp để nhận và gửi tin nhắn. Khi người dùng gửi tin nhắn tới số điện thoại WhatsApp của bạn, Wassenger sẽ nắm giữ tin nhắn đó và đẩy dưới dạng yêu cầu HTTP POST (sự kiện webhook) tới địa chỉ máy chủ bạn đã chỉ định.
- Lớp xử lý AI (API OpenAI + mã nguồn dự án): Đây là "bộ não" của robot. Máy chủ (có thể là máy tính cục bộ hoặc máy chủ đám mây) chạy chương trình Node.js này chứa máy chủ HTTP chuyên nhận webhook từ Wassenger. Khi nhận được tin nhắn, chương trình thực hiện nhiều bước xử lý tiền xử lý: kiểm tra người gửi có trong danh sách đen, cuộc trò chuyện đã được gán cho nhân viên hỗ trợ hay chưa, loại tin nhắn (văn bản, âm thanh, hình ảnh) có được hỗ trợ hay không. Sau khi vượt qua các bước kiểm tra, chương trình gửi nội dung tin nhắn người dùng (văn bản, hoặc mô tả từ âm thanh/hình ảnh đã chuyển đổi) cùng với chỉ dẫn vai trò đã định trước tới API Chat Completions của OpenAI. Mô hình GPT sẽ tạo ra văn bản phản hồi dựa trên ngữ cảnh này.
- Lớp gửi tin nhắn và định tuyến (mã nguồn dự án + API Wassenger): Đây là "tay nghề thực thi". Sau khi nhận được văn bản phản hồi từ AI, chương trình sẽ kiểm tra xem có cần chuyển đổi thành âm thanh (theo cấu hình). Sau đó gọi API của Wassenger để gửi nội dung phản hồi cuối cùng (văn bản hoặc tệp âm thanh) về cuộc trò chuyện WhatsApp tương ứng. Đồng thời, chương trình cũng chịu trách nhiệm duy trì lịch sử hội thoại (để hiểu ngữ cảnh), xử lý logic nghiệp vụ, ví dụ như khi người dùng nhập "human", chuyển cuộc trò chuyện sang nhân viên hỗ trợ.
Ưu điểm của kiến trúc này nằm ở tách biệt và chuyên môn hóa. Wassenger giải quyết vấn đề tuân thủ và ổn định trong việc tích hợp WhatsApp, OpenAI cung cấp khả năng hiểu và tạo nội dung AI hàng đầu, còn mã nguồn của chúng ta tập trung vào việc tổ chức logic nghiệp vụ và tùy chỉnh. Bạn không cần phải trở thành chuyên gia về API WhatsApp hay mô hình ngôn ngữ lớn để xây dựng một trợ lý mạnh mẽ.
2.2 Tại sao chọn giải pháp này?
Trên thị trường có nhiều cách xây dựng chatbot, từ các nền tảng không mã hóa như Dialogflow, ManyChat, đến các thư viện ngược như whatsapp-web.js của Python. Tuy nhiên, giải pháp này mang lại lợi thế riêng trong một số tình huống:
- Tuân thủ và độ ổn định: Sử dụng API thương mại chính thức (qua Wassenger) tránh rủi ro bị khóa tài khoản do kỹ thuật ngược, đảm bảo tỷ lệ giao nhận tin nhắn cao.
- Tính năng mạnh mẽ và tiên tiến: Tích hợp mô hình đa phương tiện GPT mới nhất, xử lý hình ảnh và âm thanh, hiểu biết và chất lượng phản hồi vượt xa các công cụ truyền thống hoặc mô hình nhỏ.
- Tùy chỉnh cao: Mã nguồn hoàn toàn mở, bạn có thể sửa đổi mọi phần. Đặc biệt là tính năng "gọi hàm", cho phép AI kích hoạt mã do bạn tự định nghĩa (ví dụ: truy vấn cơ sở dữ liệu, gọi API bên ngoài), thực hiện "tăng cường sinh thành từ truy xuất (RAG)", khiến câu trả lời của AI dựa trên dữ liệu thời gian thực và chính xác.
- Cấu trúc chi phí rõ ràng: Chi phí chủ yếu bao gồm phí dịch vụ Wassenger (theo gói tin nhắn) và phí gọi API OpenAI (theo số token). Với các trường hợp có thể dự đoán lượng truy vấn, tổng chi phí là khả thi và minh bạch.
Tuy nhiên, cũng tồn tại rào cản: bạn cần một máy chủ chạy Node.js (hoặc môi trường phát triển cục bộ) và hiểu cơ bản về JavaScript và dòng lệnh. Nhưng tài liệu dự án đã đơn giản hóa đáng kể các bước này.
3. Chuẩn bị môi trường và điều kiện tiên quyết
Trước khi chạy mã, chúng ta cần chuẩn bị tất cả những "chìa khóa" và "công cụ" cần thiết. Quá trình này giống như lắp ráp Lego, thiếu phần nào cũng không được.
3.1 Đăng ký tài khoản và lấy mã xác thực
Bạn cần đăng ký và nhận các chứng nhận từ ba dịch vụ quan trọng sau:
- Tài khoản Wassenger và API Key:
- Chức năng: Kết nối số điện thoại WhatsApp của bạn và cung cấp kênh nhận/gửi tin nhắn.
- Thực hiện: Truy cập trang web chính thức của Wassenger để đăng ký. Trong bảng điều khiển, bạn cần "thêm thiết bị", tức là liên kết số điện thoại WhatsApp (cả số cá nhân hoặc doanh nghiệp đều được). Làm theo hướng dẫn bằng cách quét mã QR bằng điện thoại để hoàn tất liên kết. Sau đó, tạo một API Key trong phần thiết lập dành cho nhà phát triển. Hãy bảo quản kỹ mã này vì nó có quyền truy cập vào tài khoản WhatsApp của bạn.
- Tài khoản OpenAI và API Key:
- Chức năng: Cung cấp trí tuệ nhân tạo cho robot.
- Thực hiện: Truy cập nền tảng OpenAI để đăng ký và đăng nhập. Trong trang API Keys, tạo một khóa mới. Lưu ý quan trọng: Do chính sách thanh toán trước của OpenAI, tài khoản mới thường cần nạp tiền (ví dụ 5 hoặc 10 USD) để bắt đầu sử dụng API. Hãy đảm bảo tài khoản có số dư, nếu không tất cả các cuộc gọi API đều thất bại.
- Tài khoản Ngrok và Auth Token (chỉ cần thiết cho phát triển cục bộ):
- Chức năng: Tạo một URL công cộng tạm thời cho chương trình chạy cục bộ (tunnel), để webhook của Wassenger có thể truy cập máy chủ cục bộ từ internet.
- Thực hiện: Nếu bạn dự định triển khai trên máy chủ đám mây (như AWS, DigitalOcean...) với IP công cộng hoặc tên miền, thì không cần Ngrok. Nếu chỉ test trên máy cục bộ, hãy đăng ký Ngrok và tìm mã token trong phần "Your Authtoken" trên bảng điều khiển.
3.2 Cài đặt môi trường phát triển cục bộ
Dự án dựa trên Node.js, nên bạn cần cài đặt nó trước.
- Cài đặt Node.js: Truy cập trang web chính thức của Node.js tải phiên bản LTS (hỗ trợ dài hạn) (v18 hoặc v20) để cài đặt. Sau khi cài xong, mở terminal (hoặc Command Prompt/PowerShell), chạy lệnh
node -vvànpm -vđể kiểm tra cài đặt thành công, hiển thị số phiên bản. - Lấy mã nguồn dự án: Có hai cách:
- Sử dụng Git (khuyến nghị): Trong terminal, điều hướng đến thư mục mong muốn (ví dụ
~/projects), chạy lệnhgit clone https://github.com/wassengerhq/whatsapp-chatgpt-bot.git. - Tải ZIP trực tiếp: Trên trang GitHub của dự án nhấn "Code", chọn "Download ZIP", giải nén vào thư mục cục bộ.
- Cài đặt phụ thuộc: Mở terminal, vào thư mục gốc của dự án (có file
package.json). Chạy lệnhnpm install. Lệnh này sẽ tự động tải tất cả các thư viện bên thứ ba cần thiết (Express.js để tạo máy chủ web, thư viện chính thức của OpenAI,...).
Lưu ý: Nếu quá trình
npm installchậm hoặc thất bại, có thể do mạng. Bạn có thể đổi nguồn npm về mirror Trung Quốc bằng lệnhnpm config set registry https://registry.npmmirror.com, sau đó chạy lạinpm install.
4. Phân tích sâu tệp cấu hình chính
Timothy của dự án là tệp config.js. Tất cả hành vi tùy chỉnh đều được điều chỉnh tại đây. Mở file này và xem từng phần.
4.1 Cấu hình khóa cơ bản
Tìm phần đầu file, điền vào các mã bạn đã lấy.
// Wassenger API Key - lấy từ bảng điều khiển Wassenger
const apiKey = process.env.API_KEY || 'YOUR_WASSENGER_API_KEY_HERE'; // Ưu tiên dùng biến môi trường
// OpenAI API Key - lấy từ nền tảng OpenAI
const openaiKey = process.env.OPENAI_API_KEY || 'YOUR_OPENAI_API_KEY_HERE';
// Ngrok Token (chỉ cần thiết cho phát triển cục bộ)
const ngrokToken = process.env.NGROK_TOKEN || 'YOUR_NGROK_AUTH_TOKEN_HERE';
Thực hành tốt nhất: Tôi khuyên dùng biến môi trường để quản lý các khóa nhạy cảm này, thay vì viết trực tiếp trong mã nguồn. Điều này an toàn hơn và thuận tiện khi chuyển đổi giữa môi trường (phát triển, sản xuất). Khi chạy chương trình, có thể thiết lập qua dòng lệnh:
API_KEY=your_key OPENAI_API_KEY=your_openai_key node main.js
4.2 Tùy chỉnh hành vi và tính cách của robot
Đây là phần giúp robot "giống bạn". Văn bản trong biến botInstructions là "cài đặt vai trò" và "hướng dẫn công việc" cho mô hình AI.
const botInstructions = `Bạn là trợ lý hỗ trợ khách hàng chuyên nghiệp làm việc cho [Tên công ty].
Bạn có thể tự giới thiệu là [Tên robot].
Bạn sẽ trò chuyện với khách hàng ngẫu nhiên muốn hỏi về sản phẩm.
[Thông tin công ty] là công ty cung cấp [Mô tả sản phẩm/dịch vụ].
Bạn là chuyên gia hỗ trợ khách hàng. Hãy lịch sự, thân thiện, sẵn lòng giúp đỡ và đồng cảm.
Từ chối lịch sự bất kỳ truy vấn nào không liên quan đến hỗ trợ khách hàng hoặc [Tên công ty].
Giữ nghiêm ngặt vai trò của bạn là trợ lý ảo hỗ trợ khách hàng của [Tên công ty].
Nếu bạn không thể hỗ trợ một số vấn đề, hãy yêu cầu người dùng nhập *chuyển nhân viên* để nói chuyện với nhân viên hỗ trợ.
Cuộc hẹn bán hàng có thể được đặt với đại diện bán hàng: hãy hỏi người dùng muốn ngày và giờ nào để sắp xếp.
Giả định múi giờ là GMT+8 (giờ Bắc Kinh).`;
Kỹ thuật viết:
- Xác định ranh giới: Rõ ràng nói với AI điều gì nên làm, điều gì không nên làm. Ví dụ: "Giữ nghiêm ngặt vai trò", "Từ chối lịch sự truy vấn không liên quan".
- Cung cấp lối thoát: Đảm bảo AI biết khi nào cần chuyển sang con người (ví dụ: "nhập chuyển nhân viên").
- Cụ thể hóa: Thay thế
[Tên công ty],[Sản phẩm]bằng thông tin thực tế để AI hoạt động tốt hơn. - Sử dụng tiếng Trung: Nếu khách hàng chủ yếu nói tiếng Trung, hãy viết hướng dẫn bằng tiếng Trung. Điều này giúp AI hiểu rõ hơn trong ngữ cảnh này.
4.3 Cấu hình chức năng và giới hạn
Đối tượng features và limits cho phép bạn kiểm soát chính xác năng lực và tiêu thụ tài nguyên của robot.
const features = {
audioInput: true, // Có xử lý tin nhắn thoại người dùng (cần chuyển thành văn bản)
audioOutput: true, // Có trả lời bằng âm thanh người dùng
audioOnly: false, // Chỉ trả lời bằng âm thanh (không văn bản). Nếu bật, audioOutput phải là true
voice: 'nova', // Giọng nói tổng hợp, chọn alloy, echo, fable, onyx, nova, shimmer. 'nova' nghe tự nhiên hơn.
voiceSpeed: 1, // Tốc độ đọc, từ 0.25 đến 4.0
imageInput: true // Có xử lý hình ảnh người dùng gửi
};
const limits = {
maxInputCharacters: 1000, // Số ký tự tối đa xử lý cho mỗi tin nhắn người dùng, phần dài sẽ bị cắt
maxOutputTokens: 800, // Số token tối đa cho phản hồi AI. Kiểm soát độ dài và chi phí. Thông thường 800-1000 là đủ.
chatHistoryLimit: 15, // Số tin nhắn lịch sử lưu cho mỗi cuộc trò chuyện. Cung cấp ngữ cảnh nhưng tăng tiêu thụ token và chi phí.
maxMessagesPerChat: 200, // Số tin nhắn tối đa robot trả lời trong một cuộc trò chuyện. Ngăn chặn spam.
maxAudioDuration: 120, // Thời lượng tối đa tin nhắn thoại người dùng (giây), quá lâu bỏ qua
maxImageSize: 2 * 1024 * 1024 // Kích thước tối đa hình ảnh người dùng (byte), 2MB
};
Kinh nghiệm chọn tham số:
maxOutputTokens: Với trường hợp hỗ trợ khách hàng, nên đặt từ 800-1000. Quá ngắn có thể không đủ thông tin, quá dài tốn kém và lộn xộn.chatHistoryLimit: Đây là yếu tố cân bằng giữa hiệu quả và chi phí. Giữ 10-15 tin nhắn giúp AI nhớ ngữ cảnh (ví dụ người dùng đã hỏi gì), nhưng mỗi tin nhắn đều thêm lịch sử, tăng tiêu thụ token tuyến tính. Nếu cuộc trò chuyện dài, có thể thêm chức năng tóm tắt lịch sử thông minh trong mã.voiceSpeed: 1.0 là tốc độ bình thường. Với hỗ trợ khách hàng, khoảng 0.9-1.1 nghe dễ chịu hơn.
5. Tính năng nâng cao: Triển khai RAG và tích hợp dữ liệu bên ngoài
Đây là phần mạnh nhất của dự án — gọi hàm (Function Calling). Cho phép AI tự động "gọi" hàm bạn viết khi cần truy xuất thông tin bên ngoài, sau đó đưa kết quả vào ngữ cảnh để tạo phản hồi cuối cùng. Điều này thực hiện "tăng cường sinh thành từ truy xuất (RAG)", khiến câu trả lời AI không chỉ dựa trên dữ liệu huấn luyện mà còn cập nhật từ dữ liệu động trong công ty.
5.1 Nguyên lý và cấu hình gọi hàm
Trong mảng functions của config.js, bạn có thể định nghĩa nhiều hàm. Mỗi hàm cần mô tả tên, mục đích, tham số (nếu có) và mã thực thi.
Khi người dùng hỏi, mô hình AI sẽ đánh giá: "Để trả lời câu hỏi này, tôi có cần một hàm cung cấp thông tin bổ sung không?" Nếu cần, nó sẽ tạm dừng tạo phản hồi, thay vào đó tạo yêu cầu gọi hàm theo định dạng cấu trúc. Chương trình bắt yêu cầu này, thực thi hàm tương ứng và đưa kết quả trở lại cho AI. AI sẽ tạo phản hồi cuối cùng dựa trên thông tin mới.
Ví dụ: Người dùng hỏi: "Gói cao nhất của các bạn giá bao nhiêu?" AI nhận thấy cần hàm "lấy giá gói", nên gọi hàm getPlanPrices bạn đã định nghĩa. Hàm này lấy thông tin từ cơ sở dữ liệu, API bảng giá hoặc mảng cứng, trả về đoạn văn bản. AI sẽ tạo câu trả lời chính xác: "Gói Enterprise cao nhất là XXX đồng/tháng, bao gồm YYY chức năng..."
5.2 Thực hành: Thêm hàm truy vấn trạng thái đơn hàng
Giả sử bạn kinh doanh trực tuyến, người dùng có thể hỏi trạng thái đơn hàng qua WhatsApp. Chúng ta thêm hàm này:
const functions = [
// ... Các hàm khác ...
{
name: 'queryOrderStatus',
description: 'Dựa trên số đơn hàng hoặc số điện thoại người dùng cung cấp, truy vấn trạng thái đơn hàng, thông tin vận chuyển...',
parameters: {
type: 'object',
properties: {
orderNumber: {
type: 'string',
description: 'Số đơn hàng người dùng cung cấp. Nếu không có, hãy cố gắng suy luận từ lịch sử hoặc hồ sơ người dùng, hoặc trả về chuỗi rỗng để yêu cầu người dùng cung cấp.'
},
phoneNumber: {
type: 'string',
description: '4 chữ số cuối số điện thoại người dùng dùng khi đặt hàng, dùng để xác minh.'
}
},
// Không bắt buộc, vì AI có thể tự suy luận từ lịch sử hoặc yêu cầu thông tin
required: []
},
run: async ({ parameters, data }) => {
// Hàm nhận tham số từ AI
const { orderNumber, phoneNumber } = parameters;
console.log(`[Gọi hàm] Truy vấn đơn hàng, tham số:`, parameters);
// 1. Kiểm tra tham số
if (!orderNumber && !phoneNumber) {
return 'Không thể truy vấn đơn hàng: Vui lòng cung cấp số đơn hàng hoặc số điện thoại đăng ký.';
}
// 2. Mô phỏng gọi API hệ thống đơn hàng (mã giả)
// Trong thực tế, đây là gọi API nội bộ hoặc truy vấn CSDL
let queryResult;
try {
// Ví dụ: gọi API giả định
// const response = await fetch(`https://your-order-api.com/query?order=${orderNumber}&phone=${phoneNumber}`);
// queryResult = await response.json();
// Để demo, mô phỏng kết quả trả về
queryResult = {
found: true,
orderNumber: orderNumber || 'IN20240528001',
status: 'Đã giao',
shippingCompany: 'Vietnam Post',
trackingNumber: 'SF1234567890',
estimatedDelivery: '2024-05-30',
items: ['Sản phẩm A x1', 'Sản phẩm B x2']
};
} catch (error) {
console.error('Gọi API đơn hàng thất bại:', error);
return 'Xin lỗi, hệ thống truy vấn đơn hàng tạm thời không truy cập được, vui lòng thử lại sau hoặc liên hệ nhân viên hỗ trợ.';
}
// 3. Tạo văn bản trả về cho AI
if (!queryResult.found) {
return `Không tìm thấy thông tin đơn hàng "${orderNumber}". Vui lòng kiểm tra lại số đơn hàng hoặc cung cấp số điện thoại đăng ký để tìm kiếm thêm.`;
}
const replyText = [
`Đã truy vấn thông tin đơn hàng **${queryResult.orderNumber}** của bạn:`,
`- **Trạng thái**: ${queryResult.status}`,
`- **Đơn vị vận chuyển**: ${queryResult.shippingCompany}`,
`- **Số tracking**: ${queryResult.trackingNumber}`,
`- **Dự kiến giao**: ${queryResult.estimatedDelivery}`,
`- **Sản phẩm**: ${queryResult.items.join(', ')}`,
`\nBạn có thể sử dụng số tracking để theo dõi chi tiết trên website đơn vị vận chuyển.`
].join('\n');
return replyText;
}
}
];
Phân tích điểm mấu chốt:
description: Phải rõ ràng. AI dựa vào mô tả này để quyết định khi nào gọi hàm. Mô tả cần nêu rõ mục đích và trường hợp áp dụng.parameters: Định nghĩa đầu vào hàm. AI sẽ cố gắng trích xuất các tham số này từ câu hỏi người dùng. Định nghĩa càng chi tiết, độ chính xác càng cao.run: Là mã thực thi. Bạn có thể làm bất cứ điều gì: gọi REST API, truy vấn CSDL MySQL/PostgreSQL, đọc file cục bộ, tính toán phức tạp,... Hàm phải trả về chuỗi, chuỗi này sẽ được đưa vào ngữ cảnh của AI.- Xử lý lỗi: Cần có try-catch trong hàm. Nếu gọi API bên ngoài thất bại, trả về thông báo thân thiện để AI có thể truyền lại cho người dùng, không để robot bị crash.
5.3 Hướng dẫn AI gọi hàm chủ động
Chỉ định hàm là chưa đủ, bạn cần thêm vào chỉ dẫn cho AI (botInstructions) để nó biết về các hàm này. Thêm vào cuối chỉ dẫn gốc:
... (các chỉ dẫn trước) ...
Khi người dùng hỏi về trạng thái đơn hàng, thông tin vận chuyển, thông tin tài khoản, bảng giá sản phẩm, tồn kho hoặc cần truy vấn thông tin động nào khác, bạn có thể sử dụng các công cụ bạn đã cung cấp để lấy dữ liệu mới nhất, đảm bảo độ chính xác của câu trả lời.
Ví dụ, nếu người dùng hỏi "Đơn hàng của tôi đi đâu rồi?", bạn có thể sử dụng hàm "queryOrderStatus".
Khi gặp vấn đề tương tự, AI sẽ ưu tiên gọi hàm để lấy dữ liệu chính xác thay vì dựa vào trí nhớ mơ hồ từ dữ liệu huấn luyện.
6. Chạy cục bộ và triển khai lên đám mây
Sau khi cấu hình xong, bạn có thể bắt đầu chạy robot. Chúng ta chia thành hai trường hợp: test cục bộ và triển khai online.
6.1 Chạy trên máy cục bộ (dùng Ngrok)
Đây là cách test nhanh nhất.
- Khởi động robot: Trong thư mục gốc dự án, mở terminal, chạy:
node main.js
hoặc dùng chế độ phát triển (tự động restart khi sửa mã):
npm run dev
- Quan sát đầu ra: Chương trình sẽ làm những việc sau:
- Kiểm tra cấu hình.
- Khởi động máy chủ web cục bộ (cổng mặc định 8080).
- Khởi động tunnel Ngrok và in ra URL công cộng tạm thời (ví dụ
https://abc123.ngrok.io). - Tự động đăng ký URL này làm webhook của Wassenger.
- Hiển thị thông báo thành công như "Bot is ready and listening...".
- Kiểm tra: Dùng một số điện thoại WhatsApp khác (hoặc phiên làm việc khác trên cùng thiết bị) gửi tin nhắn tới số điện thoại đã liên kết với Wassenger. Bạn sẽ thấy log nhận và gửi tin nhắn trong terminal và nhận phản hồi từ AI trên WhatsApp.
Vấn đề phổ biến khi chạy cục bộ:
- Cổng bị chiếm dụng: Nếu cổng 8080 bị dùng, có thể đổi bằng biến môi trường:
PORT=3000 node main.js.- Xác thực Ngrok thất bại: Kiểm tra
ngrokTokencó đúng không, hoặc thử reset token trên trang web Ngrok.- Lỗi API OpenAI: Thường là "Insufficient funds" (thiếu tiền). Đảm bảo tài khoản OpenAI đã nạp tiền.
6.2 Triển khai lên máy chủ đám mây (Ubuntu + PM2 ví dụ)
Để robot chạy 24/7, bạn cần một máy chủ đám mây. Dưới đây là ví dụ sử dụng Ubuntu và PM2 làm công cụ quản lý tiến trình.
- Chuẩn bị máy chủ:
- Mua máy chủ đám mây (như Tencent Cloud Lightweight Server, AWS EC2...), chọn bản Ubuntu 22.04 LTS.
- Kết nối SSH đến máy chủ.
- Cài đặt môi trường cơ bản:
# Cập nhật gói hệ thống
sudo apt update && sudo apt upgrade -y
# Cài đặt Node.js (dùng kho NodeSource để lấy phiên bản mới)
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs git
# Kiểm tra cài đặt
node -v
npm -v
- Triển khai mã nguồn:
# Clone mã nguồn
git clone https://github.com/wassengerhq/whatsapp-chatgpt-bot.git
cd whatsapp-chatgpt-bot
# Cài đặt phụ thuộc
npm install --production
- Cấu hình biến môi trường: Tạo hoặc chỉnh sửa tệp biến môi trường như
.env:
nano .env
Điền vào các khóa của bạn, không dùng dấu ngoặc kép:
API_KEY=your_wassenger_api_key_here
OPENAI_API_KEY=your_openai_api_key_here
WEBHOOK_URL=https://your-server-public-ip-or-domain:8080/webhook
NODE_ENV=production
PORT=8080
Quan trọng:
WEBHOOK_URLphải là IP công cộng hoặc tên miền của máy chủ, cổng (ở đây là 8080) cần mở trong tường lửa.
- Chạy bền vững với PM2:
# Cài đặt PM2 toàn cục
sudo npm install -g pm2
# Dùng PM2 khởi động ứng dụng, truyền biến môi trường từ .env
pm2 start main.js --name whatsapp-ai-bot --env .env
# Cấu hình PM2 khởi động tự động khi reboot
pm2 startup
pm2 save
# Xem log
pm2 logs whatsapp-ai-bot
- Cấu hình tường lửa và tên miền (khuyến nghị):
- Tường lửa: Đảm bảo quy tắc security group hoặc iptables cho phép lưu lượng TCP 8080 vào.
- Tên miền và HTTPS: Với môi trường sản xuất, nên dùng tên miền và cấu hình HTTPS (chứng chỉ SSL). Có thể dùng Nginx làm reverse proxy và Let's Encrypt để lấy chứng chỉ miễn phí. Lúc này
WEBHOOK_URLsẽ làhttps://bot.yourdomain.com/webhook, an toàn và ổn định hơn.
7. Giám sát, bảo trì và xử lý sự cố
Sau khi robot lên mạng, công việc bảo trì mới bắt đầu. Dưới đây là một số mẹo để giữ cho nó ổn định.
7.1 Nhật ký và giám sát
- Xem nhật ký: Dù chạy cục bộ hay dùng PM2, hãy thói quen kiểm tra log. Log ghi lại quá trình xử lý từng tin nhắn, chi tiết gọi API AI và lỗi.
- Xem log PM2:
pm2 logs whatsapp-ai-bot - Xem lỗi cụ thể:
pm2 logs whatsapp-ai-bot --err - Giám sát chỉ số quan trọng:
- Tiêu thụ API OpenAI: Định kỳ kiểm tra trang Usage trên nền tảng OpenAI để giám sát token tiêu thụ và chi phí, đánh giá xem có vượt mức dự kiến không.
- Sử dụng tin nhắn Wassenger: Kiểm tra số lượng tin nhắn còn lại trong bảng điều khiển Wassenger, tránh hết gói khiến dịch vụ gián đoạn.
- Tài nguyên máy chủ: Sử dụng
htophoặcglancesđể giám sát CPU, RAM và băng thông máy chủ.
7.2 Vấn đề thường gặp và cách xử lý
Tôi gặp nhiều vấn đề trong quá trình test và vận hành, dưới đây là bảng tra cứu nhanh:
| Hiện tượng | Nguồn gốc khả dĩ | Cách xử lý |
|---|---|---|
| Robot không trả lời tin nhắn | 1. Webhook chưa đăng ký đúng hoặc URL không truy cập được. 2. API Key Wassenger không hợp lệ hoặc thiết bị chưa kết nối. 3. Tiến trình chương trình bị crash. | 1. Kiểm tra terminal/log, đảm bảo webhook đăng ký thành công và không có lỗi. Dùng curl kiểm tra WEBHOOK\_URL có truy cập được không. 2. Đăng nhập bảng điều khiển Wassenger, kiểm tra thiết bị trực tuyến và API Key hợp lệ. 3. Kiểm tra trạng thái tiến trình PM2 (pm2 status), khởi động lại. |
| Phản hồi AI lạ hoặc lệch chủ đề | 1. Chỉ dẫn botInstructions chưa rõ ràng hoặc mâu thuẫn. 2. Lịch sử trò chuyện (chatHistoryLimit) quá dài, gây nhiễu. 3. Tham số nhiệt độ (temperature) của mô hình OpenAI quá cao (mặc định thấp). |
1. Rút gọn và củng cố chỉ dẫn, dùng ngôn ngữ chắc chắn, cụ thể, rõ ràng ranh giới. 2. Giảm chatHistoryLimit xuống 10-15 tin nhắn. 3. Có thể chỉnh tham số temperature trong mã gọi API OpenAI (bot.js), đặt từ 0.2-0.5 để đầu ra ổn định hơn. |
| Thời gian xử lý chậm, người dùng chờ lâu | 1. API OpenAI phản hồi chậm. 2. Mạng máy chủ có độ trễ cao. 3. API bên ngoài trong hàm (functions) phản hồi chậm. |
1. Hiện tượng phổ biến, có thể gửi thông báo "đang suy nghĩ" khi phản hồi đầu tiên. 2. Đảm bảo máy chủ gần khu vực người dùng hoặc vùng dịch vụ OpenAI. 3. Tối ưu hóa mã trong hàm, thiết lập timeout (ví dụ 5 giây) cho API bên ngoài, nếu quá thời gian trả về thông báo thân thiện. |
| Âm thanh không phát hoặc chuyển văn bản thất bại | 1. Định dạng âm thanh người dùng không hỗ trợ. 2. API chuyển văn bản (Whisper) của OpenAI bị lỗi hoặc quá thời gian chờ. 3. Tệp âm thanh quá lớn, vượt giới hạn maxAudioDuration. |
1. Trong templateMessages.noAudioAccepted, thiết lập thông báo fallback thân thiện. 2. Thêm logic xử lý lỗi và thử lại trong phần xử lý âm thanh. 3. Đảm bảo limits.maxAudioDuration được thiết lập hợp lý (ví dụ 120 giây). |
| Chức năng "chuyển nhân viên" không hoạt động | 1. Logic kiểm tra từ khóa "human" sai (mặc định là tiếng Anh). 2. Gọi API Wassenger thất bại, không thể phân công nhân viên. | 1. Sửa logic kiểm tra từ khóa "chuyển nhân viên" trong bot.js, hỗ trợ tiếng Trung như "chuyển nhân viên", "nhân viên hỗ trợ". 2. Kiểm tra quyền API Key Wassenger và ID nhân viên trong actions.js. |
7.3 Gợi ý tối ưu chi phí
Chi phí chính là gọi API AI. Dưới đây là cách tiết kiệm:
- Đặt giới hạn tần suất tin nhắn: Sử dụng
limits.maxMessagesPerChathợp lý để ngăn chặn người dùng gửi liên tục. - Tối ưu độ dài lịch sử trò chuyện:
chatHistoryLimitlà công cụ hai mặt. Đối với cuộc trò chuyện ngắn gọn, 10 tin nhắn là đủ. Với cuộc trò chuyện dài, có thể tăng nhưng chú ý chi phí tăng theo. - Đơn giản hóa chỉ dẫn hệ thống: Nội dung
botInstructionscũng tiêu hao token. Giữ ngôn ngữ ngắn gọn, hiệu quả nhất có thể. - Sử dụng mô hình rẻ hơn: Nếu chất lượng phản hồi không quá cao, có thể chuyển từ
gpt-4ohoặcgpt-4-turbosanggpt-3.5-turbo, giảm chi phí đáng kể. Chỉ cần chỉnh tham sốmodeltrongbot.js. - Thiết lập bộ nhớ đệm: Đối với các câu hỏi thường gặp (ví dụ "địa chỉ công ty là gì"), có thể thêm bộ nhớ đệm trong mã nguồn. Nếu người dùng hỏi trùng, trả về câu trả lời từ đệm, không cần gọi OpenAI.
Dự án này cung cấp một điểm khởi đầu cực kỳ mạnh mẽ, nhưng không phải là một hộp đen "cài xong rồi quên". Giá trị thực sự nằm ở cách bạn tinh chỉnh nó theo nhu cầu kinh doanh: thiết kế chỉ dẫn AI chính xác hơn, phát triển các hàm gọi thực tế hơn, tối ưu trải nghiệm người dùng. Bắt đầu từ câu trả lời tự động đơn giản, dần dần cải tiến, bạn hoàn toàn có thể phát triển nó thành trợ lý thông minh xử lý các quy trình kinh doanh phức tạp.