Pembaruan urutan asinkron

Setelah pelanggan mengirim pesanan makanan, Anda dapat mengirim pesan pembaruan pesanan ke layanan Pemesanan Menyeluruh untuk memberi tahu kita tentang perubahan tersebut.

Berikut beberapa alasan umum untuk mengirimkan pembaruan pesanan:

  • Estimasi waktu pemenuhan pesanan untuk pesanan tersedia atau berubah.
  • Status pesanan berubah.
  • Pesanan tidak dapat dipenuhi lagi.
  • Harga item menu yang disertakan dalam pesanan berubah.
  • Pelanggan memiliki cara baru untuk mengelola pesanannya, seperti dukungan pelanggan atau nomor telepon restoran.
  • Tanda terima pesanan tersedia.

Bagian selanjutnya akan memberikan detail tentang cara menangani berbagai skenario ini menggunakan pembaruan pesanan.

Status urutan transisi

Sebuah pesanan memiliki enam kemungkinan status. Status ini dan kemungkinan transisinya diuraikan dalam diagram berikut:

Transisi status pesanan

Saat pelanggan pertama kali melakukan pesanan, pesanannya dimulai dengan status CREATED, CONFIRMED, atau REJECTED. Anda dapat mengirim pesan pembaruan pesanan ke memperbarui status pesanan, selama transisi status valid. CREATED status digunakan saat platform partner tidak dapat mengonfirmasi atau menolak pesanan segera. Contoh kasus penggunaan adalah saat pelanggan memesan melalui pengiriman agregator. Agregator pengiriman menerima pengiriman dari Google, dan {i>aggregator<i} mengirimkan informasi ke restoran tersebut. Setelah restoran menerima dan mengonfirmasi ketersediaan pesanan, status sekarang dapat menjadi CONFIRMED, jika tidak REJECTED.

Selanjutnya, pesanan dalam status CONFIRMED dipindahkan ke status IN_PREPARATION. Bergantung pada apakah pesanannya diambil untuk diambil atau dikirim, berikutnya gunakan status READY_FOR_PICKUP atau IN_TRANSIT. Saat makanan telah dikirim atau diambil, pesanan ditetapkan ke status FULFILLED.

Jika Anda mengizinkan pelanggan untuk membatalkan pesanan, Anda dapat menggunakan status CANCELLED. Pesanan dapat dibatalkan saat berada dalam status CREATED, CONFIRMED, IN_PREPARATION, READY_FOR_PICKUP, atau IN_TRANSIT. Layanan Pemesanan Anda Menyeluruh akan memberikan pengembalian dana bergantung pada kebijakan pembatalan dan status pembayaran pada saat pembatalan.

Layanan Pemesanan Anda End-to-End tidak harus mendukung semua status yang tersedia dan transisi. Namun, status akhir pesanan harus berupa FULFILLED, REJECTED, atau CANCELLED.

Memberikan perkiraan waktu pemenuhan

Anda dapat memberikan perkiraan rentang waktu kepada pengguna untuk mencapai pesanan mereka siap diambil (atau diantar). Menggunakan kolom estimatedFulfillmentTimeIso8601 FoodOrderUpdateExtension untuk memberikan estimasi rentang waktu saat pesanan pelanggan siap untuk diambil atau dikirim.

Kirim estimatedFulfillmentTimeIso8601 pada waktu berikut:

  • Saat estimasi waktu tersedia, idealnya dalam urutan CREATED atau status CONFIRMED.
  • Saat estimasi waktu berubah, seperti memperbarui estimasi waktu lebih akurat jika urutannya IN_TRANSIT.

Untuk mengelola ekspektasi pengguna secara efektif, bersikaplah konservatif dalam perkiraan dan memberikan rentang tanggal dan waktu, bukan tanggal dan waktu yang tetap. Anda seharusnya faktor dalam variasi seperti kondisi lalu lintas bila memungkinkan. Sebagai misalnya, Anda dapat mengirim perkiraan pukul 12.45 (batas bawah) hingga 13.15 (bagian atas terikat) untuk pesanan yang estimasi waktu pengirimannya adalah pukul 13.00.

Menyediakan tindakan pengelolaan pesanan

Saat mengirimkan pembaruan pesanan, Anda dapat memberikan referensi kepada pelanggan yang membantu mereka mengelola pesanannya dalam bentuk OrderManagementAction. Setelah pelanggan melakukan pemesanan, mereka mungkin perlu menghubungi Anda atau restoran memenuhi pesanan untuk melacak kemajuan, membuat perubahan, atau membatalkan pesanan mereka.

OrderManagementAction memungkinkan pelanggan untuk mengirim email, menelepon, atau menautkan ke URL langsung dari perangkat mereka. Gunakan informasi yang sama di OrderManagementAction seperti dalam konfirmasi pesanan email yang Anda kirimkan ke .

Tindakan pengelolaan pesanan mencakup jenis berikut:

  • CUSTOMER_SERVICE: Berikan tindakan kepada pelanggan untuk menghubungi pelanggan layanan. Jenis tindakan pengelolaan ini wajib untuk pembaruan pesanan.
  • EMAIL: Beri pelanggan tindakan untuk mengirim email ke alamat yang disediakan alamat email Anda.
  • CALL: Memberi pelanggan tindakan untuk menelepon nomor telepon yang diberikan.
  • VIEW_DETAIL: Memberi pelanggan tindakan untuk melihat detail mereka pesanan.

Setiap pembaruan pesanan harus berisi setidaknya satu tindakan pengelolaan pesanan. Namun, tindakan pengelolaan pesanan yang diberikan dapat bervariasi berdasarkan status pesanan. Misalnya, jika pesanan berada dalam status CONFIRMED, CUSTOMER_SERVICE tindakan dapat mengarah ke nomor telepon layanan pelanggan Anda. Jika urutan tersebut berstatus pembaruan untuk IN_TRANSIT, tindakan CUSTOMER_SERVICE dapat mengarah ke nomor telepon restoran pemenuhan pesanan.

Mengirim pembaruan pesanan

Anda menggunakan jenis pesan AsyncOrderUpdateRequestMessage untuk mengirim pesanan pembaruan ke layanan Pemesanan Menyeluruh. Google akan merespons kembali dengan AsyncOrderUpdateResponseMessage. Misalnya, jika Anda ingin menginformasikan bahwa pesanan mereka valid dan diterima, Anda dapat mengirimkan AsyncOrderUpdateRequestMessage untuk mengubah status pesanan menjadi CONFIRMED dengan label Accepted by restaurant.

Diagram pembaruan pesanan

Menetapkan pesan pembaruan pesanan

Saat Anda mengirim AsyncOrderUpdateRequestMessage ke Google, Anda harus menyertakan informasi tentang status pesanan menggunakan kolom OrderUpdate.

Contoh berikut menunjukkan contoh AsyncOrderUpdateRequestMessage untuk setiap status pesanan:

DIKONFIRMASI

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa pesanan telah dikonfirmasi dengan tanda terima dan perkiraan tanggal pengiriman baik.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "CONFIRMED",
        "label": "Provider confirmed"
      },
      "receipt": {
        "userVisibleOrderId": "userVisibleId1234"
      },
      "updateTime": "2017-07-17T12:00:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
        "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601": "2017-07-17T13:00:00Z/2017-07-17T13:30:00Z"
      }
    }
  }
}
    

DITOLAK

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa pesanan ditolak dengan alasan penolakan.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "REJECTED",
        "label": "Order rejected"
      },
      "updateTime": "2017-05-10T02:30:00.000Z",
      "rejectionInfo": {
        "type": "UNKNOWN",
        "reason": "Sorry, the restaurant cannot take your order right now."
      },
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
      "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
      "foodOrderErrors": [
        {
        "error": "NO_CAPACITY",
        "description": "Sorry, the restaurant cannot take your order right now."
        }
      ]
      }
    }
  }
}
    

DIBATALKAN

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa pesanan dibatalkan dengan alasan pembatalan.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "CANCELLED",
        "label": "Order cancelled"
      },
      "updateTime": "2017-05-10T02:30:00.000Z",
      "cancellationInfo": {
        "reason": "Customer requested"
      },
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ]
    }
  }
}
    

IN_PREPARATION

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa makanan tersebut sedang disiapkan.

{
  "isInSandbox":true,
  "customPushMessage":{
    "orderUpdate":{
      "actionOrderId":"sample_action_order_id",
      "orderState":{
        "state":"IN_PREPARATION",
        "label":"Order is being prepared"
      },
      "receipt": {
        "userVisibleOrderId": "userVisibleId1234"
      },
      "updateTime":"2018-04-15T11:30:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension":{
        "@type":"type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601":"PT20M"
      }
    }
  }
}
    

READY_FOR_PICKUP

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa makanan siap untuk diambil.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "READY_FOR_PICKUP",
        "label": "Order is ready for pickup"
      },
      "receipt": {
        "userVisibleOrderId": "userVisibleId1234"
      },
      "updateTime": "2018-04-15T12:00:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
        "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601": "PT20M"
      }
    }
  }
}
    

IN_TRANSIT

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa pesanan sedang dalam pengiriman dengan perkiraan waktu pengiriman.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "IN_TRANSIT",
        "label": "Order is on the way"
      },
      "inTransitInfo": {
        "updatedTime": "2017-07-17T12:00:00Z"
      },
      "updateTime": "2017-07-17T12:00:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
        "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601": "PT20M"
      }
    }
  }
}
  

TERPENUHI

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa pesanan diambil atau diantar:

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
      "state": "FULFILLED",
      "label": "Order delivered"
      },
      "updateTime": "2017-05-10T02:30:00.000Z",
      "fulfillmentInfo": {
        "deliveryTime": "2017-05-10T02:30:00.000Z"
      },
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ]
    }
  }
}
    

Untuk contoh lainnya tentang permintaan pembaruan pesanan dalam berbagai kasus penggunaan, baca Menerapkan pembaruan pesanan lanjutan.

Buat token otorisasi dan kirim pesan

Pembaruan pesanan memerlukan token otorisasi sehingga dapat memverifikasi bahwa pesan berasal dari layanan web Pemesanan Anda.

Untuk menerapkan pembaruan pesanan pada project Anda, ikuti langkah-langkah berikut:

  1. Buat token otorisasi dengan mengikuti langkah-langkah berikut:
    1. Menggunakan Library Google Auth untuk membaca kredensial dari layanan Anda file akun.
    2. Minta token menggunakan cakupan API berikut: https://www.googleapis.com/auth/actions.fulfillment.conversation
  2. Gunakan token ini untuk mengirim permintaan POST HTTP yang diautentikasi ke endpoint berikut: https://actions.googleapis.com/v2/conversations:send
  3. Tetapkan header Content-Type ke application/json sebagai bagian dari permintaan Anda.

Contoh berikut menunjukkan cara menerapkan pembaruan pesanan:

Node.js

Kode ini menggunakan library autentikasi Google untuk Node.js.

const {auth} = require('google-auth-library')
const request = require('request');
// The service account client secret file downloaded from the Google Cloud Console
const serviceAccountJson = require('./service-account.json')
// order-update.json is a file that contains the payload
const jsonBody = require('./order-update.json')

/**
 * Get the authorization token using a service account.
 */
async function getAuthToken() {
  let client = auth.fromJSON(serviceAccountJson)
  client.scopes = ['https://www.googleapis.com/auth/actions.fulfillment.conversation']
  const tokens = await client.authorize()
  return tokens.access_token;
}

/**
 * Send an order update request
 */
async function sendOrderUpdate() {
  const token = await getAuthToken()
  request.post({
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    url: 'https://actions.googleapis.com/v2/conversations:send',
    body: jsonBody,
    json: true
  },
  (err, res, body) => {
    if (err) { return console.log(err); }
    console.log(`Response: ${JSON.stringify(res)}`)
  })
}
    

Python

Kode ini menggunakan library autentikasi Google untuk Python.

from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession
import json

# service-account.json is the service account client secret file downloaded from the
# Google Cloud Console
credentials = service_account.Credentials.from_service_account_file(
    'service-account.json')

scoped_credentials = credentials.with_scopes(
    ['https://www.googleapis.com/auth/actions.fulfillment.conversation'])

authed_session = AuthorizedSession(scoped_credentials)

# order-update.json is a file that contains the payload
json_payload=json.load(open('order-update.json'))

response = authed_session.post(
    'https://actions.googleapis.com/v2/conversations:send',
    json=json_payload)
    

Java

Kode ini menggunakan library autentikasi Google untuk Java.

/**
 * Get the authorization token using a service account.
 */
private static String getAuthToken() {
  InputStream serviceAccountFile = Example.class.getClassLoader().getResourceAsStream("service-account.json");
  ServiceAccountCredentials.Builder credentialsSimpleBuilder =
      ServiceAccountCredentials.fromStream(serviceAccountFile).toBuilder();
  credentialsSimpleBuilder.setScopes(ImmutableList.of("https://www.googleapis.com/auth/actions.fulfillment.conversation"));
  AccessToken accessToken = credentialsSimpleBuilder.build().refreshAccessToken();
  return accessToken.getTokenValue();
}

/**
 * Send an order update request
 */
public void sendOrderUpdate() {
  String authToken = getAuthToken();
  // Execute POST request
  executePostRequest("https://actions.googleapis.com/v2/conversations:send",
      authToken, "update_order_example.json",);
}
    

Agar pembaruan pesanan berhasil tanpa error, Google akan menampilkan respons HTTP 200 dengan payload kosong. Jika ada masalah, misalnya update formatnya salah, Google akan menampilkan error.