Hiện nay, nhiều doanh nghiệp hơn bao giờ hết sử dụng chatbot thông qua WhatsApp để tương tác với khách hàng, nhận biết nhu cầu của họ và thu thập dữ liệu cần thiết. Tuy nhiên, quá trình thu thập và tổ chức dữ liệu như vậy mang lại nhiều thách thức về mặt hiệu quả. WhatsApp Flows sẽ hỗ trợ bạn giải quyết vấn đề này.
Bằng cách tích hợp chatbot với WhatsApp Flows, doanh nghiệp có thể diễn giải thông tin khách hàng mà mình nhận được hiệu quả hơn. Sau đó, Chatbot có thể bắt đầu các Flow cụ thể được điều chỉnh để thu thập dữ liệu, tùy theo ngữ cảnh của cuộc trò chuyện.
Trong hướng dẫn này, bạn sẽ xây dựng một chatbot bằng Llama 2 và Python, kết nối chatbot này với WhatsApp Flows để nâng cao khả năng thu thập dữ liệu. Khi làm vậy, bạn sẽ trải nghiệm cách WhatsApp Flows nâng cao sự thân thiện với người dùng của trải nghiệm chatbot và cải thiện độ chính xác cũng như hiệu quả của việc thu thập dữ liệu khách hàng.
Chatbot sẽ phản hồi yêu cầu và gợi ý của người dùng bằng WhatsApp Flows để thu thập dữ liệu. Cụ thể hơn, người dùng sẽ có thể trò chuyện với chatbot, tìm kiếm thông tin về các dịch vụ mà một khách sạn hư cấu ở Tây Ban Nha cung cấp và liên hệ với công ty đó để được hỗ trợ.
Chatbot sẽ sử dụng các lệnh if
đơn giản kết hợp với mô hình Llama 2 tiêu chuẩn để cung cấp quyền truy cập vào cơ sở trí thức tổng quát đầy đủ.
Phần 1:
Tạo Flow bằng cách sử dụng Công cụ tạo Flow trong Trình quản lý WhatsApp.
Phần 2:
Chuyển đổi mô hình Llama 2 từ GGML sang GGUF.
Trong phần này, bạn sẽ sử dụng Công cụ tạo Flow để tạo một số Flow. Ngoài ra, bạn có thể sử dụng Flows API mà chúng tôi không nêu chi tiết ở đây.
Để làm theo, hãy đảm bảo bạn:
Đã cài đặt ngrok.
Có tài khoản nhà phát triển trên Meta for Developersđã được xác minh và quen thuộc với API Đám mây do Meta cung cấp.
Cuối cùng, hãy đảm bảo bạn hoàn thành các bước cần thiết để sử dụng Flow. Bạn cũng có thể xem trước mã dự án hoàn chỉnh.
Để bắt đầu, hãy điều hướng đến trang Flow trong Tài khoản WhatsApp Business của bạn. Nếu đây là lần đầu tiên tương tác với Flow, bạn sẽ thấy nút có tiêu đề Bắt đầu xây dựng Flow. Nếu không, bạn sẽ thấy nút Tạo Flow ở phía trên bên phải của trang.
Nhấp vào nút hiển thị để mở hộp thoại nơi bạn có thể nhập một số chi tiết về Flow của mình:
Đầu tiên, bạn sẽ tạo Flow tạo điều kiện cho người dùng tìm kiếm thông tin về các dịch vụ mà công ty khách sạn cung cấp.
Nhập tên vào trường thông tin Tên. Sau đó, bên dưới menu thả xuống Hạng mục, chọn Đăng ký và đặt menu thả xuống Mẫu thành Không có. Nhấp vào Gửi.
Trang tiếp theo hiển thị công cụ chỉnh sửa ở bên trái và bản xem trước ở bên phải.
Thay thế nội dung của công cụ chỉnh sửa bằng đánh dấu JSON cho Flow của bạn. (Bạn có thể tìm hiểu thêm về Flow JSON trong tài liệu dành cho nhà phát triển.)
Lưu Flow. Bản xem trước của bạn sẽ giống với ảnh dưới đây:
Flow này bao gồm một màn hình để người dùng nhập thông tin chi tiết, chọn dịch vụ mà họ quan tâm và điền tin nhắn bổ sung nếu họ muốn. Khi người dùng nhấp vào Gửi, Flow sẽ đóng và gửi dữ liệu đã thu thập đến doanh nghiệp của bạn để xử lý. Một phương pháp truyền dữ liệu này liên quan đến việc sử dụng điểm cuối. Tuy nhiên, dự án này không cần điểm cuối. Dữ liệu sẽ được chuyển đến cùng một webhook dùng để chạy chatbot.
Bạn có thể thực hiện quá trình chuyển này bằng cách sử dụng hành động. Xác định dữ liệu cần chuyển sang màn hình tiếp theo bằng cách sử dụng đối tượng payload
:
... "on-click-action": { "name": "complete", "payload": { "firstname": "${form.first_name}", "secondname": "${form.second_name}", "services_interested": "${form.services_interested}", "additional_info": "${form.additional_info}", "flow_key": "agentconnect" } } ...
Trong đoạn mã, hành động nhấp vào nút của người dùng sẽ kích hoạt on-click-action
, từ đó thu thập dữ liệu trong phần tải dữ liệu. Sau đó, phần tải dữ liệu sẽ được gửi đến máy chủ webhook và đóng Flow thông qua hành động complete
.
Bạn có thể chỉ định các khóa payload
như với bất kỳ biến nào. Các giá trị tương ứng có thể đại diện cho đối tượng dữ liệu hoặc tên của các thành phần trong Flow (tương tự thuộc tính tên của mẫu HTML).
Lúc này, bạn có thể xem Flow trong bối cảnh hoạt động thực tế và mô phỏng trải nghiệm người dùng thực sự bằng cách sử dụng nút chuyển Bản xem trước có tính tương tác:
Sau khi thử nghiệm, bạn có thể đăng Flow vì Flow đang ở trạng thái Bản nháp. Để làm việc này, hãy mở menu bên phải Lưu và nhấp vào Đăng. Flow giờ đã sẵn sàng và dùng được.
Bây giờ, bạn sẽ tạo Flow "Liên hệ với chúng tôi".
Bắt đầu bằng cách lặp lại quy trình tạo Flow ban đầu như trên. Đối với hạng mục, chọn Liên hệ với chúng tôi. Thay thế nội dung của công cụ chỉnh sửa bằng đánh dấu JSON để hiển thị như sau:
Đăng Flow và tiếp tục đến phần tiếp theo để thiết lập chatbot. Phần này có ba hàm - send_message
, flow_details
và flow_reply_processor
- chứa logic quan trọng để gửi Flow đến người dùng. Phần này cũng bao gồm logic để xử lý phần tải dữ liệu nhận được của Flow. Vì vậy, bạn nên xem qua ngay cả khi đã xây dựng chatbot.
Tiếp theo, bạn sẽ cấu hình chatbot và tích hợp chatbot vào Flow.
Trước khi tiếp tục, hãy đảm bảo bạn:
Có kiến thức cơ bản và phiên bản mới nhất của Python
Đã tải xuống phiên bản HuggingFace của Llama 2. Mô hình HuggingFace Llama 2 không yêu cầu thêm công cụ hoặc phần cứng chuyên dụng. Bạn cũng có thể sử dụng phiên bản chính thức nhưng sẽ phải thiết lập thêm.
Có ID số điện thoại và mã truy cập của tài khoản
Có công cụ chỉnh sữa mã
Chatbot sẽ hoạt động thông qua tập lệnh xác định trước được thiết kế để hỗ trợ người dùng dựa trên thông tin đầu vào của họ. Khi tương tác lần đầu, chatbot sẽ đưa ra văn bản chào mừng được cá nhân hóa và menu dựa trên văn bản tùy thuộc vào tin nhắn của người dùng. Những tùy chọn này đáp ứng các nhu cầu cụ thể: truy vấn các dịch vụ mà khách sạn cung cấp, liên hệ với một trong các nhân viên tổng đài của khách sạn hoặc tương tác với chatbot do Llama cung cấp.
Việc phản hồi bằng ký tự chữ và số sẽ kết nối người dùng với dịch vụ hoặc hành động tương ứng. Tuy nhiên, mọi cách phản hồi khác đều sẽ kích hoạt chức năng chatbot mặc định, hỗ trợ những câu hỏi tổng quát hoặc hướng dẫn chi tiết cho người dùng về các dịch vụ có sẵn dựa trên nội dung trò chuyện thêm.
Để bắt đầu, hãy tạo một môi trường ảo bằng cách chạy lệnh dưới đây trong thiết bị đầu cuối của bạn:
python -m venv venv
Kích hoạt:
source venv/bin/activate
Sau đó, cài đặt các gói cần thiết:
pip install requests flask llama-cpp-python python-dotenv
Sử dụng Flask
để tạo các tuyến và tương tác với API, requests
để gửi yêu cầu internet, llama-cpp-python
để tương tác với mô hình và python-dotenv
để tải biến môi trường.
Tiếp theo, hãy tạo file môi trường có tên .env
và nội dung sau đây, gán các giá trị phù hợp. (Bạn có thể sử dụng bất kỳ chuỗi nào cho VERIFY_TOKEN
.)
TOKEN = ACCESS_TOKEN = PHONE_NUMBER_ID =
Trong cùng thư mục như trên, tạo file có tên main.py
và bắt đầu bằng cách thêm các gói bạn sẽ sử dụng:
import os import re import time import uuid import requests from dotenv import load_dotenv from flask import Flask, request, make_response, json from llama_cpp import Llama
Bây giờ, hãy khởi tạo các biến và lớp. Đoạn mã này cũng sẽ khởi tạo Flask và gọi phương thức load_dotenv()
để hỗ trợ tải biến:
app = Flask(__name__) load_dotenv() PHONE_NUMBER_ID = os.getenv('PHONE_NUMBER_ID') url = f"https://graph.facebook.com/v18.0/{PHONE_NUMBER_ID}/messages" TOKEN = os.getenv('TOKEN') ACCESS_TOKEN = os.getenv('ACCESS_TOKEN') code_prompt_texts = ["Contact us", "Chat with our chatbot", "YES", "NO"] service_list = [ "Accommodation Services", "Spa Services", "Dining Services", "Recreational Facilities", "Business & Conference Services", "Transportation Services", "Accessibility Services", "Pet-Friendly Services" ]
service_list lưu trữ các dịch vụ mà khách sạn cung cấp. Danh sách code_prompt_texts
chứa các tùy chọn tương ứng với thông tin đầu vào của người dùng, là 1, 2, Y và N bằng cách sử dụng hàm dưới đây. Hàm dưới đây sẽ ánh xạ câu trả lời của người dùng đến tùy chọn tương ứng.
def extract_string_from_reply(user_input): match user_input: case "1": user_prompt = code_prompt_texts[0].lower() case "2": user_prompt = code_prompt_texts[1].lower() case "Y": user_prompt = code_prompt_texts[2].lower() case "N": user_prompt = code_prompt_texts[3].lower() case _: user_prompt = str(user_input).lower() return user_prompt
Mã này chuyển đổi các chuỗi thành chữ viết thường để ngăn chặn tình trạng không khớp khi chạy logic có điều kiện. Cấu trúc match…case
so khớp gợi ý mà người dùng nhập với thông tin đầu ra. Ví dụ: người dùng nhập "1" sẽ kích hoạt chức năng "Contact us"
.
Tiếp theo, hàm sau đây chứa lệnh if
sử dụng gói Python RegEx (re
) để tìm kiếm các cụm từ nhất định trong tin nhắn của khách hàng nhằm quyết định loại phản hồi sẽ gửi cho người dùng:
def user_message_processor(message, phonenumber, name): user_prompt = extract_string_from_reply(message) if user_prompt == "yes": send_message(message, phonenumber, "TALK_TO_AN_AGENT", name) elif user_prompt == "no": print("Chat terminated") else: if re.search("service", user_prompt): send_message(message, phonenumber, "SERVICE_INTRO_TEXT", name) elif re.search( "help|contact|reach|email|problem|issue|more|information", user_prompt ): send_message(message, phonenumber, "CONTACT_US", name) elif re.search("hello|hi|greetings", user_prompt): if re.search("this", user_prompt): send_message(message, phonenumber, "CHATBOT", name) else: send_message(message, phonenumber, "SEND_GREETINGS_AND_PROMPT", name) else: send_message(message, phonenumber, "CHATBOT", name)
Giờ đây, tin nhắn như "Hello there"
sẽ kích hoạt phương thức send_message
với SEND_GREETINGS_AND_PROMPT
làm đối số thứ hai. Dưới đây là phương thức send_message
. Hãy thay thế nội dung giữa <xxx>
cho thích hợp.
def send_message(message, phone_number, message_option, name): greetings_text_body = ( "\nHello " + name + ". Welcome to our hotel. What would you like us to help you with?\nPlease respond with a numeral between 1 and 2.\n\n1. " + code_prompt_texts[0] + "\n2. " + code_prompt_texts[1] + "\n\nAny other reply will connect you with our chatbot." ) # loading the list's entries into a string for display to the user services_list_text = "" for i in range(len(service_list)): item_position = i + 1 services_list_text = ( f"{services_list_text} {item_position}. {service_list[i]} \n" ) service_intro_text = f"We offer a range of services to ensure a comfortable stay, including but not limited to:\n\n{services_list_text}\n\nWould you like to connect with an agent to get more information about the services?\n\nY: Yes\nN: No" contact_flow_payload = flow_details( flow_header="Contact Us", flow_body="You have indicated that you would like to contact us.", flow_footer="Click the button below to proceed", flow_id=str("<FLOW-ID>"), flow_cta="Proceed", recipient_phone_number=phone_number, screen_id="CONTACT_US", ) agent_flow_payload = flow_details( flow_header="Talk to an Agent", flow_body="You have indicated that you would like to talk to an agent to get more information about the services that we offer.", flow_footer="Click the button below to proceed", flow_id=str("<FLOW-ID>"), flow_cta="Proceed", recipient_phone_number=phone_number, screen_id="TALK_TO_AN_AGENT", ) match message_option: case "SEND_GREETINGS_AND_PROMPT": payload = json.dumps( { "messaging_product": "whatsapp", "to": str(phone_number), "type": "text", "text": {"preview_url": False, "body": greetings_text_body}, } ) case "SERVICE_INTRO_TEXT": payload = json.dumps( { "messaging_product": "whatsapp", "to": str(phone_number), "type": "text", "text": {"preview_url": False, "body": service_intro_text}, } ) case "CHATBOT": LLM = Llama( model_path="/home/incognito/Downloads/llama-2-7b-chat.ggmlv3.q8_0.gguf.bin", n_ctx=2048, ) # create a text prompt prompt = message # generate a response (takes several seconds) output = LLM(prompt) payload = json.dumps( { "messaging_product": "whatsapp", "to": str(phone_number), "type": "text", "text": { "preview_url": False, "body": output["choices"][0]["text"], }, } ) case "CONTACT_US": payload = contact_flow_payload case "TALK_TO_AN_AGENT": payload = agent_flow_payload case "FLOW_RESPONSE": payload = json.dumps( { "messaging_product": "whatsapp", "to": str(phone_number), "type": "text", "text": {"preview_url": False, "body": message}, } ) headers = { "Content-Type": "application/json", "Authorization": "Bearer " + ACCESS_TOKEN, } requests.request("POST", url, headers=headers, data=payload) print("MESSAGE SENT")
Nếu tin nhắn là lời chào đơn giản(SEND_GREETINGS_AND_PROMPT
), phản hồi sẽ bao gồm gợi ý bổ sung (greetings_text_body
).
Tương tự, khi người dùng đặt câu hỏi về các dịch vụ được cung cấp, tin nhắn văn bản (service_intro_text
) chứa các dịch vụ sẽ được gửi đến người dùng. Ngoài các dịch vụ, tin nhắn này còn chứa gợi ý để người dùng chọn có muốn trò chuyện với nhân viên tổng đài hay không.
Nếu mục nhập yêu cầu phản hồi từ chatbot (CHATBOT
), bạn cần khởi tạo mô hình, cung cấp nội dung tin nhắn cho mô hình và xử lý phản hồi để gửi lại cho người dùng. FLOW_RESPONSE
hiển thị phản hồi được ghi lại của Flow.
Các lựa chọn khác, CONTACT_US
và TALK_TO_AN_AGENT
, sẽ gửi phần tải dữ liệu của Flow đến người dùng. Phần tải dữ liệu của Flow bắt nguồn từ hàm flow_details
có nội dung được thể hiện ở dưới đây. Phẩn tải dữ liệu tích hợp chi tiết thiết yếu của Flow, bao gồm FLOW_ID
, mà bạn có thể lấy từ trang Flow của tài khoản WhatsApp Business của mình. Bạn cũng có thể xác định những ID này trong các biến môi trường.
def flow_details(flow_header, flow_body, flow_footer, flow_id, flow_cta, recipient_phone_number, screen_id ): # Generate a random UUID for the flow token flow_token = str(uuid.uuid4()) flow_payload = json.dumps({ "type": "flow", "header": { "type": "text", "text": flow_header }, "body": { "text": flow_body }, "footer": { "text": flow_footer }, "action": { "name": "flow", "parameters": { "flow_message_version": "3", "flow_token": flow_token, "flow_id": flow_id, "flow_cta": flow_cta, "flow_action": "navigate", "flow_action_payload": { "screen": screen_id } } } }) payload = json.dumps({ "messaging_product": "whatsapp", "recipient_type": "individual", "to": str(recipient_phone_number), "type": "interactive", "interactive": json.loads(flow_payload) }) return payload
Phương pháp này tạo ra action.parameters.flow_token
bằng cách tạo UUID ngẫu nhiên. action.parameters.flow_action_payload.screen
được truyền làm tham số (screen_id
). Lý tưởng nhất thì giá trị này phải đại diện cho ID của màn hình ban đầu mà bạn dự định hiển thị cho người dùng khi action.parameters.flow_cta
được thực hiện.
Cuối cùng, hãy thêm các tuyến webhook. Webhook yêu cầu GET
khởi chạy khi thêm webhook vào ứng dụng trên Meta for Developers. Webhook này trả về hub.challenge
của yêu cầu khi thành công.
@app.route("/webhook", methods=["GET"]) def webhook_get(): if request.method == "GET": if ( request.args.get("hub.mode") == "subscribe" and request.args.get("hub.verify_token") == TOKEN ): return make_response(request.args.get("hub.challenge"), 200) else: return make_response("Success", 403)
Yêu cầu POST
trích xuất và xử lý phần tải dữ liệu tin nhắn bằng cách sử dụng phương thức user_message_processor
đã giới thiệu ở phần trước. Vì mã này chỉ phục vụ phần tải dữ liệu tin nhắn nên sẽ báo lỗi khi thu được bất kỳ phần tải dữ liệu nào khác. Vì lý do này, bạn có thể sử dụng lệnh if
để kiểm tra xem liệu có phần thân messages
hay không.
@app.route("/webhook", methods=["POST"]) def webhook_post(): if request.method == "POST": request_data = json.loads(request.get_data()) if ( request_data["entry"][0]["changes"][0]["value"].get("messages") ) is not None: name = request_data["entry"][0]["changes"][0]["value"]["contacts"][0][ "profile" ]["name"] if ( request_data["entry"][0]["changes"][0]["value"]["messages"][0].get( "text" ) ) is not None: message = request_data["entry"][0]["changes"][0]["value"]["messages"][ 0 ]["text"]["body"] user_phone_number = request_data["entry"][0]["changes"][0]["value"][ "contacts" ][0]["wa_id"] user_message_processor(message, user_phone_number, name) else: # checking that there is data in a flow's response object before processing it if ( request_data["entry"][0]["changes"][0]["value"]["messages"][0][ "interactive" ]["nfm_reply"]["response_json"] ) is not None: flow_reply_processor(request) return make_response("PROCESSED", 200)
Ngoài ra, bạn có thể sử dụng hàm trình trợ giúp có tên flow_reply_processor
để trích xuất phản hồi từ Flow và gửi lại cho người dùng.
def flow_reply_processor(request): request_data = json.loads(request.get_data()) name = request_data["entry"][0]["changes"][0]["value"]["contacts"][0]["profile"]["name"] message = request_data["entry"][0]["changes"][0]["value"]["messages"][0]["interactive"]["nfm_reply"][ "response_json"] flow_message = json.loads(message) flow_key = flow_message["flow_key"] if flow_key == "agentconnect": firstname = flow_message["firstname"] reply = f"Thank you for reaching out {firstname}. An agent will reach out to you the soonest" else: firstname = flow_message["firstname"] secondname = flow_message["secondname"] issue = flow_message["issue"] reply = f"Your response has been recorded. This is what we received:\n\n*NAME*: {firstname} {secondname}\n*YOUR MESSAGE*: {issue}" user_phone_number = request_data["entry"][0]["changes"][0]["value"]["contacts"][0][ "wa_id"] send_message(reply, user_phone_number, "FLOW_RESPONSE", name)
Hàm này sử dụng khóa (flow_key
) để phân biệt giữa hai Flow, từ đó trích xuất phản hồi một cách thích hợp khi truyền ID màn hình đầu tiên chính xác.
Trước khi chạy mã, hãy so sánh mã với phiên bản đầy đủ và xác nhận rằng mọi thứ đều khớp.
Trước khi tiến hành, hãy chạy lệnh này từ thiết bị đầu cuối của bạn:
flask --app main run --port 5000
Nếu thành công, bạn sẽ thấy thông báo có nội dung:
* Running on http://127.0.0.1:5000
Tiếp theo, chạy ngrok http 5000
để lấy URL ánh xạ đến ứng dụng của bạn. Sao chép liên kết đó.
Sau đó, trong tài khoản nhà phát triển của bạn trên Meta for Developers, hãy nhấp vào menu Cấu hình bên dưới WhatsApp trong bảng điều hướng bên trái:
Trong thẻ Webhook, nhấp vào Chỉnh sửa.
Sau đó, trong trường URL gọi lại của hộp thoại mở ra, dán URL đã sao chép và nối /webhook
vào.
Thêm mã truy cập từ biến TOKEN
của file .env
vào trường Xác minh mã. Nhấp vào tùy chọn Xác minh và lưu để đóng hộp thoại.
Bây giờ, từ cùng thẻ như trên, hãy nhấp vào Quản lý và kiểm tra trường tin nhắn. Thẻ sẽ hiển thị như sau:
Lúc này, webhook đã sẵn sàng.
Bạn có thể gửi tin nhắn như "Xin chào" đến số tài khoản của mình. Bạn sẽ nhận được phản hồi thích hợp. Hãy thử trả lời bằng gợi ý hiển thị trong menu để kiểm tra Flow:
Sau đây là ảnh chụp màn hình khác hiển thị phản hồi của chatbot. Người dùng yêu cầu một bản dịch nhanh mà bot có thể cung cấp.
WhatsApp Flows là công cụ mạnh mẽ có thể hỗ trợ doanh nghiệp thu thập thông tin có cấu trúc, nâng cao tương tác với khách hàng và tinh giản giao tiếp giữa doanh nghiệp và người tiêu dùng. Một trong những cách xây dựng Flow là sử dụng Công cụ tạo Flow trong Trình quản lý WhatsApp. Công cụ này mang lại giao diện thân thiện với người dùng để thiết kế Flow.
Ứng dụng minh họa này giới thiệu sơ bộ về cách tận dụng WhatsApp Flows để cải thiện tương tác với khách hàng và phân tích dựa trên dữ liệu. Để sử dụng chuyên biệt hơn, bạn cũng có thể cấu hình Llama 2 và WhatsApp Flows để kết nối chatbot với mô hình tùy chỉnh hoặc đào tạo chatbot trên nguồn dữ liệu độc quyền, từ đó hỗ trợ chatbot trả lời các câu hỏi dùng ngôn ngữ tự nhiên về sản phẩm của bạn và các chức năng khác.
Hãy tận dụng WhatsApp Flows để nâng tầm tương tác với khách hàng và tinh giản việc thu thập dữ liệu trong ứng dụng ngay hôm nay. Thử ngay.