メインコンテンツまでスキップ

PoD、予約確認、その他のリアルタイムイベントの統合

SWAT APIは、予約や車両割り当ての変更に関する通知をクライアントにディスパッチする機能をサポートしており、ERP

OMS、またはCRMシステムとのスムーズな統合を可能にします。

ユースケースは以下の通りです。

  • 予約完了後、ERPに配達証明を送信する
  • 集荷確認を送信する
  • 予約割り当ての確認を送信する
  • 予約拒否に関する通知を送信する
  • 集荷または配達失敗の通知を送信する

Webhooks Postmanコレクションを探索する Run In Postman

統合のアプローチ

警告

現在、webhookは認証をサポートしておらず、コンシューミングエンドポイントへのオープンなHTTPSアクセスが必要です。セキュリティはSWATサーバーのIPアドレスをホワイトリストに登録することで実現できます。

このようなユースケースにはwebhookを使用する必要があります。詳細については、webhookドキュメントを参照してください。統合手順は以下の通りです。

  • シミュレーションのwebhookを設定する
  • メッセージのフィルターを設定する
  • メッセージが期待通りに届くかテストする

論理図を以下に示します。

ドライバーアプリケーション、サードパーティシステム、またはPostman(テスト用)を使用して、注文(予約

)ステータスが変更されたことを通知するトリガーとしてWebリクエストを使用できます。ノードのステータスが変更されると、事前に設定されたwebhookがトリガーされます。

ヒント

シミュレーションの設定は、シミュレーションレベルまたはシミュレーションテンプレートレベルで行うことができます。シミュレーションテンプレートを使用する場合、そのテンプレートに基づいて作成された新しいシミュレーションには、継承されたwebhook設定が含まれるため、プロジェクトのテンプレートレベルで一度だけ設定を行う必要があります。これは通常、プロジェクトのセットアップ段階でSWATチームによって行われます。

イベントのライフサイクル(SWAT Driver Appを使用する場合)

関連するmessage_typeが購読されていると仮定します。

  • 車両への予約/注文の割り当て時(最適化完了後の自動割り当て、または手動調整による割り当て)に、assignmentイベントが生成されます。割り当てられた各注文ごとにイベントが生成されます。
{
"simulation_id": 165838,
"agent_type": "vehicle_group",
"message_type": "assignment",
"tracking_url": "https://<some_url>"
"data": {
"vehicle_id": 1886660,
"vehicle_agent_id": "e8de0fa7-6196-4b29-87de-8768ca804b04",
"polyline5": "....",
"nodes": [
{
"id": 12911051,
"created_at": "2025-05-08T22:47:17.655090+00:00",
"modified_at": "2025-05-08T22:47:26.755836+00:00",
"uid": "dc701f0a-d3ab-4ca2-b7f6-517f238c5926",
"lat": 1.3786144,
"lon": 103.9420438,
"h3": "0040062446533035102040",
"location_name": "Central Street",
"location_code": "",
"display_name": "Central Street",
"booking_uid": "fc3abbab-d463-49e9-9927-de4c88681306",
"booking_id": 6602801,
"customer_id": null,
"open_time_ts": "2025-05-09T12:30:00+00:00",
"close_time_ts": "2025-05-09T12:45:00+00:00",
"close_time_ts_dynamic": "2025-05-09T12:45:00+00:00",
"service_time": 300.0,
"demand": {
"sample": 1
},
"status": "assigned",
"node_type": "pickup",
"assigned_vehicle_id": 1886660,
"simulation_id": 165838,
"assignment_order": 0,
"scheduled_ts": "2025-05-09T12:30:00+00:00",
"visited_at_ts": null,
"completed_service_at": null,
"started_service_at_ts": null,
"walking_time_to_node": 0.0,
"walking_distance_to_node": 0.0,
"min_trip_duration": null,
"max_trip_duration": 30540.0,
"fixed_route_walk_time": null,
"fixed_route_ride_time": null,
"fixed_route_wait_time": null,
"fixed_route_journey_time": null,
"fixed_route_is_unreachable": false,
"cancelled_at_ts": null,
"penalty": 100000000,
"lifo_order_check": false,
"lifo_order_penalty": null,
"groups": [],
"matrix_timestamp": "2025-05-09T12:30:00+00:00",
"geofence_ids": [],
"geofence_id": null,
"transit_stop_id": null,
"transit_stop_street": null,
"transit_stop_type": null,
"transfer_type": "depart_at",
"weight": null,
"trip_cost": 0.0,
"initial_open_time_ts": null,
"initial_max_trip_duration": null,
"initial_close_time_ts": null,
"initial_close_time_ts_dynamic": null,
"max_slack": null,
"slack": 0.0,
"data": {
"phone": null,
"remarks": null,
"username": null,
"external_id": "1627132_1",
"pickup_city": "Singapore",
"dropoff_city": "Singapore",
"instructions": null,
"customer_name": null,
"pickup_region": "Singapore",
"customer_name2": null,
"customer_phone": null,
"dropoff_region": "Singapore",
"order_identity": {
"external_id": "1627132_1",
"simulation_id": 165838
},
"pickup_address": "Central Street",
"pickup_country": "SG",
"dropoff_address": "Ube street",
"dropoff_country": "SG",
"raw_order_record": {
"date": "2025-05-09",
"demand": {
"sample": "1"
},
"external_id": "1627132_1",
"demand_load_1": "1",
"demand_type_1": "sample",
"label_operator": "OR",
"multipleDemand": {
"demand_type_1": {
"sample": "1"
}
},
"pickup_address": "Central Street",
"vehicle_labels": {
"or": [
"somelabel"
]
},
"dropoff_address": "Ube street",
"pickup_zip_code": "",
"dropoff_zip_code": "",
"pickup_location_lat": "1.3786144",
"pickup_location_lon": "103.9420438",
"pickup_open_time_ts": "20:30",
"pickup_service_time": "300",
"dropoff_location_lat": "1.3245751",
"dropoff_location_lon": "103.8926381",
"dropoff_open_time_ts": "20:30",
"dropoff_service_time": "0",
"pickup_close_time_ts": "20:45",
"dropoff_close_time_ts": "23:59",
"vehicle_characteristics": {}
},
"pickup_postal_code": null,
"pickup_unit_number": null,
"dropoff_postal_code": null,
"dropoff_unit_number": null,
"pickup_location_lat": 1.3786144,
"pickup_location_lon": 103.9420438,
"pickup_customer_name": null,
"pickup_location_name": "Central Street",
"dropoff_customer_name": null,
"is_pickup_end_of_trip": null,
"pickup_customer_name2": null,
"pickup_customer_phone": null,
"dropoff_customer_name2": null,
"dropoff_customer_phone": null,
"geofence_definition_strategy": null
},
"boarding_pass": "973",
"partial_route_index": null,
"finalization_type": "min",
"allow_jump": false,
"estimated_earliest_arrival_ts": null,
"estimated_scheduled_ts": null,
"vehicle_characteristics": {},
"offer_should_be_auto_accepted": null,
"dynamic_break": null,
"user_accepted_offer_at": null,
"is_invalidated": null,
"time_windows": null,
"booking_shipment_external_id": null
},
{
"id": 12911052,
"created_at": "2025-05-08T22:47:17.655350+00:00",
"modified_at": "2025-05-08T22:47:26.755836+00:00",
"uid": "cdae9fd7-f2b3-4f90-a1ab-48c143f0a5da",
"lat": 1.3245751,
"lon": 103.8926381,
"h3": "0040062446531120132442",
"location_name": "Ube street",
"location_code": "",
"display_name": "Ube street",
"booking_uid": "fc3abbab-d463-49e9-9927-de4c88681306",
"booking_id": 6602801,
"customer_id": null,
"open_time_ts": "2025-05-09T12:30:00+00:00",
"close_time_ts": "2025-05-09T15:59:00+00:00",
"close_time_ts_dynamic": "2025-05-09T15:59:00+00:00",
"service_time": 0.0,
"demand": {
"sample": -1
},
"status": "assigned",
"node_type": "dropoff",
"assigned_vehicle_id": 1886660,
"simulation_id": 165838,
"assignment_order": 1,
"scheduled_ts": "2025-05-09T12:48:26.640000+00:00",
"visited_at_ts": null,
"completed_service_at": null,
"started_service_at_ts": null,
"walking_time_to_node": 0.0,
"walking_distance_to_node": 0.0,
"min_trip_duration": null,
"max_trip_duration": 30540.0,
"fixed_route_walk_time": null,
"fixed_route_ride_time": null,
"fixed_route_wait_time": null,
"fixed_route_journey_time": null,
"fixed_route_is_unreachable": false,
"cancelled_at_ts": null,
"penalty": 100000000,
"lifo_order_check": false,
"lifo_order_penalty": null,
"groups": [],
"matrix_timestamp": "2025-05-09T15:59:00+00:00",
"geofence_ids": [],
"geofence_id": null,
"transit_stop_id": null,
"transit_stop_street": null,
"transit_stop_type": null,
"transfer_type": "depart_at",
"weight": null,
"trip_cost": 0.0,
"initial_open_time_ts": null,
"initial_max_trip_duration": null,
"initial_close_time_ts": null,
"initial_close_time_ts_dynamic": null,
"max_slack": null,
"slack": 0.0,
"data": {
"phone": null,
"remarks": null,
"username": null,
"external_id": "1627132_1",
"pickup_city": "Singapore",
"dropoff_city": "Singapore",
"instructions": null,
"customer_name": null,
"pickup_region": "Singapore",
"customer_name2": null,
"customer_phone": null,
"dropoff_region": "Singapore",
"order_identity": {
"external_id": "1627132_1",
"simulation_id": 165838
},
"pickup_address": "Central Street",
"pickup_country": "SG",
"dropoff_address": "Ube street",
"dropoff_country": "SG",
"raw_order_record": {
"date": "2025-05-09",
"demand": {
"sample": "1"
},
"external_id": "1627132_1",
"demand_load_1": "1",
"demand_type_1": "sample",
"label_operator": "OR",
"multipleDemand": {
"demand_type_1": {
"sample": "1"
}
},
"pickup_address": "Central Street",
"vehicle_labels": {
"or": [
"somelabels"
]
},
"dropoff_address": "Ube street",
"pickup_zip_code": "",
"dropoff_zip_code": "",
"pickup_location_lat": "1.3786144",
"pickup_location_lon": "103.9420438",
"pickup_open_time_ts": "20:30",
"pickup_service_time": "300",
"dropoff_location_lat": "1.3245751",
"dropoff_location_lon": "103.8926381",
"dropoff_open_time_ts": "20:30",
"dropoff_service_time": "0",
"pickup_close_time_ts": "20:45",
"dropoff_close_time_ts": "23:59",
"vehicle_characteristics": {}
},
"pickup_postal_code": null,
"pickup_unit_number": null,
"dropoff_postal_code": null,
"dropoff_unit_number": null,
"pickup_location_lat": 1.3786144,
"pickup_location_lon": 103.9420438,
"pickup_customer_name": null,
"pickup_location_name": "Central Street",
"dropoff_customer_name": null,
"is_pickup_end_of_trip": null,
"pickup_customer_name2": null,
"pickup_customer_phone": null,
"dropoff_customer_name2": null,
"dropoff_customer_phone": null,
"geofence_definition_strategy": null
},
"boarding_pass": "572",
"partial_route_index": null,
"finalization_type": "min",
"allow_jump": false,
"estimated_earliest_arrival_ts": null,
"estimated_scheduled_ts": null,
"vehicle_characteristics": {},
"offer_should_be_auto_accepted": null,
"dynamic_break": null,
"user_accepted_offer_at": null,
"is_invalidated": null,
"time_windows": null,
"booking_shipment_external_id": null
}
],
"edges": [
{
"from_node_id": 12911051,
"to_node_id": 12911052,
"polyline5": "...",
"edge_type": "between_nodes"
}
]
},
"current_sim_ts": "2025-05-08T22:47:26.157793+00:00",
"server_ts": "2025-05-08T22:48:23.719827+00:00",
"transmit_to_websocket": true,
"agent_id": null,
"user_id": null
}
  • 予約/注文の拒否時(最適化の結果、予約が拒否され、車両に割り当てられない場合)に、no_offerタイプのイベントが発行されます。1回の最適化につき1つのイベントが生成され、最適化されずに車両に割り当てられない複数の予約が含まれる場合があります。
{
"simulation_id": 165837,
"agent_type": "scheduler",
"message_type": "no_offer",
"data": {
"booking_ids": [
6602761,
6602779
],
"booking_uids": [
"526f8cfd-4814-4365-98a1-e2333c6bc9f3",
"23040721-0b5c-4d42-9dd6-46d561e4a573"
]
},
"current_sim_ts": "2025-05-08T22:31:50.871386+00:00",
"server_ts": "2025-05-08T22:32:31.930735+00:00",
"transmit_to_websocket": true,
"agent_id": null,
"user_id": null
}
  • 車両が稼働可能になった場合(つまり、現在の時刻がシミュレーションの開始時刻と終了時刻の範囲内であり、車両の開始時刻と終了時刻の間である場合)、各車両について数分ごとにvehicle_arrivalタイプのイベントが生成されます。これは、車両のライブETAを取得するのに役立ちます。
{
"simulation_id": 165837,
"agent_type": "vehicle",
"message_type": "vehicle_arrival",
"data": {
"booking_id": 6602769,
"booking_uid": "095796ae-d630-4b1c-875b-d311cc376ccc",
"node_id": 12910987,
"node_uid": "299c60e3-ed3e-4aac-8933-0635ec594504",
"node_type": "pickup",
"estimated_earliest_arrival_ts": "2025-05-08T22:40:01.251570+00:00",
"estimated_scheduled_ts": "2025-05-09T01:30:00+00:00",
"scheduled_ts": "2025-05-09T01:30:00+00:00",
"vehicle_id": 1886604,
"vehicle_agent_id": "08785064-406a-44d0-9e17-1ebaccb5d79d"
},
"current_sim_ts": "2025-05-08T22:40:01.251570+00:00",
"server_ts": "2025-05-08T22:40:01.251570+00:00",
"transmit_to_websocket": false,
"agent_id": null,
"user_id": null
}
  • 集荷が成功すると、node_statusイベントが発行されます。このイベントは、集荷が成功するたびに生成されます。
{
"simulation_id": 165838,
"agent_type": "vehicle",
"message_type": "node_status",
"data": {
"node_uid": "f749a1f3-3ef4-493f-aff4-b9e25a23cdd0",
"status": "completed",
"vehicle_id": 1886760,
"node_id": 12911043,
"node_type": "pickup",
"booking_uid": "03550997-1ee0-4f5e-9cfa-267075b612ae",
"booking_id": 6602797,
"action_data": {
"action_type": "pickup_success",
"lat": -43.5481285,
"lon": 172.6854415,
"driver_uid": null,
"image_urls": [
"https://sgerp-stage.d.gcdev.swatrider.com/api/v2/microservices/image/c330dd78-f4b0-4bab-a6ef-23faf3597fe3"
],
"data": {
"driver_note": {
"pickup_items": {
"Samples": 50
}
}
}
},
"is_confirmation": true
},
"current_sim_ts": "2025-05-09T10:53:18.976000+12:00",
"server_ts": "2025-05-08T22:53:19.218878+00:00",
"transmit_to_websocket": false,
"agent_id": "467e618f-84ed-4b91-bfa9-e79020e394bf",
"user_id": 13529
}
  • 集荷が失敗すると、fail_to_boardイベントが発行されます。このイベントは、集荷が失敗するたびに生成されます。

{
"simulation_id": 165987,
"agent_type": null,
"message_type": "fail_to_board_confirmation",
"data": {
"booking_ids": [
6605341
],
"booking_uids": []
},
"current_sim_ts": "2025-05-09T20:42:59.003000+12:00",
"server_ts": "2025-05-09T08:42:59.648019+00:00",
"transmit_to_websocket": false,
"agent_id": null,
"user_id": null
}

  • 配達(ドロップオフ)が成功すると、node_statusイベントが発行されます。このイベントは、ドロップオフが成功するたびに生成されます。
{
"simulation_id": 165839,
"agent_type": "vehicle",
"message_type": "node_status",
"data": {
"node_uid": "4f554055-5f6f-400b-9c14-b404fa7c4ee5",
"status": "completed",
"vehicle_id": 1886918,
"node_id": 12911150,
"node_type": "dropoff",
"booking_uid": "b1fa1f17-efbe-4504-a220-bc517c1c6d32",
"booking_id": 6602850,
"action_data": {
"action_type": "proof_of_delivery",
"lat": -43.5481273,
"lon": 172.6854356,
"driver_uid": null,
"image_urls": [
"https://sgerp-stage.d.gcdev.swatrider.com/api/v2/microservices/image/8f8cb90f-b75f-4f50-b768-d52b011b269f"
],
"data": {
"driver_note": {}
}
},
"is_confirmation": true
},
"current_sim_ts": "2025-05-09T11:29:41.323000+12:00",
"server_ts": "2025-05-08T23:29:41.579335+00:00",
"transmit_to_websocket": false,
"agent_id": "5839cf90-fafc-4d0e-94f4-b87be50a4a1e",
"user_id": 13529
}
  • 配達(ドロップオフ)が失敗すると、node_statusイベントが発行されます。このイベントは、ドロップオフが失敗するたびに生成されます。
{
"simulation_id": 165839,
"agent_type": "vehicle",
"message_type": "node_status",
"data": {
"node_uid": "6816e777-d510-43d7-acd7-a3ccd28968b2",
"status": "fail_to_deliver",
"vehicle_id": 1886918,
"node_id": 12911106,
"node_type": "dropoff",
"booking_uid": "f0d9e122-181a-4b06-8de7-aed7aafca879",
"booking_id": 6602828,
"action_data": {
"action_type": "failure_of_delivery",
"lat": -43.5481273,
"lon": 172.6854356,
"driver_uid": null,
"image_urls": [],
"data": {
"comment": "n99ne here",
"driver_note": {}
}
},
"is_confirmation": true
},
"current_sim_ts": "2025-05-09T11:29:41.323000+12:00",
"server_ts": "2025-05-08T23:29:41.583098+00:00",
"transmit_to_websocket": false,
"agent_id": "5839cf90-fafc-4d0e-94f4-b87be50a4a1e",
"user_id": 13529
}

関連する設定

PATCH https://<base_url>/api/v2/simulation/<simulation_id>

Webhooks subscription in simulation.data object
{
"data": {
...
"messaging_webhook_url" : "https://<webhook_url>",
"messaging_webhook_message_types" : ["node_status"]
...
}
}
警告

既存の設定を維持するためには、推奨されるアプローチに従うことが重要です。これには、まずGET https://<base_url>/api/v2/simulation/<simulation_id>を使用してdataオブジェクトを取得し、そのdataフィールドにwebhook設定を追加してから、完全なdataオブジェクトでPATCHを実行することが含まれます。この方法により、現在の設定が確実に保持されます。

メッセージフィルターでnode_statusが選択されている場合、シミュレーション内の任意のノード

のステータスが変更されると、webhookがトリガーされます。たとえば、集荷またはドロップオフが発生し、ドライバーがドライバーアプリケーションを使用して配達を確認すると、ノードのステータスが変更されます。同じ確認は、ノードステータスを更新するAPIリクエストを通じて行うこともできます。

オプションで、コンシューミングアプリケーションが予約が車両に割り当てられた(または配達がスケジュールされた)ときに通知される必要がある場合、assignmentメッセージをmessaging_webhook_message_typesリストに追加できます。通常、これはルート最適化の実行中、またはアドホックな予約が実行のためにシミュレーションに追加されたとき(たとえば、勤務シフトの途中)に発生します。

ドロップオフが発生したことをシステムに通知する

ヒント

予約

には、集荷場所とドロップオフ場所を表す少なくとも2つのノードが含まれています。これが、ノードを使用してwebhookをトリガーする必要がある理由です(同じ予約内のドロップオフまたは集荷のいずれか)。どのノードが予約に属するかを調べるには、GET <base_url>/api/v2/node?booking=<booking_id>を使用できます。

このステップは、コンシューミングアプリケーションがSWATバックエンドで予約の状態を管理する必要がある場合にのみ必要です。たとえば、予約の状態はERPで変更されるか、顧客のドライバーアプリケーションである場合があります。SWATドライバーアプリケーションが使用されている場合、ドライバーのワークフローが予約の状態を自動的に変更するため、このステップはスキップできます。

たとえば、予約のドロップオフを確認するには、このリクエストを使用できます。

POST https://<base_url>/api/v2/microservices/node_status

Submit node status update message
{
"simulation_id": 172571, //Simulation id to update the data for
"data": {
"booking_id": 22151625, //Booking integer identifier to update th value for
"status": "completed", //New status of the node. Supported node statuses:
"vehicle_id": 17590317,
"booking_uid": "e438ab3d-b33a-572d-a114-0a5490e07f40",
"node_type": "dropoff",
"node_id": 48332514,
"node_uid": "a1d1a6ae-9a0d-40c1-a633-3d6ef05cf7b9"
},
"current_sim_ts": "2024-11-16T18:26:22Z"
}

集荷の失敗をシステムに通知するには、以下のペイロード例を送信します。

POST https://<base_url>/api/v2/microservices/node_status

Submit node status update message
{
"simulation_id": 172571, //Simulation id to update the data for
"data": {
"booking_id": 22151625, //Booking integer identifier to update th value for
"status": "fail_to_board", //New status of the node. Supported node statuses:
"vehicle_id": 17590317,
"booking_uid": "e438ab3d-b33a-572d-a114-0a5490e07f40",
"node_type": "pickup",
"node_id": 48332514,
"node_uid": "a1d1a6ae-9a0d-40c1-a633-3d6ef05cf7b9",
"action_data": {
"lat":0,
"lon":0,
"action_type": "cancelled",
"data":
{
"comment": "cancelled"
}
}
},
"current_sim_ts": "2024-11-16T18:26:22Z"
}

さらに、ドライバーのコメント、配達の実際の場所、ドキュメントの画像など、ノードの変更に関する特定の情報を追加するオプションがあります。以下の例はこれを示しています。

POST https://<base_url>/api/v2/microservices/node_status

Submit node status update message
{
"data": {
"status": "completed",
"node_id": 2349069,
"node_uid": "32b0ef45-6baa-44aa-8203-ce9312ab645b",
"node_type": "dropoff",
"booking_id": 1122584,
"vehicle_id": 182389,
"action_data": {
"lat": 1.3,
"lon": 103.8,
"data": {},
"image_urls": [
"https://firebasestorage.googleapis.com:443/v0/b/<some_url>"
],
"action_type": "proof_of_delivery",
"action_subtype": "photo"
},
"booking_uid": "efbbe0f6-a80c-520b-81fa-5f1621cfd90b"
},
"simulation_id": 19138,
"current_sim_ts": "2022-05-16T18:30:57Z"
}

また、複数のノードを更新する必要がある場合は、一括更新APIを使用できます。

POST https://<base_url>/api/v2/microservices/node_status_list

Submit node status update message
{
"simulation_id": 123,
"current_sim_ts": "string",
"data": {
"vehicle_id": 123,
"node_updates": [
{
"node_id": 123,
"status": "new",
"action_data": {}
}
]
}
}
ヒント

コンシューマーがSWAT Driver Appを使用している場合、通知はモバイルアプリケーションによって必要なすべてのデータとともに自動的に生成されます。これらのnode_statusリクエストは、サードパーティのフィールドアプリケーションが使用されている場合、または配達確認がERPやOMSなどの外部システムから来る場合にのみ必要です。

Webhookを介したコンシューマーによる通知メッセージの受信

シミュレーション設定が構成されると、node_statusの変更に関するメッセージがPOSTメソッドを介して設定されたエンドポイントに到着します。ペイロードの例:

Example of completed drop offs
{
"simulation_id": 172571,
"agent_type": "vehicle",
"message_type": "node_status",
"data": {
"node_uid": "a1d1a6ae-9a0d-40c1-a633-3d6ef05cf7b9",
"status": "completed",
"vehicle_id": 17590317,
"node_id": 48332514,
"node_type": "dropoff",
"booking_uid": "e438ab3d-b33a-572d-a114-0a5490e07f40",
"booking_id": 22151625,
"action_data": null,
"is_confirmation": true
},
"current_sim_ts": "2024-11-16T18:26:22+00:00",
"server_ts": "2024-09-10T04:33:23.364180",
"transmit_to_websocket": false,
"agent_id": "daae025f-f21d-4c65-b901-45e139283667",
"user_id": 57638
}

フィールドの可能な設定については、POST https://<base_url>/api/v2/microservices/node_statusエンドポイントのリファレンスドキュメントの例を参照してください。

Webhook受信後のノードと予約ステータスの取得

webhookメッセージにコンシューマーが必要とする情報(たとえば、コンシューマーが使用する顧客識別子とのマッピング)が含まれていない場合、関連するノード

(および予約)のすべてのデータを取得するために追加のリクエストが必要になる場合があります。

リクエストの例は、node_idがwebhookメッセージからのノード識別子である場合、次のようになります。 GET https://<base_url>/api/v2/node/{node_id}

このリクエストは、dropoffpickupなどのnode_typeを含む、そのノードに関連付けられたすべてのデータと、現在のstatusを返します。

ヒント

bookingは少なくとも2つのnodes(集荷とドロップオフなど)を参照し、webhookは1つのノード更新に対してのみトリガーされるため、各予約は予約内のすべてのノードが完了したときに完全に完了します。

通知でサポートされるデータ

通知には、配達証明の画像、ドライバーのメモ、ドロップオフが発生した実際の場所など、action_dataオブジェクト内のオプションフィールドを含めることができます。

PODを含むその他の関連ステータスについては、失敗したドロップオフ、集荷、POD付きの集荷に対する応答を含むPOST https://<base_url>/api/v2/microservices/node_statusの例を参照してください。

Example of optional action_data field for traceability
{
"action_data": {
"type": "object",
"description": "Optional data associated with the event (for example, a link to PoD image)",
"properties": {
"lat": {
"type": "number",
"description": "Latitude of the vehicle when the action happened"
},
"lon": {
"type": "number",
"description": "Longtitude of the vehicle when the action happened"
},
"action_type": {
"type": "string",
"description": "Type of action"
},
"data": {
"type": "object",
"properties": {
"comment": {
"type": "string",
"description": "optional comment that a driver can leave"
}
}
},
"image_urls": {
"type": "array",
"description": "URLs of uploaded attachments (such as photos of POD)",
"items": {
"type": "string",
"format": "uri"
}
}
}
}
}

配達証明の画像を取得する

webhookメッセージで説明したように、メッセージにはオプションフィールドaction_data.image_urls[]が含まれる場合があり、これには通知とノードに添付された画像のリストが含まれます。画像を取得するには、次の2つのステップを実行する必要があります。

ヒント

画像は、シナリオに応じてドロップオフポイントまたは集荷ポイントのいずれかに添付できます(たとえば、ミルクランの場合、両方である可能性があります)。通常、配達アプリケーションの場合、配達証明はドロップオフノードで利用できます。この場合、data.node_type=dropoffを含むメッセージの画像のみをリクエストしてください。

ノードの画像リストの取得

ノードで利用可能な画像のリストを取得するには、以下を使用します。 GET https://<base_url>/api/v2/imagestoreitem?node=<node_id> ここで、node_idはwebhookメッセージのdata.node_idフィールドから取得する必要があります。結果には、そのノードで利用可能な画像が含まれます。以下の例では、ノードには2つの画像(署名と配達された商品の写真)が添付されています。SWAT Driverアプリが使用されている場合、応答フィールドobjects[].imageの画像ファイル名を使用して、署名と配達/集荷の写真を区別できます。

JSONペイロードを見る
Example for retrieving image_id
{
"meta": {
"has_more": false,
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 2
},
"objects": [
{
"booking": "/api/v2/booking/5888352",
"created_at": "2024-09-30T09:04:40.780442+00:00",
"description": "None",
"driver": null,
"h3": null,
"id": "005afc5d-66d8-45f5-a8f8-2f6397f09758",
"image": "http://mot-stage-dev.s3.amazonaws.com/sgerp/sgerp-stage/image_store/swat_delivery_test_DO.jpg",
"lat": 0,
"lon": 0,
"modified_at": "2024-09-30T09:04:40.780466+00:00",
"name": "swat delivery 253_PU_1",
"node": "/api/v2/node/11452232",
"project": "/api/v2/project/550",
"resource_uri": "/api/v2/imagestoreitem/005afc5d-66d8-45f5-a8f8-2f6397f09758",
"simulation": "/api/v2/simulation/122093",
"user": "/api/v2/user/4014",
"vehicle": "/api/v2/vehicle/1726343"
},
{
"booking": "/api/v2/booking/5888352",
"created_at": "2024-09-30T09:04:41.297751+00:00",
"description": "None",
"driver": null,
"h3": null,
"id": "ba9a077f-806b-4ccb-8761-e80f29b8e092",
"image": "http://mot-stage-dev.s3.amazonaws.com/sgerp/sgerp-stage/image_store/swat_delivery_test_signature.jpeg",
"lat": 0,
"lon": 0,
"modified_at": "2024-09-30T09:04:41.297774+00:00",
"name": "swat_delivery_253_PU_signature",
"node": "/api/v2/node/11452232",
"project": "/api/v2/project/550",
"resource_uri": "/api/v2/imagestoreitem/ba9a077f-806b-4ccb-8761-e80f29b8e092",
"simulation": "/api/v2/simulation/122093",
"user": "/api/v2/user/4014",
"vehicle": "/api/v2/vehicle/1726343"
}
]
}

画像のダウンロード

画像をダウンロードするには、以下を使用します。 GET https://<base_url>/api/v2/microservices/image/<image_uid> ここで、image_uidobjects[].idフィールドの値です。 このリクエストは、実際の画像を含むimage/pngバイナリストリームを返します。必要に応じて、他の画像についてもこのリクエストを繰り返します。

ドロップオフまたは集荷の失敗

APIクライアント(またはSWAT Driver App)は、失敗したドロップオフと集荷に関するメッセージをバックエンドに準備して送信する責任があります。失敗した集荷の場合、その予約のドロップオフを実行する必要がないため、失敗したドロップオフと集荷を処理するために異なるワークフローが実装されています。

警告

失敗したドロップオフと集荷に関するメッセージを受信するには、コンシューマーはnode_statusfail_to_boardの2つのメッセージタイプを購読する必要があります。

失敗したドロップオフ

SWATバックエンドには、失敗したドロップオフに関する情報が、そのドロップオフに対応するノードを以下のリクエストで更新することで通知されます。

POST /api/v2/microservices/node_status

{
"simulation_id": 19138,
"current_sim_ts": "2022-05-16T18:34:00Z",
"data": {
"booking_uid": "367ce4d5-7f97-5fff-b8b7-65b3ed991ea7",
"node_id": 2349059,
"booking_id": 1122579,
"vehicle_id": 182389,
"status": "fail_to_deliver",
"node_type": "dropoff",
"action_data": {
"lat": 1.3,
"data": {
"comment": "Recipient not home"
},
"action_type": "failure_of_delivery",
"lon": 103.8,
"image_urls": []
},
"node_uid": "404a9948-df7c-4535-8c5a-ebd9ae5c40dc"
}
}

このリクエストの結果として、node_statusタイプのwebhookメッセージがトリガーされます。これにはaction_dataフィールドからの情報が含まれ、対応する予約がfailed_to_deliverとしてマークされます。ノードは車両に割り当てられたままになりますが(これは予約の再配達をスケジュールするために使用できます)、ノードもassigned状態のままになります。

Webhookメッセージは次のようになります。

{
"simulation_id": 124551,
"agent_type": "vehicle",
"message_type": "node_status",
"data": {
"node_uid": "02eb7d5c-0a92-4604-8181-0f663f4f9212",
"status": "fail_to_deliver",
"vehicle_id": 1737453,
"node_id": 11564954,
"node_type": "dropoff",
"booking_uid": "2bf03eec-e439-4dd6-afd3-ed9dca5286d7",
"booking_id": 5950159,
"action_data": {
"action_type": "failure_of_delivery",
"lat": 1.3,
"lon": 103.8,
"driver_uid": "",
"image_urls": [],
"data": {
"comment": "Recipient not home"
}
},
"is_confirmation": true
},
"current_sim_ts": "2024-10-16T18:34:00+00:00",
"server_ts": "2024-10-24T06:07:23.699668",
"transmit_to_websocket": false,
"agent_id": "3d3d1b35-0010-434d-ac2d-a8c99722f1c3",
"user_id": 13529
}

失敗した集荷

SWATバックエンドは、失敗したドロップオフに関する通知を、以下のリクエストを介してその集荷に対応するノードを更新することで受け取ります。

POST /api/v2/microservices/fail_to_board

{
"simulation_id": 124551,
"current_sim_ts": "2024-10-31T17:00:00.192934+00:00",
"data": {
"booking_ids": [
5950160
]
}
}

このリクエストの結果として、fail_to_boardタイプのwebhookメッセージが生成されます。予約ステータスはfailed_to_boardに更新され、予約内のノードはfailed_to_boardとしてマークされ、ノードに割り当てられた車両は削除されます。その結果、予約は実行不可能になり、最適化プロセスに参加しなくなります。

Webhookメッセージは次の形式になります。

{
"simulation_id": 124551,
"agent_type": "vehicle",
"message_type": "fail_to_board",
"data": {
"booking_ids": [
5950160
]
},
"current_sim_ts": "2024-10-31T17:00:00.192934+00:00",
"server_ts": "2024-10-24T05:44:39.713834",
"transmit_to_websocket": false,
"agent_id": "3d3d1b35-0010-434d-ac2d-a8c99722f1c3",
"user_id": 13529
}