建構保留項目

本指南將逐步引導您完成 Actions 專案的開發程序 這個 API 會使用 Orders API 預訂項目。

交易流程

當您的 Actions 專案處理預留項目時, 使用下列流程:

  1. 驗證交易需求條件 (選用) - 使用交易 才能確保在對話開始時 使用者能夠進行交易。
  2. 建立訂單:引導使用者逐步完成 「購物車組件」以便建立預訂詳細資料
  3. 提出訂單:按下「購物車」後已完成,提出預訂「order」到 使用者以便確認資訊正確無誤。如果預訂成功 接收包含預訂詳細資料的回應。
  4. 完成訂單並傳送收據:訂單確認後,請更新 將收據傳送給使用者。
  5. 傳送訂單最新進度:在預訂的效期內, 傳送 PATCH 要求給 Orders API)。

限制和評論規範

請注意,使用 交易和 Orders API 即可。審查動作最多可能需要六週的時間 所以在規劃發布時間表時,別忘了考量到這點。 為加快審查流程,請務必遵守 交易政策與規範 ,再將動作送交審查。

您只能在下列國家/地區部署使用 Orders API 的動作:

澳洲
巴西
加拿大
印尼
日本
墨西哥
卡達
俄羅斯
新加坡
瑞士
泰國
土耳其
英國
美國

建構您的專案

如需交易對話的完整範例,請參閱我們的交易 以 Node.js 為例

設定

建立動作時,您必須指定要執行交易 動作控制台

如要設定專案和執行要求,請按照下列步驟操作:

  1. 建立新專案或匯入現有專案。
  2. 瀏覽至「部署」>「部署」目錄資訊:
  3. 在「其他資訊」部分查看交易 >勾選「執行動作」方塊 交易 API 來執行實體商品交易?」

驗證交易需求條件 (選用)

使用者表示想設定訂位後, 預約訂位舉例來說,叫用動作時,您的動作可能會 詢問"要預約席位嗎?如果使用者回答「是」,建議您 確保他們能夠繼續操作,並有機會修正任何設定 以防止他們繼續交易如要這麼做, 轉換至執行交易規定檢查的場景。

建立交易要求檢查場景

  1. 在「Scenes」分頁中新增具有該名稱的新場景。 TransactionRequirementsCheck
  2. 按一下「運算單元填充」下方的「+」來新增運算單元。
  3. 在「選取類型」下方,選取 actions.type.TransactionRequirementsCheckResult。 做為版位類型
  4. 在版位名稱欄位中,為版位命名 TransactionRequirementsCheck
  5. 勾選「自訂運算單元值回傳式曝光」核取方塊 (預設為啟用)。
  6. 按一下 [儲存]

交易需求條件檢查會產生下列其中一種結果:

  • 若符合這些條件,工作階段參數就會設定成功 ,即可繼續建立使用者的訂單。
  • 如果無法滿足一或多項條件,工作階段參數就會是 但不符合失敗條件在這種情況下, 或離開交易體驗
    • 如果使用者可以修正導致失敗狀態的錯誤, 系統會提示他們在裝置上解決這些問題。如果 對話在純語音的介面上發生, 使用者的手機播放。

處理交易需求條件檢查結果

  1. 在「Scenes」分頁中,選取新建立的 TransactionRequirementsCheck 個場景。
  2. 在「條件」下方,按一下「+」新增條件。
  3. 在文字欄位中輸入下列條件語法來檢查 成功條件:

    scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"
    
  4. 將滑鼠遊標懸停在剛剛新增的條件上,然後按一下向上箭頭 放在 if scene.slots.status == "FINAL" 之前。

  5. 啟用「傳送提示」,並提供簡單的提示給使用者 請問:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Looks like you're good to go!.
    
  6. 在「Transition」下方選取其他場景,可讓使用者繼續操作 並繼續交易。

  7. 選取條件 else if scene.slots.status == "FINAL"

  8. 啟用「傳送提示」,並提供簡單的提示給使用者 無法進行交易:

    candidates:
      - first_simple:
          variants:
            - speech: Transaction requirements check failed.
    
  9. 選取「轉換」下方的「結束對話」即可結束對話。 使用者無法完成交易時

建立訂單

取得需要的使用者資訊後,請建立「購物車」 組合引導使用者完成訂位。每次 動作的購物車組件流程會視其情況而定 課程中也會快速介紹 Memorystore 這是 Google Cloud 的全代管 Redis 服務

採用基本的購物車組件流程時,使用者可從清單中選擇要新增的選項 設計對話內容來簡化 使用者體驗舉例來說,您可以打造購物車組件體驗, 使用者可透過簡單的是非題,排定每月預約。 您也可以向使用者展示「建議」的輪轉介面或清單資訊卡 和預留項目

我們建議使用複合式回應來 透過視覺元素呈現使用者選項,同時設計對話, 使用者可以透過語音建立購物車。如需一些最佳做法 購物車組裝體驗範例,請參閱設計指南

建立一筆訂單

在整個對話中收集使用者的預訂詳細資料,然後 建構 Order 物件。

您的 Order 至少必須包含下列項目:

  • buyerInfo - 使用者購買相關資訊。
  • transactionMerchant - 協助下訂單的商家相關資訊。
  • contentslineItems 列訂單的實際內容。
,瞭解如何調查及移除這項存取權。

請參閱 Order 回應說明文件。請注意,您可能必須附上 會因預留項目而異

以下程式碼範例顯示完整的預訂訂單,包含選填欄位:

const order = {
   createTime: '2019-09-24T18:00:00.877Z',
   lastUpdateTime: '2019-09-24T18:00:00.877Z',
   merchantOrderId: orderId, // A unique ID String for the order
   userVisibleOrderId: orderId,
   transactionMerchant: {
     id: 'http://www.example.com',
     name: 'Example Merchant',
   },
   contents: {
     lineItems: [
       {
         id: 'LINE_ITEM_ID',
         name: 'Dinner reservation',
         description: 'A world of flavors all in one destination.',
         reservation: {
           status: 'PENDING',
           userVisibleStatusLabel: 'Reservation is pending.',
           type: 'RESTAURANT',
           reservationTime: {
             timeIso8601: '2020-01-16T01:30:15.01Z',
           },
           userAcceptableTimeRange: {
             timeIso8601: '2020-01-15/2020-01-17',
           },
           partySize: 6,
           staffFacilitators: [
             {
               name: 'John Smith',
             },
           ],
           location: {
             zipCode: '94086',
             city: 'Sunnyvale',
             postalAddress: {
               regionCode: 'US',
               postalCode: '94086',
               administrativeArea: 'CA',
               locality: 'Sunnyvale',
               addressLines: [
                 '222, Some other Street',
               ],
             },
           },
         },
       },
     ],
   },
   buyerInfo: {
     email: 'janedoe@gmail.com',
     firstName: 'Jane',
     lastName: 'Doe',
     displayName: 'Jane Doe',
   },
   followUpActions: [
     {
       type: 'VIEW_DETAILS',
       title: 'View details',
       openUrlAction: {
         url: 'http://example.com',
       },
     },
     {
       type: 'CALL',
       title: 'Call us',
       openUrlAction: {
         url: 'tel:+16501112222',
       },
     },
     {
       type: 'EMAIL',
       title: 'Email us',
       openUrlAction: {
         url: 'mailto:person@example.com',
       },
     },
   ],
   termsOfServiceUrl: 'http://www.example.com'
 };

建立排序和簡報選項

const orderOptions = {
      'requestDeliveryAddress': false,
    };

const presentationOptions = {
      'actionDisplayName': 'RESERVE'
    };

將訂單資料儲存至工作階段參數

從執行要求中,將訂單資料儲存到工作階段參數。訂單 物件將用於同一工作階段的不同情境

conv.session.params.order = {
    '@type': 'type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec',
    order: order,
    orderOptions: orderOptions,
    presentationOptions: presentationOptions
};

提出訂單

建立預訂訂單後,您必須向使用者顯示 確認或拒絕。為此,您應該轉換至執行交易的場景 決策。

建立交易決策情境

  1. 在「Scenes」分頁中,新增名稱為 TransactionDecision 的新場景。
  2. 按一下「運算單元填充」下方的「+」來新增運算單元。
  3. 在「選取類型」下方,選取 actions.type.TransactionDecisionValue 做為 版位類型
  4. 在版位名稱欄位中,為版位命名 TransactionDecision
  5. 勾選「自訂運算單元值回傳式曝光」核取方塊 (預設為啟用)。
  6. 在「設定運算單元」下方的下拉式選單中,選取「使用工作階段參數」
  7. 在「設定運算單元」下方,輸入要用於 將訂單儲存在文字欄位中 (即 $session.params.order)。
  8. 按一下 [儲存]

Google 助理嘗試填入 TransactionDecisionValue 時段時,會啟動 內建體驗,可將您傳遞的 Order 直接算繪到 「購物車預覽資訊卡」使用者可以說「schedule availability」、拒絕交易 或者要求變更預留項目詳細資料

此時使用者也可以要求變更訂單。在這個範例中 可確保您的執行要求可以在下列時間過後處理訂單變更要求: 完成購物車組裝體驗

處理交易決策結果

填入 TransactionDecisionValue 版位時,系統會向 交易決策會儲存在工作階段參數中這個值包含 包括:

  • ORDER_ACCEPTED
  • ORDER_REJECTED
  • CART_CHANGE_REQUESTED
  • USER_CANNOT_TRANSACT

如何處理交易決策結果:

  1. 在「Scenes」分頁中,選取新建立的 TransactionDecision 場景。
  2. 在「條件」下方,按一下「+」新增條件。
  3. 在文字欄位中輸入下列條件語法來檢查 成功條件:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  4. 將滑鼠遊標懸停在剛剛新增的條件上,然後按一下向上箭頭 放在 if scene.slots.status == "FINAL" 之前。

  5. 啟用「傳送提示」,並提供簡單的提示給使用者 預訂程序已完成:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction completed! Your reservation
                $session.params.TransactionDecision.order.merchantOrderId is all
                set!
    
  6. 選取「轉換」下方的「結束對話」即可結束對話。

  7. 在「條件」下方,按一下「+」新增條件。

  8. 在文字欄位中輸入下列條件語法來檢查 失敗條件:

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_REJECTED"
    
  9. 將滑鼠遊標懸停在剛剛新增的條件上,然後按一下向上箭頭 放在 if scene.slots.status == "FINAL" 之前。

  10. 啟用「傳送提示」並提供簡單的提示,讓使用者知道 訂單已被拒絕:

    candidates:
      - first_simple:
          variants:
            - speech: Looks like you don't want to set up a reservation. Goodbye.
    
  11. 選取「轉換」下方的「結束對話」即可結束對話。

  12. 選取條件 else if scene.slots.status == "FINAL"

  13. 啟用「傳送提示」,並提供簡單的提示給使用者 無法進行交易:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction failed with status
                $session.params.TransactionDecision.transactionDecision
    
  14. 選取「轉換」下方的「結束對話」即可結束對話。 使用者無法完成交易時

完成預訂並傳送收據

TransactionDecisionValue 運算單元傳回 ORDER_ACCEPTED 的結果時, 您必須立即執行所需的處理作業 或是保存在您自己的資料庫中)。

傳送簡單的回應即可持續對話。使用者收到 「收據卡收合」以及回應

如何傳送初始訂單更新通知:

  1. 在「Scenes」分頁中選取 TransactionDecision 場景。
  2. 在「Condition」(條件) 下方,選取檢查成功結果的條件。 ORDER_ACCEPTED:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  3. 針對這個條件,啟用「Call your Webhook」(呼叫 Webhook),並提供意圖 處理常式名稱,例如 update_order

  4. 在 Webhook 程式碼中,新增用於傳送初始訂單更新的意圖處理常式:

    app.handle('update_order', conv => {
      const currentTime = new Date().toISOString();
      let order = conv.session.params.TransactionDecision.order;
      conv.add(new OrderUpdate({
        'updateMask': {
          'paths': [
            'reservation.status',
            'reservation.user_visible_status_label',
            'reservation.confirmation_code'
          ]
        },
        'order': {
          'merchantOrderId': order.merchantOrderId,
          'lastUpdateTime': currentTime,
          'reservation': {
            'status': 'CONFIRMED',
            'userVisibleStatusLabel': 'Reservation confirmed',
            'confirmationCode': '123ABCDEFGXYZ',
          },
        },
        'reason': 'Reason string'
      }));
    });
    

傳送訂單最新資訊

預留項目狀態在整個生命週期中都會變更。傳送使用者 向 Orders API 發出 HTTP PATCH 要求更新的預訂訂單,其中包含 訂單狀態和詳細資料

設定對 Orders API 的非同步要求

系統會透過存取權授權給 Orders API 的訂單更新要求 產生下一個符記如要 PATCH 訂單更新並更新至 Orders API,請下載 JSON 與 Actions Console 專案相關聯的服務帳戶金鑰,然後交換 不記名權杖的服務帳戶金鑰,可傳遞至 HTTP 要求的 Authorization 標頭。

如要擷取服務帳戶金鑰,請執行下列步驟:

  1. 前往 Google Cloud 控制台, 依序輕觸「選單」圖示 ⋮ >。API 與服務 >憑證 >建立憑證 >服務帳戶金鑰
  2. 在「服務帳戶」下方,選取「新增服務帳戶」
  3. 將服務帳戶設為 service-account
  4. 角色設定為 專案 >擁有者
  5. 將金鑰類型設為「JSON」JSON
  6. 選取「建立」
  7. 系統會將私人 JSON 服務帳戶金鑰下載至本機電腦。

在訂單中更新代碼,請將服務金鑰換成不記名權杖 使用 Google API 用戶端程式庫 "https://www.googleapis.com/auth/actions.order.developer"」範圍。您可以 API 用戶端程式庫的安裝步驟和範例 GitHub 頁面

Node.js 範例中參照 order-update.js 參考範例金鑰交換

傳送訂單最新資訊

以 OAuth 不記名權杖交換服務帳戶金鑰之後,請傳送 訂單更新,成為對 Orders API 提出的授權 PATCH 要求。

Orders API 網址: PATCH https://actions.googleapis.com/v3/orders/${orderId}

請在要求中提供下列標頭:

  • "Authorization: Bearer token" 替換為 OAuth 不記名權杖 您當初是為服務帳戶交換服務帳戶金鑰
  • "Content-Type: application/json"

PATCH 要求應採用以下格式的 JSON 內容:

{ "orderUpdate": OrderUpdate }

OrderUpdate 物件包含下列頂層欄位:

  • updateMask - 您要更新的訂單欄位。如要更新 預訂狀態 將值設為 reservation.status, reservation.userVisibleStatusLabel
  • order:更新的內容。如果您要更新的是 請將值設為更新的 Order 物件。 如果您只想更新預訂狀態 (例如 "PENDING""FULFILLED"),物件會包含 以下欄位:

    • merchantOrderId - 您在 Order 物件中設定的 ID。
    • lastUpdateTime - 該更新作業的時間戳記。
    • purchase - 包含以下內容的物件:
      • status - 訂單狀態,格式為 ReservationStatus, 例如「CONFIRMED」或「CANCELLED」。
      • userVisibleStatusLabel - 面向使用者的標籤,提供詳細資料 訂單狀態,例如「您的預訂已確認」。
  • userNotification (選用) - userNotification 物件。注意事項 包含此物件並不保證會顯示於 使用者的裝置。

下列程式碼範例顯示會更新 OrderUpdate 預訂訂單向 FULFILLED 的狀態:

// Import the 'googleapis' module for authorizing the request.
const {google} = require('googleapis');
// Import the 'request-promise' module for sending an HTTP POST request.
const request = require('request-promise');
// Import the OrderUpdate class from the client library.
const {OrderUpdate} = require('@assistant/conversation');

// Import the service account key used to authorize the request.
// Replacing the string path with a path to your service account key.
// i.e. const serviceAccountKey = require('./service-account.json')

// Create a new JWT client for the Actions API using credentials
// from the service account key.
let jwtClient = new google.auth.JWT(
   serviceAccountKey.client_email,
   null,
   serviceAccountKey.private_key,
   ['https://www.googleapis.com/auth/actions.order.developer'],
   null,
);

// Authorize the client
let tokens = await jwtClient.authorize();

// Declare the ID of the order to update.
const orderId = '<UNIQUE_MERCHANT_ORDER_ID>';

// Declare order update
const orderUpdate = new OrderUpdate({
   updateMask: {
     paths: [
       'contents.lineItems.reservation.status',
       'contents.lineItems.reservation.userVisibleStatusLabel'
     ]
   },
   order: {
     merchantOrderId: orderId, // Specify the ID of the order to update
     lastUpdateTime: new Date().toISOString(),
     contents: {
       lineItems: [
         {
           reservation: {
             status: 'FULFILLED',
             userVisibleStatusLabel: 'Reservation fulfilled',
           },
         }
       ]
     },
   },
   reason: 'Reservation status was updated to fulfilled.',
});

// Set up the PATCH request header and body,
// including the authorized token and order update.
let options = {
 method: 'PATCH',
 uri: `https://actions.googleapis.com/v3/orders/${orderId}`,
 auth: {
   bearer: tokens.access_token,
 },
 body: {
   header: {
     isInSandbox: true,
   },
   orderUpdate,
 },
 json: true,
};

// Send the PATCH request to the Orders API.
try {
 await request(options);
} catch (e) {
 console.log(`Error: ${e}`);
}

設定預留項目狀態

訂單更新的 ReservationStatus 必須能說明訂單目前的狀態。更新應用程式的「order.ReservationStatus」中 欄位,請使用下列其中一個值:

  • PENDING - 預留項目已建立採取行動,但需要 需要額外處理作業
  • CONFIRMED - 預訂已在您的排程後端確認。
  • CANCELLED - 使用者已取消預訂。
  • FULFILLED - 服務已完成使用者的預訂。
  • CHANGE_REQUESTED - 使用者要求變更預訂,然後 或圖片。
  • REJECTED - 如果無法處理或其他原因 確認預訂

針對與您商家相關的各個狀態,傳送最新的訂單狀態 舉例來說,如果預留項目需要手動處理 要求預訂後進行確認,並傳送 PENDING 訂單更新資訊至 完成額外處理程序後不一定每個預留項目都需要所有狀態值。

測試專案

測試專案時,你可以在「Actions」主控台啟用沙箱模式 ,即可在不扣款付款方式的情況下測試動作。 如要啟用沙箱模式,請按照下列步驟操作:

  1. 在動作控制台中,按一下導覽列的「測試」
  2. 按一下 [設定]。
  3. 啟用「Development Sandbox」選項。

如果是實體交易,您也可以將欄位 isInSandbox 設為 true 樣本。這項操作等同於在 使用 Actions 主控台。如要查看使用 isInSandbox 的程式碼片段,請參閱 「傳送訂單最新資訊」部分。

疑難排解

如果您在測試期間遇到任何問題,請參閱疑難排解步驟 交易類型