1. เกริ่นนำ
อัปเดตครั้งล่าสุด: 30-10-2020
สร้างรถเข็นช็อปปิ้งด้วย Business Messages!
นี่เป็น Codelab ชุดที่ 2 ในชุดที่มีเป้าหมายเพื่อสร้างเส้นทางของผู้ใช้ด้วยการซื้อออนไลน์แบบรับสินค้าที่ร้านค้า ในเส้นทางอีคอมเมิร์ซจำนวนมาก รถเข็นช็อปปิ้งเป็นกุญแจสู่ความสำเร็จในการเปลี่ยนผู้ใช้ให้เป็นลูกค้าที่ชำระเงิน รถเข็นช็อปปิ้งยังเป็นวิธีทำความเข้าใจลูกค้าของคุณให้ดีขึ้น และเป็นวิธีหนึ่งในการให้ข้อเสนอแนะเกี่ยวกับสินค้าอื่นๆ ที่ลูกค้าอาจสนใจ ใน Codelab นี้เราจะมุ่งเน้นที่การสร้างประสบการณ์รถเข็นช็อปปิ้งและทำให้แอปพลิเคชันใช้งานได้กับ Google App Engine
รถเข็นช็อปปิ้งที่ดีควรเป็นอย่างไร
รถเข็นช็อปปิ้งเป็นกุญแจสำคัญที่นำไปสู่ประสบการณ์การช็อปปิ้งออนไลน์ที่ประสบความสำเร็จ ผลที่ได้คือ Business Messages ไม่ใช่แค่ช่วยในการแนะนำผลิตภัณฑ์ในส่วนถามและตอบเกี่ยวกับผลิตภัณฑ์ให้แก่ผู้มีโอกาสเป็นลูกค้าเท่านั้น แต่ยังช่วยอำนวยความสะดวกในประสบการณ์การช็อปปิ้งตลอดการสนทนาไปจนถึงการชำระเงินให้เสร็จสิ้นภายในการสนทนาอีกด้วย
นอกจากรถเข็นช็อปปิ้งที่ดีแล้ว ประสบการณ์การช็อปปิ้งที่ดีจะช่วยให้ผู้ใช้สามารถเลือกดูสินค้าตามหมวดหมู่ และช่วยให้ธุรกิจสามารถแนะนำผลิตภัณฑ์อื่นๆ ที่ผู้ซื้ออาจสนใจได้ หลังจากเพิ่มสินค้าลงในรถเข็นช็อปปิ้งแล้ว ผู้ใช้จะตรวจสอบทั้งรถเข็นและนำสินค้าออกหรือเพิ่มสินค้าอื่นๆ ก่อนชำระเงินได้
สิ่งที่คุณจะสร้าง
ในส่วนนี้ของชุด Codelab คุณจะขยายขอบเขตของ Agent ดิจิทัลที่คุณสร้างไว้ในตอนที่ 1 ให้กับ Bonjour Meal ซึ่งเป็นบริษัทที่สมมติขึ้น เพื่อให้ผู้ใช้เรียกดูแคตตาล็อกสินค้าและเพิ่มสินค้าลงในรถเข็นช็อปปิ้งได้
ใน Codelab นี้ แอปของคุณจะ
- แสดงแคตตาล็อกคำถามใน Business Messages
- แนะนำรายการที่ผู้ใช้อาจสนใจ
- ตรวจสอบเนื้อหาของรถเข็นสินค้าและสร้างสรุปราคารวม
สิ่งที่คุณจะได้เรียนรู้
- วิธีทำให้เว็บแอปพลิเคชันใช้งานได้บน App Engine บน Google Cloud Platform
- วิธีใช้กลไกพื้นที่เก็บข้อมูลถาวรเพื่อบันทึกสถานะของรถเข็นช็อปปิ้ง
Codelab นี้มุ่งเน้นที่การขยายการทำงานของ Agent ดิจิทัลจากตอนที่ 1 ของชุด Codelab นี้
สิ่งที่คุณต้องมี
- โปรเจ็กต์ GCP ที่ลงทะเบียนและได้รับอนุมัติให้ใช้กับ Business Messages แล้ว
- ดูวิธีดำเนินการในเว็บไซต์ของนักพัฒนาซอฟต์แวร์
- ไฟล์ข้อมูลเข้าสู่ระบบ JSON ของบัญชีบริการที่สร้างขึ้นสำหรับโปรเจ็กต์ GCP
- อุปกรณ์ Android 5 ขึ้นไปหรืออุปกรณ์ iOS ที่มีแอป Google Maps
- มีประสบการณ์กับการเขียนโปรแกรมเว็บแอปพลิเคชัน
- การเชื่อมต่ออินเทอร์เน็ต
2. การตั้งค่า
Codelab นี้จะถือว่าคุณได้สร้าง Agent แรกและทำส่วนที่ 1 ของ Codelab แล้ว ด้วยเหตุนี้ เราจะไม่กล่าวถึงพื้นฐานการเปิดใช้ Business Messages และ Business Communications API, การสร้างคีย์บัญชีบริการ การติดตั้งใช้งานแอปพลิเคชัน หรือการตั้งค่าเว็บฮุคในคอนโซลการสื่อสารทางธุรกิจ อย่างไรก็ตาม เราจะโคลนแอปพลิเคชันตัวอย่างเพื่อให้มั่นใจว่าแอปพลิเคชันของคุณสอดคล้องกับสิ่งที่เรากำลังสร้าง และเราจะเปิดใช้ API สำหรับ Datastore บน Google Cloud Platform เพื่อให้สามารถคงข้อมูลที่เกี่ยวข้องกับรถเข็นช็อปปิ้งไว้ได้
โคลนแอปพลิเคชันจาก GitHub
ในเทอร์มินัล ให้โคลน Django Echo Bot Sample ลงในไดเรกทอรีที่ทำงานของโปรเจ็กต์ด้วยคำสั่งต่อไปนี้
$ git clone https://github.com/google-business-communications/bm-bonjour-meal-django-starter-code
คัดลอกไฟล์เข้าสู่ระบบ JSON ที่สร้างขึ้นสำหรับบัญชีบริการไปไว้ในโฟลเดอร์ทรัพยากรของตัวอย่าง แล้วเปลี่ยนชื่อข้อมูลเข้าสู่ระบบเป็น "bm-agent-service-account-credentials.json"
bm-bonjour-meal-django-starter-code/bonjourmeal-codelab/step-2/resources/bm-agent-service-account-credentials.json
เปิดใช้ Google Datastore API
ในส่วนที่ 1 ของ Codelab นี้ คุณได้เปิดใช้ Business Messages API, Business Communications API และ Cloud Build API
สำหรับ Codelab นี้ เนื่องจากเราจะทำงานร่วมกับ Google Datastore เราจึงจำเป็นต้องเปิดใช้ API นี้ด้วย
- เปิด Google Datastore API ในคอนโซล Google Cloud
- ตรวจสอบว่าคุณกําลังทำงานกับโปรเจ็กต์ GCP ที่ถูกต้อง
- คลิกเปิดใช้
การทำให้แอปพลิเคชันตัวอย่างใช้งานได้
ในเทอร์มินัล ให้ไปที่ไดเรกทอรีขั้นตอนที่ 2 ของตัวอย่าง
เรียกใช้คำสั่งต่อไปนี้ในเทอร์มินัลเพื่อทำให้ตัวอย่างใช้งานได้
$ gcloud config set project PROJECT_ID*
$ gcloud app deploy
- PROJECT_ID คือรหัสโครงการของโครงการที่คุณใช้ลงทะเบียนกับ API
จด URL ของแอปพลิเคชันที่ทำให้ใช้งานได้แล้วในเอาต์พุตของคำสั่งสุดท้าย:
Deployed service [default] to [https://PROJECT_ID.appspot.com]
รหัสที่คุณเพิ่งทำให้ใช้งานได้มีเว็บแอปพลิเคชันที่มีเว็บฮุคเพื่อรับข้อความจาก Business Messages ซึ่งมีทุกอย่างที่เราทำตั้งแต่ส่วนที่ 1 ของ Codelab หากยังไม่ได้ดำเนินการ โปรดกำหนดค่าเว็บฮุค
แอปพลิเคชันจะตอบคำถามง่ายๆ บางข้อ เช่น ผู้ใช้ที่ถามเกี่ยวกับเวลาทำการของ Bonjour Meal คุณควรทดสอบในอุปกรณ์เคลื่อนที่ผ่าน URL ทดสอบที่เรียกจากข้อมูลตัวแทนภายในคอนโซลการสื่อสารทางธุรกิจได้ URL ทดสอบจะเปิดตัวประสบการณ์ Business Messages ในอุปกรณ์เคลื่อนที่ และคุณจะเริ่มโต้ตอบกับตัวแทนจากที่นั่นได้
3. แคตตาล็อกผลิตภัณฑ์
ระบบสินค้าคงคลัง
ในกรณีส่วนใหญ่ คุณจะผสานรวมกับพื้นที่โฆษณาของแบรนด์ได้โดยตรงผ่าน API ภายใน ในกรณีอื่นๆ คุณอาจคัดลอกเนื้อหาจากหน้าเว็บหรือสร้างระบบติดตามสินค้าคงคลังของคุณเอง เรามุ่งเน้นที่การสร้างระบบสินค้าคงคลัง เราจะใช้ไฟล์ภาพนิ่งธรรมดาที่มีรูปภาพและข้อมูลผลิตภัณฑ์ของตัวแทน ในส่วนนี้ เราจะดึงข้อมูลจากไฟล์แบบคงที่นี้ แสดงข้อมูลนั้นในการสนทนา และอนุญาตให้ผู้ใช้เรียกดูสินค้าที่มีอยู่เพื่อเพิ่มลงในรถเข็นช็อปปิ้งได้
ไฟล์สินค้าคงคลังแบบคงที่จะมีลักษณะดังนี้
bonjourmeal-codelab/step-2/resources/inventory.json
{
"food": [
{
"id":0,
"name": "Ham and cheese sandwich",
"price": "6.99",
"image_url": "https://storage.googleapis.com/bonjour-rail.appspot.com/ham-and-cheese.png",
"remaining": 8
},
{
"id":1,
"name": "Chicken veggie wrap",
"price": "9.99",
"image_url": "https://storage.googleapis.com/bonjour-rail.appspot.com/chicken-veggie-wrap.png",
"remaining": 2
},
{
"id":2,
"name": "Assorted cheese plate",
"price": "7.99",
"image_url": "https://storage.googleapis.com/bonjour-rail.appspot.com/assorted-cheese-plate.png",
"remaining": 6
},
{
"id":3,
"name": "Apple walnut salad",
"price": "12.99",
"image_url": "https://storage.googleapis.com/bonjour-rail.appspot.com/apple-walnut-salad.png",
"remaining": 1
}
]
}
มารับแอปพลิเคชัน Python เพื่ออ่านไฟล์นี้กัน
การอ่านจากพื้นที่โฆษณาของเรา
โดยพื้นที่โฆษณาเป็นไฟล์แบบคงที่ชื่อ "inventory.json" ซึ่งอยู่ในไดเรกทอรี ./resources เราต้องเพิ่มตรรกะ Python ลงใน view.py เพื่ออ่านเนื้อหาของไฟล์ JSON จากนั้นแสดงเนื้อหาดังกล่าวในการสนทนา เรามาสร้างฟังก์ชันที่อ่านข้อมูลจากไฟล์ JSON และแสดงรายการผลิตภัณฑ์ที่พร้อมใช้งานกัน
คุณสามารถวางคำจำกัดความของฟังก์ชันนี้ไว้ที่ใดก็ได้ใน views.py
bonjourmeal-codelab/step-2/bopis/views.py
...
def get_inventory_data():
f = open(INVENTORY_FILE)
inventory = json.load(f)
return inventory
...
วิธีนี้น่าจะทำให้เราได้ข้อมูลที่เราต้องการในการอ่านข้อมูลจากพื้นที่โฆษณา ตอนนี้เราต้องการวิธีที่จะนำเสนอข้อมูลผลิตภัณฑ์นี้ในการสนทนา
แสดงแคตตาล็อกผลิตภัณฑ์
เพื่อความสะดวกใน Codelab นี้ เรามีแคตตาล็อกผลิตภัณฑ์ทั่วไปที่จะแสดงสินค้าคงคลังทั้งหมดในการสนทนา Business Messages ผ่านภาพหมุนการ์ดริชมีเดียเดียว
หากต้องการดูแคตตาล็อกผลิตภัณฑ์ เราจะสร้างการตอบกลับที่แนะนำที่มีข้อความ "แสดงเมนู" และข้อมูล PostbackData "show-product-catalog
" เมื่อผู้ใช้แตะการตอบกลับที่แนะนำและเว็บแอปพลิเคชันได้รับข้อมูลระบบรายงานผล Conversion เราจะส่งภาพสไลด์การ์ดริชมีเดีย เรามาเพิ่มค่าคงที่ใหม่สำหรับการตอบกลับที่แนะนำนี้ที่ด้านบนของ views.py กัน
bonjourmeal-codelab/step-2/bopis/views.py
...
CMD_SHOW_PRODUCT_CATALOG = 'show-product-catalog'
...
จากที่นี่ เราจะแยกวิเคราะห์ข้อความและกำหนดเส้นทางไปยังฟังก์ชันใหม่ที่ส่งภาพหมุนของการ์ดสื่อสมบูรณ์ที่มีแคตตาล็อกผลิตภัณฑ์ ก่อนอื่น ให้ขยายฟังก์ชัน route_message
เพื่อเรียกใช้ฟังก์ชัน "send_product_catalog
" เมื่อแตะการตอบกลับที่แนะนำ จากนั้นเราจะกำหนดฟังก์ชันดังกล่าว
ในข้อมูลโค้ดต่อไปนี้ ให้เพิ่มเงื่อนไขเพิ่มเติมลงในคำสั่ง if ในฟังก์ชัน route_message
เพื่อตรวจสอบว่า normalized_message
เท่ากับค่าคงตัวที่เรากําหนดไว้ก่อนหน้า CMD_SHOW_PRODUCT_CATALOG
หรือไม่
bonjourmeal-codelab/step-2/bopis/views.py
...
def route_message(message, conversation_id):
'''
Routes the message received from the user to create a response.
Args:
message (str): The message text received from the user.
conversation_id (str): The unique id for this user and agent.
'''
normalized_message = message.lower()
if normalized_message == CMD_RICH_CARD:
send_rich_card(conversation_id)
elif normalized_message == CMD_CAROUSEL_CARD:
send_carousel(conversation_id)
elif normalized_message == CMD_SUGGESTIONS:
send_message_with_suggestions(conversation_id)
elif normalized_message == CMD_BUSINESS_HOURS_INQUIRY:
send_message_with_business_hours(conversation_id)
elif normalized_message == CMD_ONLINE_SHOPPING_INQUIRY:
send_online_shopping_info_message(conversation_id)
elif normalized_message == CMD_SHOW_PRODUCT_CATALOG:
send_product_catalog(conversation_id)
else:
echo_message(message, conversation_id)
...
มาทำขั้นตอนดังกล่าวให้เสร็จสมบูรณ์แล้วกำหนด send_product_catalog
กัน send_product_catalog
จะเรียกใช้ get_menu_carousel,
ซึ่งจะสร้างภาพสไลด์ของการ์ดริชมีเดียจากไฟล์สินค้าคงคลังที่เราอ่านก่อนหน้านี้
คุณสามารถวางคำจำกัดความของฟังก์ชันไว้ที่ใดก็ได้ใน views.py โปรดทราบว่าข้อมูลโค้ดต่อไปนี้จะใช้ค่าคงที่ใหม่ 2 ค่าที่ควรเพิ่มลงในด้านบนสุดของไฟล์
bonjourmeal-codelab/step-2/bopis/views.py
...
CMD_ADD_ITEM = 'add-item'
CMD_SHOW_CART = 'show-cart'
...
def get_menu_carousel():
"""Creates a sample carousel rich card.
Returns:
A :obj: A BusinessMessagesCarouselCard object with three cards.
"""
inventory = get_inventory_data()
card_content = []
for item in inventory['food']:
card_content.append(BusinessMessagesCardContent(
title=item['name'],
description=item['price'],
suggestions=[
BusinessMessagesSuggestion(
reply=BusinessMessagesSuggestedReply(
text='Add item',
postbackData='{'+f'"action":"{CMD_ADD_ITEM}","item_name":"{item["id"]}"'+'}'))
],
media=BusinessMessagesMedia(
height=BusinessMessagesMedia.HeightValueValuesEnum.MEDIUM,
contentInfo=BusinessMessagesContentInfo(
fileUrl=item['image_url'],
forceRefresh=False))))
return BusinessMessagesCarouselCard(
cardContents=card_content,
cardWidth=BusinessMessagesCarouselCard.CardWidthValueValuesEnum.MEDIUM)
def send_product_catalog(conversation_id):
"""Sends the product catalog to the conversation_id.
Args:
conversation_id (str): The unique id for this user and agent.
"""
rich_card = BusinessMessagesRichCard(carouselCard=get_menu_carousel())
fallback_text = ''
# Construct a fallback text for devices that do not support carousels
for card_content in rich_card.carouselCard.cardContents:
fallback_text += (card_content.title + '\n\n' + card_content.description
+ '\n\n' + card_content.media.contentInfo.fileUrl
+ '\n---------------------------------------------\n\n')
message_obj = BusinessMessagesMessage(
messageId=str(uuid.uuid4().int),
representative=BOT_REPRESENTATIVE,
richCard=rich_card,
fallback=fallback_text,
suggestions=[
BusinessMessagesSuggestion(
reply=BusinessMessagesSuggestedReply(
text='See my cart',
postbackData=CMD_SHOW_CART)
),
BusinessMessagesSuggestion(
reply=BusinessMessagesSuggestedReply(
text='See the menu',
postbackData=CMD_SHOW_PRODUCT_CATALOG)
),
]
)
send_message(message_obj, conversation_id)
...
หากคุณตรวจสอบการสร้างรายการในภาพสไลด์ เราจะสร้างอินสแตนซ์ของคลาส BusinessMessagesSuggestion
ด้วย คำแนะนำแต่ละรายการแสดงถึงการเลือกของผู้ใช้สำหรับผลิตภัณฑ์ในภาพสไลด์ เมื่อผู้ใช้แตะการตอบกลับที่แนะนำ Business Messages จะส่ง PostbackData ที่มี JSON ที่อธิบายสินค้าและการดำเนินการที่ผู้ใช้ต้องการ (เพิ่มหรือนำออกจากรถเข็น) ไปยังเว็บฮุค ในส่วนต่อไปนี้ เราจะแยกวิเคราะห์ข้อความที่มีลักษณะเช่นนี้เพื่อให้สามารถเพิ่มสินค้าลงในรถเข็นได้จริง
ตอนนี้เราได้ทำการเปลี่ยนแปลงเหล่านี้แล้ว มาทำให้เว็บแอปพลิเคชันกับ Google App Engine ใช้งานได้และลองใช้งาน!
$ gcloud app deploy
เมื่อคุณโหลดแพลตฟอร์มการสนทนาในอุปกรณ์เคลื่อนที่แล้ว ให้ส่งข้อความ "show-product-catalog" ซึ่งคุณจะเห็นภาพสไลด์ของผลิตภัณฑ์ที่มีลักษณะดังนี้
หากคุณแตะเพิ่มรายการ จะไม่มีสิ่งใดเกิดขึ้นเลย เว้นแต่ตัวแทนจะสะท้อนข้อมูลระบบรายงานผล Conversion จากคําตอบที่แนะนํา ในส่วนถัดไป เราจะใช้แคตตาล็อกผลิตภัณฑ์และนำมาใช้สร้างรถเข็นช็อปปิ้งที่จะเพิ่มสินค้า
คุณจะขยายแคตตาล็อกผลิตภัณฑ์ที่เพิ่งสร้างขึ้นได้หลายวิธี คุณอาจมีเมนูเครื่องดื่มหรืออาหารมังสวิรัติที่แตกต่างออกไป การใช้ภาพสไลด์หรือชิปคำแนะนำเป็นวิธีที่ยอดเยี่ยมในการช่วยให้ผู้ใช้เจาะลึกตัวเลือกเมนูต่างๆ เพื่อเข้าสู่ชุดผลิตภัณฑ์ที่ต้องการ เพื่อเป็นการเสริมการทำงานของ Codelab นี้ ให้ลองขยายระบบแคตตาล็อกผลิตภัณฑ์เพื่อให้ผู้ใช้สามารถดูเครื่องดื่มแยกจากอาหารในเมนู หรือสามารถกำหนดตัวเลือกอาหารมังสวิรัติได้
4. รถเข็นช็อปปิ้ง
ในส่วนนี้ของ Codelab เราจะสร้างฟังก์ชันรถเข็นสินค้าจากส่วนที่แล้ว ซึ่งช่วยให้เราสามารถเรียกดูผลิตภัณฑ์ที่มีจำหน่ายได้
ประสบการณ์การใช้งานหลักของรถเข็นช็อปปิ้งช่วยให้ผู้ใช้เพิ่มสินค้าลงในรถเข็น นำสินค้าออกจากรถเข็น ติดตามจำนวนสินค้าแต่ละรายการในรถเข็น และตรวจสอบสินค้าในรถเข็นได้ในหลายๆ ด้าน
การติดตามสถานะของรถเข็นช็อปปิ้งหมายความว่าเราจำเป็นต้องเก็บข้อมูลในเว็บแอปพลิเคชันไว้ เพื่อให้ทดสอบและใช้งานได้ง่าย เราจะใช้ Google Datastore ใน Google Cloud Platform เพื่อเก็บข้อมูลไว้ถาวร รหัสการสนทนาจะยังคงเป็นรหัสคงที่ระหว่างผู้ใช้และธุรกิจ เราจึงใช้รหัสนี้เพื่อเชื่อมโยงผู้ใช้กับสินค้าในรถเข็นช็อปปิ้งได้
เริ่มต้นด้วยการเชื่อมต่อกับ Google Datastore และยืนยันรหัสการสนทนาเมื่อเราเห็น
การเชื่อมต่อกับพื้นที่เก็บข้อมูล
เราจะเชื่อมต่อกับ Google Datastore เมื่อใดก็ตามที่ระบบดำเนินการโต้ตอบกับรถเข็นช็อปปิ้ง เช่น เมื่อผู้ใช้กำลังเพิ่มหรือลบสินค้า ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ไลบรารีของไคลเอ็นต์นี้เพื่อโต้ตอบกับ Google Datastore ได้ที่เอกสารอย่างเป็นทางการ
ข้อมูลโค้ดต่อไปนี้กำหนดฟังก์ชันในการอัปเดตรถเข็นช็อปปิ้ง ฟังก์ชันนี้จะรับอินพุตต่อไปนี้: conversation_id
และ message
message
มี JSON ที่อธิบายการดำเนินการที่ผู้ใช้ต้องการ ซึ่งได้รวมอยู่ในภาพสไลด์ที่แสดงแคตตาล็อกผลิตภัณฑ์แล้ว ฟังก์ชันนี้จะสร้างไคลเอ็นต์ Google Datastore และดึงข้อมูลเอนทิตี ShoppingCart ทันที โดยที่คีย์คือรหัสการสนทนา
คัดลอกฟังก์ชันต่อไปนี้ไปยังไฟล์ views.py ของคุณ เราจะอธิบายเรื่องนี้เพิ่มเติมในส่วนถัดไป
bonjourmeal-codelab/step-2/bopis/views.py
from google.oauth2 import service_account
from google.cloud import datastore
def update_shopping_cart(conversation_id, message):
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_LOCATION)
client = datastore.Client(credentials=credentials)
key = client.key('ShoppingCart', conversation_id)
entity = datastore.Entity(key=key)
result = client.get(key)
# TODO: Add logic to add and remove items from cart
entity.update(result)
client.put(entity)
ขยายฟังก์ชันนี้เพื่อเพิ่มสินค้าลงในรถเข็น
การเพิ่มสินค้าลงในรถเข็น
เมื่อผู้ใช้แตะการดำเนินการที่แนะนำเพิ่มรายการจากภาพสไลด์ของผลิตภัณฑ์ PostbackData จะมี JSON ที่อธิบายการดำเนินการที่ผู้ใช้ต้องการ พจนานุกรม JSON มี 2 คีย์คือ "action" และ "item_name" และระบบจะส่งพจนานุกรม JSON นี้ไปยังเว็บฮุคของคุณ ช่อง "item_name" คือตัวระบุที่ไม่ซ้ำกันซึ่งเชื่อมโยงกับสินค้าใน Inventory.json
เมื่อเราได้รับคำสั่งรถเข็นและรายการในรถเข็นที่แยกวิเคราะห์จากข้อความแล้ว เราจะสามารถเขียนคำสั่งแบบมีเงื่อนไขเพื่อเพิ่มรายการได้ กรณีสำคัญที่ควรพิจารณาคือ หาก Datastore ไม่เคยเห็นรหัสการสนทนา หรือเมื่อรถเข็นช็อปปิ้งได้รับรายการนี้เป็นครั้งแรก รายการต่อไปนี้เป็นส่วนขยายของฟังก์ชัน update_shopping_cart
ที่ระบุไว้ข้างต้น การเปลี่ยนแปลงนี้จะเพิ่มรายการลงในรถเข็นช็อปปิ้งที่ Google Datastore เก็บไว้
ข้อมูลโค้ดต่อไปนี้คือส่วนขยายของฟังก์ชันก่อนหน้าที่เพิ่มใน views.py ของคุณ คุณสามารถเพิ่มความแตกต่างได้ตามต้องการ หรือคัดลอกข้อมูลโค้ดและแทนที่ฟังก์ชัน update_shopping_cart
เวอร์ชันที่มีอยู่
bonjourmeal-codelab/step-2bopis/views.py
def update_shopping_cart(conversation_id, message):
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_LOCATION)
inventory = get_inventory_data()
cart_request = json.loads(message)
cart_cmd = cart_request["action"]
cart_item = cart_request["item_name"]
item_name = inventory['food'][int(cart_item)]['name']
client = datastore.Client(credentials=credentials)
key = client.key('ShoppingCart', conversation_id)
entity = datastore.Entity(key=key)
result = client.get(key)
if result is None:
if cart_cmd == CMD_ADD_ITEM:
entity.update({
item_name: 1
})
else:
if cart_cmd == CMD_ADD_ITEM:
if result.get(item_name) is None:
result[item_name] = 1
else:
result[item_name] = result[item_name] + 1
entity.update(result)
client.put(entity)
เราจะขยายฟังก์ชันนี้ในภายหลังเพื่อรองรับสถานการณ์ที่ cart_cmd
มีสตริง "del-item" ที่กำหนดไว้ใน CMD_DEL_ITEM
นำมารวมกัน
ตรวจสอบว่าคุณเพิ่มท่อประปาในฟังก์ชัน route_message
แล้ว เพื่อให้ได้รับข้อความให้เพิ่มสินค้าลงในรถเข็นที่มีการเรียกฟังก์ชัน update_shopping_cart
นอกจากนี้ คุณยังต้องกำหนดค่าคงที่สำหรับการเพิ่มรายการโดยใช้วิธีการที่เราใช้ใน Codelab
bonjourmeal-codelab/step-2bopis/views.py
...
CMD_DEL_ITEM = 'del-item'
...
def route_message(message, conversation_id):
'''
Routes the message received from the user to create a response.
Args:
message (str): The message text received from the user.
conversation_id (str): The unique id for this user and agent.
'''
normalized_message = message.lower()
if normalized_message == CMD_RICH_CARD:
send_rich_card(conversation_id)
elif normalized_message == CMD_CAROUSEL_CARD:
send_carousel(conversation_id)
elif normalized_message == CMD_SUGGESTIONS:
send_message_with_suggestions(conversation_id)
elif normalized_message == CMD_BUSINESS_HOURS_INQUIRY:
send_message_with_business_hours(conversation_id)
elif normalized_message == CMD_ONLINE_SHOPPING_INQUIRY:
send_online_shopping_info_message(conversation_id)
elif normalized_message == CMD_SHOW_PRODUCT_CATEGORY:
send_product_catalog(conversation_id)
elif CMD_ADD_ITEM in normalized_message or CMD_DEL_ITEM in normalized_message:
update_shopping_cart(conversation_id, message)
else:
echo_message(message, conversation_id)
...
ขณะนี้เราสามารถเพิ่มสินค้าลงในรถเข็นช็อปปิ้งได้แล้ว หากคุณใช้การเปลี่ยนแปลงกับ Google App Engine คุณน่าจะเห็นการเปลี่ยนแปลงรถเข็นช็อปปิ้งแสดงในแดชบอร์ด Google Datastore ในคอนโซล GCP ดูภาพหน้าจอด้านล่างของคอนโซล Google Datastore มีเอนทิตีหนึ่งที่ชื่อตามรหัสการสนทนา ตามด้วยความสัมพันธ์บางอย่างกับรายการสินค้าคงคลังและจำนวนสินค้าเหล่านั้นที่อยู่ในรถเข็นช็อปปิ้ง
ในส่วนถัดไป เราจะสร้างวิธีแสดงรายการในรถเข็นช็อปปิ้ง กลไกการตรวจสอบรถเข็นช็อปปิ้งควรแสดงสินค้าทั้งหมดในรถเข็น จำนวนสินค้า และตัวเลือกในการนำสินค้าออกจากรถเข็น
กำลังตรวจสอบสินค้าในรถเข็น
การแสดงรายการในรถเข็นช็อปปิ้งเป็นวิธีเดียวที่จะทำให้เราสามารถทราบถึงสถานะของรถเข็นสินค้าและทราบว่าเราสามารถนำสินค้าใดออกได้บ้าง
ก่อนอื่น มาส่งข้อความที่เป็นมิตร เช่น "นี่คือรถเข็นช็อปปิ้งของคุณ" ตามด้วยข้อความอื่นที่มีภาพสไลด์การ์ดริชมีเดียพร้อมการตอบกลับที่แนะนำที่เชื่อมโยงว่า "นำออก 1 รายการ" หรือ "เพิ่มใหม่" ภาพสไลด์การ์ดริชมีเดียควรแสดงจำนวนสินค้าที่บันทึกไว้ในรถเข็นเพิ่มเติม
สิ่งที่ควรทราบก่อนที่เราจะเข้าไปเขียนฟังก์ชันคือ หากในรถเข็นช็อปปิ้งมีสินค้าเพียงประเภทเดียว เราจะไม่สามารถแสดงผลเป็นภาพสไลด์ได้ ภาพสไลด์ Rich Card ต้องมีการ์ดอย่างน้อย 2 ใบ ในทางกลับกัน ถ้าไม่มีสินค้าในรถเข็น เราก็จะแสดงข้อความง่ายๆ ที่บอกว่ารถเข็นว่างเปล่า
ดังนั้น เราจะกำหนดฟังก์ชันที่ชื่อว่า send_shopping_cart
ฟังก์ชันนี้เชื่อมต่อกับ Google Datastore และขอเอนทิตี ShoppingCart ตามรหัสการสนทนา เมื่อได้ข้อมูลแล้ว เราจะเรียกใช้ฟังก์ชัน get_inventory_data
และใช้ภาพสไลด์การ์ดริชมีเดียเพื่อรายงานสถานะของรถเข็นช็อปปิ้ง นอกจากนี้เราจะต้องรับรหัสของผลิตภัณฑ์ตามชื่อ แล้วประกาศฟังก์ชันเพื่อดูใน Google Datastore เพื่อหาค่านั้นได้ ขณะที่ระบบกำลังสร้างภาพสไลด์ เราสามารถเชื่อมโยงการตอบกลับที่แนะนำเพื่อลบรายการหรือเพิ่มสินค้าตามรหัสผลิตภัณฑ์ ข้อมูลโค้ดด้านล่างจะดำเนินการเหล่านี้ทั้งหมด คัดลอกรหัสไว้ที่ใดก็ได้ใน views.py
bonjourmeal-codelab/step-2/bopis/views.py
...
def get_id_by_product_name(product_name):
inventory = get_inventory_data()
for item in inventory['food']:
if item['name'] == product_name:
return int(item['id'])
return False
def send_shopping_cart(conversation_id):
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_LOCATION)
# Retrieve the inventory data
inventory = get_inventory_data()
# Pull the data from Google Datastore
client = datastore.Client(credentials=credentials)
key = client.key('ShoppingCart', conversation_id)
result = client.get(key)
shopping_cart_suggestions = [
BusinessMessagesSuggestion(
reply=BusinessMessagesSuggestedReply(
text='See total price', postbackData='show-cart-price')),
BusinessMessagesSuggestion(
reply=BusinessMessagesSuggestedReply(
text='Empty the cart', postbackData='empty-cart')),
BusinessMessagesSuggestion(
reply=BusinessMessagesSuggestedReply(
text='See the menu', postbackData=CMD_SHOW_PRODUCT_CATALOG)),
]
if result is None or len(result.items()) == 0:
message_obj = BusinessMessagesMessage(
messageId=str(uuid.uuid4().int),
representative=BOT_REPRESENTATIVE,
text='There are no items in your shopping cart.',
suggestions=shopping_cart_suggestions)
send_message(message_obj, conversation_id)
elif len(result.items()) == 1:
for product_name, quantity in result.items():
product_id = get_id_by_product_name(product_name)
fallback_text = ('You have one type of item in the shopping cart')
rich_card = BusinessMessagesRichCard(
standaloneCard=BusinessMessagesStandaloneCard(
cardContent=BusinessMessagesCardContent(
title=product_name,
description=f'{quantity} in cart.',
suggestions=[
BusinessMessagesSuggestion(
reply=BusinessMessagesSuggestedReply(
text='Remove one',
postbackData='{'+f'"action":"{CMD_DEL_ITEM}","item_name":"{product_id}"'+'}'))
],
media=BusinessMessagesMedia(
height=BusinessMessagesMedia.HeightValueValuesEnum.MEDIUM,
contentInfo=BusinessMessagesContentInfo(
fileUrl=inventory['food'][product_id]
['image_url'],
forceRefresh=False)))))
message_obj = BusinessMessagesMessage(
messageId=str(uuid.uuid4().int),
representative=BOT_REPRESENTATIVE,
richCard=rich_card,
suggestions=shopping_cart_suggestions,
fallback=fallback_text)
send_message(message_obj, conversation_id)
else:
cart_carousel_items = []
# Iterate through the cart and generate a carousel of items
for product_name, quantity in result.items():
product_id = get_id_by_product_name(product_name)
cart_carousel_items.append(
BusinessMessagesCardContent(
title=product_name,
description=f'{quantity} in cart.',
suggestions=[
BusinessMessagesSuggestion(
reply=BusinessMessagesSuggestedReply(
text='Remove one',
postbackData='{'+f'"action":"{CMD_DEL_ITEM}","item_name":"{product_id}"'+'}'))
],
media=BusinessMessagesMedia(
height=BusinessMessagesMedia.HeightValueValuesEnum.MEDIUM,
contentInfo=BusinessMessagesContentInfo(
fileUrl=inventory['food'][product_id]
['image_url'],
forceRefresh=False))))
rich_card = BusinessMessagesRichCard(
carouselCard=BusinessMessagesCarouselCard(
cardContents=cart_carousel_items,
cardWidth=BusinessMessagesCarouselCard.CardWidthValueValuesEnum
.MEDIUM))
fallback_text = ''
# Construct a fallback text for devices that do not support carousels
for card_content in rich_card.carouselCard.cardContents:
fallback_text += (
card_content.title + '\n\n' + card_content.description + '\n\n' +
card_content.media.contentInfo.fileUrl +
'\n---------------------------------------------\n\n')
message_obj = BusinessMessagesMessage(
messageId=str(uuid.uuid4().int),
representative=BOT_REPRESENTATIVE,
richCard=rich_card,
suggestions=shopping_cart_suggestions,
fallback=fallback_text,
)
send_message(message_obj, conversation_id)
...
ตรวจสอบว่าคุณได้กำหนด CMD_SHOW_CART
ที่ด้านบนของ views.py แล้ว และเรียก send_shopping_cart
หากผู้ใช้ส่งข้อความที่มีคำว่า "show-cart"
bonjourmeal-codelab/step-2/bopis/views.py
...
def route_message(message, conversation_id):
'''
Routes the message received from the user to create a response.
Args:
message (str): The message text received from the user.
conversation_id (str): The unique id for this user and agent.
'''
normalized_message = message.lower()
if normalized_message == CMD_RICH_CARD:
send_rich_card(conversation_id)
elif normalized_message == CMD_CAROUSEL_CARD:
send_carousel(conversation_id)
elif normalized_message == CMD_SUGGESTIONS:
send_message_with_suggestions(conversation_id)
elif normalized_message == CMD_BUSINESS_HOURS_INQUIRY:
send_message_with_business_hours(conversation_id)
elif normalized_message == CMD_ONLINE_SHOPPING_INQUIRY:
send_online_shopping_info_message(conversation_id)
elif normalized_message == CMD_SHOW_PRODUCT_CATEGORY:
send_product_catalog(conversation_id)
elif CMD_ADD_ITEM in normalized_message or CMD_DEL_ITEM in normalized_message:
update_shopping_cart(conversation_id, message)
elif normalized_message == CMD_SHOW_CART:
send_shopping_cart(conversation_id)
else:
echo_message(message, conversation_id)
...
ตามตรรกะที่เราแนะนำในฟังก์ชัน send_shopping_cart
เมื่อคุณพิมพ์ "show-cart" คุณจะได้รับข้อความแจ้งว่าไม่มีสิ่งใดในรถเข็น การ์ดริชมีเดียที่แสดงสินค้ารายการเดียวในรถเข็น หรือภาพสไลด์ของการ์ดที่แสดงสินค้าหลายรายการ นอกจากนี้ เรามีการตอบกลับที่แนะนำ 3 แบบ ได้แก่ "ดูราคารวม" "ล้างรถเข็น" และ "ดูเมนู"
ลองใช้การเปลี่ยนแปลงโค้ดด้านบนเพื่อทดสอบว่ารถเข็นช็อปปิ้งกำลังติดตามสินค้าที่คุณเพิ่มอยู่ และคุณสามารถตรวจสอบรถเข็นได้จากการสนทนาดังที่แสดงในภาพหน้าจอด้านบน คุณสามารถทำให้การเปลี่ยนแปลงใช้งานได้ด้วยการเรียกใช้คำสั่งนี้จากไดเรกทอรีขั้นตอนที่ 2 ของขั้นตอนที่คุณเพิ่มการเปลี่ยนแปลงของคุณ
$ gcloud app deploy
เราจะสร้างฟีเจอร์ "ดูราคารวม" ในส่วนถัดไปหลังจากที่สร้างฟังก์ชันเพื่อนำสินค้าออกจากรถเข็นแล้ว ฟังก์ชัน get_cart_price
จะทำงานคล้ายกับฟีเจอร์ "ดูรถเข็นช็อปปิ้ง" ตรงที่จะทำการอ้างอิงข้ามข้อมูลใน Datastore ด้วยไฟล์ Inventory.json เพื่อสร้างราคารวมสำหรับรถเข็นช็อปปิ้ง ซึ่งจะมีประโยชน์ในส่วนถัดไปของ Codelab ที่เราผสานรวมกับการชำระเงิน
การนำสินค้าออกจากรถเข็น
ท้ายที่สุด เราสามารถทำสิ่งต่างๆ ในรถเข็นช็อปปิ้งได้โดยใช้ฟังก์ชันการนำรถเข็นออก แทนที่ฟังก์ชัน update_shopping_cart
ที่มีอยู่ด้วยข้อมูลโค้ดต่อไปนี้
bonjourmeal-codelab/step-2/ bopis/views.py
def update_shopping_cart(conversation_id, message):
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_LOCATION)
inventory = get_inventory_data()
cart_request = json.loads(message)
cart_cmd = cart_request["action"]
cart_item = cart_request["item_name"]
item_name = inventory['food'][int(cart_item)]['name']
client = datastore.Client(credentials=credentials)
key = client.key('ShoppingCart', conversation_id)
entity = datastore.Entity(key=key)
result = client.get(key)
if result is None:
if cart_cmd == CMD_ADD_ITEM:
entity.update({
item_name: 1
})
elif cart_cmd == CMD_DEL_ITEM:
# The user is trying to delete an item from an empty cart. Pass and skip
pass
else:
if cart_cmd == CMD_ADD_ITEM:
if result.get(item_name) is None:
result[item_name] = 1
else:
result[item_name] = result[item_name] + 1
elif cart_cmd == CMD_DEL_ITEM:
if result.get(item_name) is None:
# The user is trying to remove an item that's no in the shopping cart. Pass and skip
pass
elif result[item_name] - 1 > 0:
result[item_name] = result[item_name] - 1
else:
del result[item_name]
entity.update(result)
client.put(entity)
การส่งข้อความยืนยัน
เมื่อผู้ใช้เพิ่มสินค้าลงในรถเข็น คุณควรส่งข้อความยืนยันเพื่อตอบรับการดำเนินการของผู้ใช้ และว่าคุณได้ดำเนินการตามคำขอแล้ว ซึ่งนอกจากจะช่วยสร้างความคาดหวังของคุณแล้ว ยังทำให้การสนทนาดำเนินต่อไปอีกด้วย
มาขยายฟังก์ชัน update_shopping_cart
เพื่อให้ส่งข้อความไปยังรหัสการสนทนาที่ระบุว่ามีการเพิ่มหรือนำสินค้าออกแล้ว รวมถึงให้คำแนะนำให้ตรวจสอบรถเข็นช็อปปิ้งหรือดูเมนูอีกครั้ง
bonjourmeal-codelab/step-2/bopis/views.py
def update_shopping_cart(conversation_id, message):
# No changes to the function, except appending the following logic
...
if cart_cmd == CMD_ADD_ITEM:
message = 'Great! You\'ve added an item to the cart.'
else:
message = 'You\'ve removed an item from the cart.'
message_obj = BusinessMessagesMessage(
messageId=str(uuid.uuid4().int),
representative=BOT_REPRESENTATIVE,
text=message,
suggestions=[
BusinessMessagesSuggestion(
reply=BusinessMessagesSuggestedReply(
text='Review shopping cart',
postbackData=CMD_SHOW_CART)
),
BusinessMessagesSuggestion(
reply=BusinessMessagesSuggestedReply(
text='See menu again',
postbackData=CMD_SHOW_PRODUCT_CATALOG)
),
])
send_message(message_obj, conversation_id)
น่าจะทำอย่างนั้นนะ ประสบการณ์การใช้งานรถเข็นสินค้าที่มีฟีเจอร์เต็มรูปแบบซึ่งช่วยให้ผู้ใช้เพิ่มสินค้า นำสินค้าออก และตรวจสอบสินค้าในรถเข็นได้
ในขั้นนี้ หากคุณต้องการดูฟังก์ชันรถเข็นสินค้าในการสนทนาของ Business Messages ให้ติดตั้งใช้งานแอปพลิเคชันเพื่อโต้ตอบกับตัวแทนของคุณ คุณสามารถทำได้โดยเรียกใช้คำสั่งนี้ในไดเรกทอรีขั้นตอนที่ 2
$ gcloud app deploy
5. กำลังเตรียมการชำระเงิน
ในการเตรียมการผสานรวมกับผู้ประมวลผลการชำระเงินในส่วนถัดไปของซีรีส์นี้ เราต้องการวิธีที่จะได้ราคาของรถเข็นช็อปปิ้ง มาสร้างฟังก์ชันที่ดึงราคาให้เราโดยอ้างอิงข้อมูลรถเข็นช็อปปิ้งใน Google Datastore กัน โดยดึงข้อมูลราคาของสินค้าแต่ละรายการจากสินค้าคงคลัง แล้วคูณราคาด้วยจำนวนสินค้าแต่ละรายการในรถเข็น
bonjourmeal-codelab/step-2/bopis/views.py
...
def get_cart_price(conversation_id):
# Pull the data from Google Datastore
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_LOCATION)
client = datastore.Client(credentials=credentials)
key = client.key('ShoppingCart', conversation_id)
entity = datastore.Entity(key=key)
result = client.get(key)
# Retrieve the inventory data
inventory = get_inventory_data()
# Start off with a total of 0 before adding up the total
total_price = 0
if len(result.items()) != 0:
for product_name, quantity in result.items():
total_price = total_price + float(
inventory['food'][get_id_by_product_name(product_name)]['price']) * int(quantity)
return total_price
...
และสุดท้ายคือเราจะใช้ฟังก์ชันนั้นและส่งข้อความถึงผู้ใช้ได้
bonjourmeal-codelab/step-2/bopis/views.py
...
def send_shopping_cart_total_price(conversation_id):
cart_price = get_cart_price(conversation_id)
message_obj = BusinessMessagesMessage(
messageId=str(uuid.uuid4().int),
representative=BOT_REPRESENTATIVE,
suggestions=[],
text=f'Your cart\'s total price is ${cart_price}.')
send_message(message_obj, conversation_id)
...
ลองอัปเดตฟังก์ชัน route_message
และค่าคงที่เพื่อทริกเกอร์ตรรกะข้างต้นเพื่อเชื่อมโยงทั้งหมดเข้าด้วยกัน
bonjourmeal-codelab/step-2/bopis/views.py
...
CMD_GET_CART_PRICE = 'show-cart-price'
...
def route_message(message, conversation_id):
'''
Routes the message received from the user to create a response.
Args:
message (str): The message text received from the user.
conversation_id (str): The unique id for this user and agent.
'''
normalized_message = message.lower()
if normalized_message == CMD_RICH_CARD:
send_rich_card(conversation_id)
elif normalized_message == CMD_CAROUSEL_CARD:
send_carousel(conversation_id)
elif normalized_message == CMD_SUGGESTIONS:
send_message_with_suggestions(conversation_id)
elif normalized_message == CMD_BUSINESS_HOURS_INQUIRY:
send_message_with_business_hours(conversation_id)
elif normalized_message == CMD_ONLINE_SHOPPING_INQUIRY:
send_online_shopping_info_message(conversation_id)
elif normalized_message == CMD_SHOW_PRODUCT_CATEGORY:
send_product_catalog(conversation_id)
elif CMD_ADD_ITEM in normalized_message or CMD_DEL_ITEM in normalized_message:
update_shopping_cart(conversation_id, message)
elif normalized_message == CMD_SHOW_CART:
send_shopping_cart(conversation_id)
elif normalized_message == CMD_GET_CART_PRICE:
send_shopping_cart_total_price(conversation_id)
else:
echo_message(message, conversation_id)
...
ต่อไปนี้เป็นภาพหน้าจอเพื่อแสดงให้เห็นว่าตรรกะข้างต้นสามารถทำอะไรได้บ้าง
เมื่อเราพร้อมที่จะผสานรวมกับผู้ประมวลผลการชำระเงินในส่วนถัดไปของ Codelab เราจะเรียกใช้ฟังก์ชัน get_cart_price
เพื่อส่งต่อข้อมูลไปยังผู้ประมวลผลการชำระเงินและเริ่มขั้นตอนการชำระเงิน
คุณลองใช้ฟังก์ชันของรถเข็นช็อปปิ้งนี้ได้ในการสนทนา Business Messages โดยทำให้แอปพลิเคชันใช้งานได้และโต้ตอบกับตัวแทนของคุณ
$ gcloud app deploy
6. ขอแสดงความยินดี
ยินดีด้วย คุณสร้างประสบการณ์การใช้งานรถเข็นช็อปปิ้งภายใน Business Messages สำเร็จแล้ว
สิ่งที่เราไม่ได้พูดถึงใน Codelab นี้คือฟีเจอร์การทำให้รถเข็นช็อปปิ้งทั้งหมดว่างเปล่า หากคุณต้องการ ให้ลองขยายแอปพลิเคชันเพื่อดำเนินการตามคุณลักษณะ "ล้างรถเข็น" โซลูชันมีอยู่ในขั้นตอนที่ 3 ของซอร์สโค้ดที่คุณโคลน
ในอนาคต เราจะผสานรวมระบบกับผู้ประมวลผลการชำระเงินภายนอกเพื่อให้ผู้ใช้ทำธุรกรรมการชำระเงินกับแบรนด์ของคุณให้เสร็จสมบูรณ์ได้
รถเข็นช็อปปิ้งที่ดีควรเป็นอย่างไร
ประสบการณ์การใช้งานรถเข็นช็อปปิ้งที่ดีในการสนทนาไม่ต่างไปจากแอปบนอุปกรณ์เคลื่อนที่หรือในกิจการที่มีหน้าร้านจริง ความสามารถในการเพิ่มรายการ นำสินค้าออก และคำนวณราคารถเข็นเป็นเพียงฟีเจอร์บางส่วนที่เราสำรวจใน Codelab นี้ สิ่งที่แตกต่างจากตะกร้าสินค้าจริงคือความสามารถในการดูราคาของรายการทั้งหมดในรถเข็น ณ เวลาใดๆ ในขณะที่คุณเพิ่มหรือนําสินค้าออก ฟีเจอร์ที่มีมูลค่าสูงเหล่านี้จะทำให้ประสบการณ์การค้าผ่านการสนทนาของคุณโดดเด่น
ขั้นตอนถัดไปที่ควรทำ
เมื่อคุณพร้อมแล้ว โปรดดูบางหัวข้อต่อไปนี้เพื่อดูข้อมูลเกี่ยวกับการโต้ตอบที่ซับซ้อนยิ่งขึ้นที่ทําได้ใน Business Messages
เอกสารอ้างอิง
- SuggestedReply
- เอกสารอ้างอิงข้อความ Business Messages
- คำจำกัดความของ JSON สำหรับ RichCard