ซื้อของออนไลน์แบบรับสินค้าที่ร้าน: อาหารบงชูร์ - ตอนที่ 2 - การสร้างรถเข็นช็อปปิ้ง

1. เกริ่นนำ

53003251caaf2be5.png 8826bd8cb0c0f1c7.png

อัปเดตครั้งล่าสุด: 30-10-2020

สร้างรถเข็นช็อปปิ้งด้วย Business Messages!

นี่เป็น Codelab ชุดที่ 2 ในชุดที่มีเป้าหมายเพื่อสร้างเส้นทางของผู้ใช้ด้วยการซื้อออนไลน์แบบรับสินค้าที่ร้านค้า ในเส้นทางอีคอมเมิร์ซจำนวนมาก รถเข็นช็อปปิ้งเป็นกุญแจสู่ความสำเร็จในการเปลี่ยนผู้ใช้ให้เป็นลูกค้าที่ชำระเงิน รถเข็นช็อปปิ้งยังเป็นวิธีทำความเข้าใจลูกค้าของคุณให้ดีขึ้น และเป็นวิธีหนึ่งในการให้ข้อเสนอแนะเกี่ยวกับสินค้าอื่นๆ ที่ลูกค้าอาจสนใจ ใน Codelab นี้เราจะมุ่งเน้นที่การสร้างประสบการณ์รถเข็นช็อปปิ้งและทำให้แอปพลิเคชันใช้งานได้กับ Google App Engine

รถเข็นช็อปปิ้งที่ดีควรเป็นอย่างไร

รถเข็นช็อปปิ้งเป็นกุญแจสำคัญที่นำไปสู่ประสบการณ์การช็อปปิ้งออนไลน์ที่ประสบความสำเร็จ ผลที่ได้คือ Business Messages ไม่ใช่แค่ช่วยในการแนะนำผลิตภัณฑ์ในส่วนถามและตอบเกี่ยวกับผลิตภัณฑ์ให้แก่ผู้มีโอกาสเป็นลูกค้าเท่านั้น แต่ยังช่วยอำนวยความสะดวกในประสบการณ์การช็อปปิ้งตลอดการสนทนาไปจนถึงการชำระเงินให้เสร็จสิ้นภายในการสนทนาอีกด้วย

9d17537b980d0e62.png

นอกจากรถเข็นช็อปปิ้งที่ดีแล้ว ประสบการณ์การช็อปปิ้งที่ดีจะช่วยให้ผู้ใช้สามารถเลือกดูสินค้าตามหมวดหมู่ และช่วยให้ธุรกิจสามารถแนะนำผลิตภัณฑ์อื่นๆ ที่ผู้ซื้ออาจสนใจได้ หลังจากเพิ่มสินค้าลงในรถเข็นช็อปปิ้งแล้ว ผู้ใช้จะตรวจสอบทั้งรถเข็นและนำสินค้าออกหรือเพิ่มสินค้าอื่นๆ ก่อนชำระเงินได้

สิ่งที่คุณจะสร้าง

ในส่วนนี้ของชุด Codelab คุณจะขยายขอบเขตของ Agent ดิจิทัลที่คุณสร้างไว้ในตอนที่ 1 ให้กับ Bonjour Meal ซึ่งเป็นบริษัทที่สมมติขึ้น เพื่อให้ผู้ใช้เรียกดูแคตตาล็อกสินค้าและเพิ่มสินค้าลงในรถเข็นช็อปปิ้งได้

ใน Codelab นี้ แอปของคุณจะ

  • แสดงแคตตาล็อกคำถามใน Business Messages
  • แนะนำรายการที่ผู้ใช้อาจสนใจ
  • ตรวจสอบเนื้อหาของรถเข็นสินค้าและสร้างสรุปราคารวม

ab2fb6a4ed33a129.png

สิ่งที่คุณจะได้เรียนรู้

  • วิธีทำให้เว็บแอปพลิเคชันใช้งานได้บน App Engine บน Google Cloud Platform
  • วิธีใช้กลไกพื้นที่เก็บข้อมูลถาวรเพื่อบันทึกสถานะของรถเข็นช็อปปิ้ง

Codelab นี้มุ่งเน้นที่การขยายการทำงานของ Agent ดิจิทัลจากตอนที่ 1 ของชุด Codelab นี้

สิ่งที่คุณต้องมี

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 นี้ด้วย

  1. เปิด Google Datastore API ในคอนโซล Google Cloud
  2. ตรวจสอบว่าคุณกําลังทำงานกับโปรเจ็กต์ GCP ที่ถูกต้อง
  3. คลิกเปิดใช้

การทำให้แอปพลิเคชันตัวอย่างใช้งานได้

ในเทอร์มินัล ให้ไปที่ไดเรกทอรีขั้นตอนที่ 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" ซึ่งคุณจะเห็นภาพสไลด์ของผลิตภัณฑ์ที่มีลักษณะดังนี้

4639da46bcc5230c.png

หากคุณแตะเพิ่มรายการ จะไม่มีสิ่งใดเกิดขึ้นเลย เว้นแต่ตัวแทนจะสะท้อนข้อมูลระบบรายงานผล 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 มีเอนทิตีหนึ่งที่ชื่อตามรหัสการสนทนา ตามด้วยความสัมพันธ์บางอย่างกับรายการสินค้าคงคลังและจำนวนสินค้าเหล่านั้นที่อยู่ในรถเข็นช็อปปิ้ง

619dc18a8136ea69.png

ในส่วนถัดไป เราจะสร้างวิธีแสดงรายการในรถเข็นช็อปปิ้ง กลไกการตรวจสอบรถเข็นช็อปปิ้งควรแสดงสินค้าทั้งหมดในรถเข็น จำนวนสินค้า และตัวเลือกในการนำสินค้าออกจากรถเข็น

กำลังตรวจสอบสินค้าในรถเข็น

การแสดงรายการในรถเข็นช็อปปิ้งเป็นวิธีเดียวที่จะทำให้เราสามารถทราบถึงสถานะของรถเข็นสินค้าและทราบว่าเราสามารถนำสินค้าใดออกได้บ้าง

ก่อนอื่น มาส่งข้อความที่เป็นมิตร เช่น "นี่คือรถเข็นช็อปปิ้งของคุณ" ตามด้วยข้อความอื่นที่มีภาพสไลด์การ์ดริชมีเดียพร้อมการตอบกลับที่แนะนำที่เชื่อมโยงว่า "นำออก 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)
...

34801776a97056ac.png

ตามตรรกะที่เราแนะนำในฟังก์ชัน 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)

905a1f3d89893ba0.png

น่าจะทำอย่างนั้นนะ ประสบการณ์การใช้งานรถเข็นสินค้าที่มีฟีเจอร์เต็มรูปแบบซึ่งช่วยให้ผู้ใช้เพิ่มสินค้า นำสินค้าออก และตรวจสอบสินค้าในรถเข็นได้

ในขั้นนี้ หากคุณต้องการดูฟังก์ชันรถเข็นสินค้าในการสนทนาของ 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)
...

ต่อไปนี้เป็นภาพหน้าจอเพื่อแสดงให้เห็นว่าตรรกะข้างต้นสามารถทำอะไรได้บ้าง

8feacf94ed0ac6c4.png

เมื่อเราพร้อมที่จะผสานรวมกับผู้ประมวลผลการชำระเงินในส่วนถัดไปของ Codelab เราจะเรียกใช้ฟังก์ชัน get_cart_price เพื่อส่งต่อข้อมูลไปยังผู้ประมวลผลการชำระเงินและเริ่มขั้นตอนการชำระเงิน

คุณลองใช้ฟังก์ชันของรถเข็นช็อปปิ้งนี้ได้ในการสนทนา Business Messages โดยทำให้แอปพลิเคชันใช้งานได้และโต้ตอบกับตัวแทนของคุณ

$ gcloud app deploy

6. ขอแสดงความยินดี

ยินดีด้วย คุณสร้างประสบการณ์การใช้งานรถเข็นช็อปปิ้งภายใน Business Messages สำเร็จแล้ว

สิ่งที่เราไม่ได้พูดถึงใน Codelab นี้คือฟีเจอร์การทำให้รถเข็นช็อปปิ้งทั้งหมดว่างเปล่า หากคุณต้องการ ให้ลองขยายแอปพลิเคชันเพื่อดำเนินการตามคุณลักษณะ "ล้างรถเข็น" โซลูชันมีอยู่ในขั้นตอนที่ 3 ของซอร์สโค้ดที่คุณโคลน

ในอนาคต เราจะผสานรวมระบบกับผู้ประมวลผลการชำระเงินภายนอกเพื่อให้ผู้ใช้ทำธุรกรรมการชำระเงินกับแบรนด์ของคุณให้เสร็จสมบูรณ์ได้

รถเข็นช็อปปิ้งที่ดีควรเป็นอย่างไร

ประสบการณ์การใช้งานรถเข็นช็อปปิ้งที่ดีในการสนทนาไม่ต่างไปจากแอปบนอุปกรณ์เคลื่อนที่หรือในกิจการที่มีหน้าร้านจริง ความสามารถในการเพิ่มรายการ นำสินค้าออก และคำนวณราคารถเข็นเป็นเพียงฟีเจอร์บางส่วนที่เราสำรวจใน Codelab นี้ สิ่งที่แตกต่างจากตะกร้าสินค้าจริงคือความสามารถในการดูราคาของรายการทั้งหมดในรถเข็น ณ เวลาใดๆ ในขณะที่คุณเพิ่มหรือนําสินค้าออก ฟีเจอร์ที่มีมูลค่าสูงเหล่านี้จะทำให้ประสบการณ์การค้าผ่านการสนทนาของคุณโดดเด่น

ขั้นตอนถัดไปที่ควรทำ

เมื่อคุณพร้อมแล้ว โปรดดูบางหัวข้อต่อไปนี้เพื่อดูข้อมูลเกี่ยวกับการโต้ตอบที่ซับซ้อนยิ่งขึ้นที่ทําได้ใน Business Messages

เอกสารอ้างอิง