Eşzamansız sipariş güncellemesi

Bir müşteri yemek siparişi verdikten sonra, değişikliği bize bildirmek için Ordering uçtan uca hizmetine sipariş güncelleme mesajı gönderebilirsiniz.

Sipariş güncellemelerinin gönderilmesinin bazı yaygın nedenleri şunlardır:

  • Sipariş için tahmini tamamlanma zamanı gösterilir veya değişir.
  • Bir siparişin durumu değişir.
  • Sipariş artık karşılanamıyor.
  • Siparişe dahil edilen bir menü öğesinin fiyatı değişti.
  • Müşteri, siparişini yönetmek için müşteri desteği veya restoran telefon numarası gibi yeni bir yönteme sahip olur.
  • Sipariş makbuzu kullanılabilir hale gelir.

Aşağıdaki bölümlerde, sipariş güncellemelerini kullanarak bu farklı senaryoların nasıl ele alınacağı hakkında ayrıntılı bilgi verilmektedir.

Sipariş durumlarında geçiş

Bir siparişin altı olası durumu vardır. Bu durumlar ve olası geçişler aşağıdaki şemada özetlenmiştir:

Sipariş durumu geçişleri

Müşteri ilk kez sipariş gönderdiğinde sipariş CREATED, CONFIRMED veya REJECTED durumunda başlar. Durum geçişi geçerli olduğu sürece siparişin durumunu güncellemek için sipariş güncelleme mesajı gönderebilirsiniz. CREATED durumu, iş ortağının platformu siparişi hemen onaylayamaz veya reddedemediğinde kullanılır. Bir müşterinin teslimat toplayıcısı aracılığıyla sipariş vermesi örnek bir kullanım alanıdır. Teslimat toplayıcı, teslimatı Google'dan alır ve bilgileri restorana gönderir. Restoran siparişi alıp müsaitlik durumunu onayladıktan sonra durum CONFIRMED olabilir. Aksi takdirde REJECTED olur.

CONFIRMED durumundaki bir sipariş daha sonra IN_PREPARATION durumuna geçer. Sipariş için teslimat mı yoksa teslim alma mı seçeneği tercih edildiğine bağlı olarak READY_FOR_PICKUP veya IN_TRANSIT durumunu kullanın. Yemek teslim edildiğinde veya alındığında sipariş FULFILLED durumuna ayarlanır.

Müşterilerin siparişleri iptal etmesine izin verirseniz CANCELLED durumunu kullanabilirsiniz. Siparişler CREATED, CONFIRMED, IN_PREPARATION, READY_FOR_PICKUP veya IN_TRANSIT durumundayken iptal edilebilir. Siparişin Sonuna Kadar Süreci hizmetiniz, iptal politikanıza ve iptal sırasındaki ödeme durumuna bağlı olarak geri ödeme yapmalıdır.

Sipariş uçtan uca hizmetinizin mevcut tüm durumları ve geçişleri desteklemesi gerekmez. Ancak siparişin nihai durumu FULFILLED, REJECTED veya CANCELLED olmalıdır.

Tahmini tamamlanma süresi sağlama

Kullanıcılara siparişlerinin teslim alınmaya hazır olacağı (veya teslim edileceği) tahmini bir zaman aralığı sağlayabilirsiniz. Bir müşterinin siparişinin teslim alınmaya hazır olacağı veya teslim edileceği tahmini zaman aralığını belirtmek için FoodOrderUpdateExtension özelliğinin estimatedFulfillmentTimeIso8601 alanını kullanın.

estimatedFulfillmentTimeIso8601'ü aşağıdaki zamanlarda gönderin:

  • Tahmini süre, ideal olarak sipariş CREATED veya CONFIRMED durumundayken kullanılabilir hale gelir.
  • Tahmini süre değiştiğinde (ör. sipariş IN_TRANSIT olduğunda tahmini süre daha doğru olacak şekilde güncellendiğinde).

Kullanıcı beklentilerini etkili bir şekilde yönetmek için tahminlerinizde ihtiyatlı olun ve sabit bir tarih ve saat yerine tarih ve saat aralığı belirtin. Mümkün olduğunda trafik koşulları gibi varyasyonları hesaba katmalısınız. Örneğin, tahmini teslimat süresi 13:00 olan bir sipariş için 12:45 (alt sınır) ile 13:15 (üst sınır) arasında bir tahmin gönderebilirsiniz.

Sipariş yönetimi işlemleri sağlama

Sipariş güncellemesi gönderirken müşterilere siparişlerini yönetmelerine yardımcı olacak kaynakları OrderManagementAction biçiminde sağlayabilirsiniz. Müşteriler sipariş verdikten sonra siparişin durumunu takip etmek, değişiklik yapmak veya siparişi iptal etmek için sizinle veya siparişi karşılayan restoranla iletişime geçebilir.

OrderManagementAction, müşterilerin doğrudan cihazlarından e-posta göndermesine, arama yapmasına veya bir URL'ye bağlantı oluşturmasına olanak tanır. OrderManagementAction alanında, kullanıcıya gönderdiğiniz e-posta sipariş onayındaki bilgileri kullanın.

Sipariş yönetimi işlemleri aşağıdaki türleri içerir:

  • CUSTOMER_SERVICE: Müşterilere müşteri hizmetleriyle iletişime geçebilecekleri bir işlem sunun. Bu yönetim işlemi türü, sipariş güncellemeleri için zorunludur.
  • EMAIL: Müşterilere, sağlanan e-posta adresine e-posta gönderme işlemi sunun.
  • CALL: Müşterilere, sağlanan telefon numarasını aramaları için bir işlem sunun.
  • VIEW_DETAIL: Müşterilere siparişlerinin ayrıntılarını görüntülemelerini sağlayacak bir işlem sunun.

Her sipariş güncellemesi en az bir sipariş yönetimi işlemi içermelidir. Ancak, sunulan sipariş yönetimi işlemleri siparişin durumuna göre değişiklik gösterebilir. Örneğin, bir sipariş CONFIRMED durumundayken CUSTOMER_SERVICE işlemi müşteri hizmetleri telefon numaranızı gösterebilir. Bu sipariş durumu IN_TRANSIT olarak güncellendiğinde CUSTOMER_SERVICE işlemi, siparişi yerine getiren restoranın telefon numarasını gösterebilir.

Sipariş güncellemeleri gönderme

Sipariş uçtan uca hizmetine sipariş güncellemesi göndermek için AsyncOrderUpdateRequestMessage mesaj türünü kullanırsınız. Google, AsyncOrderUpdateResponseMessage ile yanıt verir. Örneğin, bir müşteriye siparişinin geçerli ve kabul edildiğini bildirmek istiyorsanız siparişin durumunu Accepted by restaurant etiketiyle CONFIRMED olarak değiştirmek için bir AsyncOrderUpdateRequestMessage gönderebilirsiniz.

Sipariş güncelleme şeması

Sipariş güncelleme mesajını ayarlama

Google'a AsyncOrderUpdateRequestMessage gönderirken OrderUpdate alanını kullanarak siparişin durumuyla ilgili bilgileri eklemeniz gerekir.

Aşağıdaki örneklerde her sipariş durumu için bir örnek AsyncOrderUpdateRequestMessage gösterilmektedir:

ONAYLANDI

Bu örnekte, kullanıcıya siparişin makbuzu ve tahmini teslimat süresiyle onaylandığını bildiren örnek bir sipariş güncelleme isteği gösterilmektedir.

{
  "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"
      }
    }
  }
}
    

REDDEDİLDİ

Bu örnekte, kullanıcıya siparişin reddedildiğini ve reddetme nedenini bildiren örnek bir sipariş güncelleme isteği gösterilmektedir.

{
  "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."
        }
      ]
      }
    }
  }
}
    

İPTAL EDİLDİ

Bu örnekte, kullanıcıya siparişin iptal edildiğini ve iptal nedeninin belirtildiği örnek bir sipariş güncelleme isteği gösterilmektedir.

{
  "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

Bu örnekte, kullanıcıyı yemeğin hazırlanmakta olduğunu bildiren örnek bir sipariş güncelleme isteği gösterilmektedir.

{
  "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

Bu örnekte, kullanıcıyı yemeğin teslim alınmaya hazır olduğu konusunda bilgilendiren örnek bir sipariş güncelleme isteği gösterilmektedir.

{
  "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

Bu örnekte, kullanıcıyı siparişin tahmini teslimat süresiyle birlikte transfer sürecinde olduğunu bildiren örnek bir sipariş güncelleme isteği gösterilmektedir.

{
  "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"
      }
    }
  }
}
  

KARŞILANDI

Bu örnekte, kullanıcıyı siparişin teslim alındığı veya alındığı konusunda bilgilendiren örnek bir sipariş güncelleme isteği gösterilmektedir:

{
  "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"
            }
          }
        }
      ]
    }
  }
}
    

Farklı kullanım alanlarında sipariş güncelleme isteklerine dair daha fazla örnek için İleri seviye sipariş güncellemelerini uygulama başlıklı makaleyi okuyun.

Yetkilendirme jetonu oluşturma ve mesajı gönderme

Sipariş güncellemeleri için bir yetkilendirme jetonu gerekir. Böylece Ordering End-to-End hizmeti, iletinin Ordering End-to-End web hizmetinizden geldiğini doğrulayabilir.

Projeniz için sipariş güncellemelerini uygulamak üzere aşağıdaki adımları uygulayın:

  1. Aşağıdaki adımları uygulayarak bir yetkilendirme jetonu oluşturun:
    1. Hizmet hesabı dosyanızdaki kimlik bilgilerini okumak için Google Kimlik Doğrulama Kitaplığı'nı kullanın.
    2. Aşağıdaki API kapsamını kullanarak jeton isteyin: https://www.googleapis.com/auth/actions.fulfillment.conversation
  2. Aşağıdaki uç noktaya kimliği doğrulanmış bir HTTP POST isteği göndermek için bu jetonu kullanın: https://actions.googleapis.com/v2/conversations:send
  3. İsteğinizin bir parçası olarak Content-Type başlığını application/json olarak ayarlayın.

Aşağıdaki örneklerde, sipariş güncellemelerinin nasıl uygulanacağı gösterilmektedir:

Node.js

Bu kodda, Node.js için Google kimlik doğrulama kitaplığı kullanılmaktadır.

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

Bu kod, Python için Google kimlik doğrulama kitaplığını kullanır.

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

Bu kod, Java için Google kimlik doğrulama kitaplığını kullanır.

/**
 * 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",);
}
    

Google, hata içermeyen başarılı sipariş güncellemeleri için boş bir yük içeren bir HTTP 200 yanıtı döndürür. Güncellemenin hatalı olması gibi bir sorun varsa Google bir hata döndürür.