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

ウェブフックとクライアント通知 (Webhooks and client notifications)

リアルタイム運用に関連する SWAT システムとサービスは、メッセージキューを使用して、コンシューマーのリアルタイム通知を実装しています。これらの通知は、着信予約、車両の移動、オファー、スケジューラの更新など、さまざまなイベントをカバーしています。

メッセージングシステムを活用するために、クライアントはウェブフックを使用してこれらのメッセージをサブスクライブできます。

メッセージのサブスクライブ (Subscribing to messages)

ウェブフックへのサブスクリプションは、ウェブフックアドレスとクライアントが受信したいメッセージのフィルターを設定することにより、(シミュレーション (simulation)

) のレベルでクライアントが管理できます。

これを行うには、リクエストを介してシミュレーションにパッチを適用できます。あるいは、simulation template を使用することもできます。

PATCH による構成 (Configuration via PATCH)

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

危険

シミュレーション設定内のオブジェクトを更新するときは、特に data フィールドに注意してください。data フィールドは、厳密なモデルに関連付けられていない任意の JSON オブジェクトです。以下のようなリクエストを送信すると、data オブジェクト全体が 置換 され、既存の値がすべて消去されます。

data プロパティに新しい値を安全に追加するには:

  1. 現在のシミュレーションオブジェクトを取得します。
  2. data 辞書を新しいフィールドで更新します。
  3. 完全なマージされた data ペイロードでシミュレーションに PATCH を適用します。
Webhooks subscription payload
{
"data": {
"messaging_webhook_url": "https://your-webhook-url.com/endpoint",
"messaging_webhook_message_types": [
"assignment",
"bookings",
"bookings_cancellation",
"fail_to_board",
"offers",
"no_offer",
"node_status",
"offer_accepted",
"offer_rejected",
"vehicle_arrival",
"vehicle_state_changed"
]
}
}
警告

ウェブフックは現在、認証メカニズム(HMAC 署名など)をサポートしていません。ウェブフックエンドポイントを保護する推奨される方法は、通知を発行する SWAT バックエンドサービスの IP アドレスをホワイトリストに登録することです。

メッセージ構造 (Message Structure)

すべてのウェブフックメッセージは、共通のエンベロープ構造を共有しています。data フィールドには、イベント固有のペイロードが含まれています。

Base message schema
{
"simulation_id": 12345,
"agent_type": "scheduler",
"message_type": "assignment",
"agent_id": "optional-uuid-string",
"data": {
"key": "value"
},
"current_sim_ts": "2025-04-01T12:00:00+00:00",
"server_ts": "2025-04-01T12:00:00.123456+00:00",
"transmit_to_websocket": false
}
フィールド説明
simulation_idイベントを生成しているシミュレーションの整数 ID。
agent_typeメッセージを生成しているエージェントのタイプ(例:schedulervehicleevent_publisher)。
message_typeイベントの特定のタイプ(例:bookingsassignment)。
agent_id(オプション) 特定のエージェントインスタンスの UUID。
dataメッセージのペイロード。構造は message_type に依存します。
current_sim_tsシミュレーションロジック内のタイムスタンプ(リアルタイム操作では、現在の時刻に対応します)。
server_tsサーバーによってメッセージが処理されたときのタイムスタンプ。
transmit_to_websocketこのメッセージが WebSocket クライアント向けであるかどうかを示すブール値。

イベントタイプ (Event Types)

予約イベント (Booking Events)

新しい予約 (bookings)

新しい予約が作成されたときにトリガーされます。

{
"simulation_id": 123,
"agent_type": "event_publisher",
"message_type": "bookings",
"data": {
"bookings": [
{
"id": 1001,
"uid": "uuid-string",
"pickup_lat": 1.23,
"pickup_lon": 103.45
}
]
},
"current_sim_ts": "2025-04-01T12:00:00+00:00",
"server_ts": "2025-04-01T12:00:00.123+00:00",
"transmit_to_websocket": true
}

予約キャンセル (bookings_cancellation)

予約がキャンセルされたときにトリガーされます。

{
"simulation_id": 123,
"agent_type": "event_publisher",
"message_type": "bookings_cancellation",
"data": {
"booking_ids": [1001, 1002]
},
"current_sim_ts": "2025-04-01T12:05:00+00:00",
"server_ts": "2025-04-01T12:05:00.123+00:00",
"transmit_to_websocket": true
}

乗車失敗 (fail_to_board)

乗客が乗車しなかった(ノーショー)場合にトリガーされます。

{
"simulation_id": 123,
"agent_type": "vehicle",
"message_type": "fail_to_board",
"data": {
"booking_ids": [1001],
"booking_uids": ["uuid-string"]
},
"current_sim_ts": "2025-04-01T12:30:00+00:00",
"server_ts": "2025-04-01T12:30:00.123+00:00",
"transmit_to_websocket": true
}

オファーイベント (Offer Events)

オファー生成 (offers)

予約に対してオファーが生成されたときにトリガーされます。

JSON の例を表示
{
"simulation_id": 3622,
"agent_type": "event_publisher",
"message_type": "offers",
"data": {
"offer_ids": [60201],
"offers": [
{
"id": 60201,
"uid": "fc57f35c-f254-4831-93fd-b987907eb1ad",
"service_session_id": "78a0034a-dbf1-4f37-8d93-7e97aada432f",
"booking_id": "8d191c2a-2371-4111-9d81-328d20be0e5c",
"vehicle_id": "69b751c0-9b35-46a9-943d-73b68eb76b63",
"offer_pickup_location_lat": 35.705422,
"offer_pickup_location_lon": 139.562104,
"estimated_pickup_time": "2020-07-25T02:13:10.993305+00:00",
"demand": { "passenger": 1 }
}
]
},
"current_sim_ts": "2020-07-25T02:10:50.244+00:00",
"server_ts": "2020-07-25T02:10:50.244+00:00",
"transmit_to_websocket": false
}

オファー承認 (offer_accepted)

ユーザーがオファーを受け入れたときにトリガーされます。

{
"simulation_id": 123,
"agent_type": "event_publisher",
"message_type": "offer_accepted",
"data": {
"offer_id": 60201
},
"current_sim_ts": "2025-04-01T12:10:00+00:00",
"server_ts": "2025-04-01T12:10:00.123+00:00",
"transmit_to_websocket": true
}

オファー拒否 (offer_rejected)

オファーが拒否されたか、期限切れになったときにトリガーされます。

{
"simulation_id": 123,
"agent_type": "event_publisher",
"message_type": "offer_rejected",
"data": {
"offer_id": 60201
},
"current_sim_ts": "2025-04-01T12:11:00+00:00",
"server_ts": "2025-04-01T12:11:00.123+00:00",
"transmit_to_websocket": true
}

オファーなし (no_offer)

スケジューラが予約に適したオファーを見つけられなかったときにトリガーされます。

{
"simulation_id": 123,
"agent_type": "scheduler",
"message_type": "no_offer",
"data": {
"booking_ids": [6478566],
"booking_uids": ["aa082b4c-e8b3-4caf-a9f2-aba007bdde66"]
},
"current_sim_ts": "2025-04-01T00:32:45.043+00:00",
"server_ts": "2025-04-01T00:33:16.168+00:00",
"transmit_to_websocket": true
}

スケジューラおよび割り当てイベント (Scheduler & Assignment Events)

計算開始 (calc_started)

スケジューラが予約のバッチの計算を開始するときにトリガーされます。

{
"simulation_id": 123,
"agent_type": "scheduler",
"message_type": "calc_started",
"data": {
"booking_ids": [101, 102],
"booking_uids": ["uuid-1", "uuid-2"]
},
"current_sim_ts": "2025-04-01T12:00:00+00:00",
"server_ts": "2025-04-01T12:00:00.123+00:00",
"transmit_to_websocket": false
}

スケジューラ結果 (scheduler_result)

割り当て前の計算結果が含まれます(内部/デバッグ用)。

{
"simulation_id": 123,
"agent_type": "scheduler",
"message_type": "scheduler_result",
"data": {
"nodes": [],
"vehicle_id": 1854642
},
"current_sim_ts": "2025-04-01T12:01:00+00:00",
"server_ts": "2025-04-01T12:01:00.123+00:00",
"transmit_to_websocket": false
}

割り当て (assignment)

車両へのルート(ノード)の割り当ての確認。これは車両が実行するための指示です。

JSON の例を表示
{
"simulation_id": 158064,
"agent_type": "vehicle_group",
"message_type": "assignment",
"data": {
"vehicle_id": 1854642,
"vehicle_agent_id": "6a955d42-706a-4b54-9562-391bc74fbd01",
"nodes": [
{
"id": 12648515,
"uid": "4c6ed49d-fe30-4243-9683-8e20ff60546d",
"lat": 1.339019,
"lon": 103.852623,
"node_type": "pickup",
"status": "assigned",
"booking_id": 6478564
},
{
"id": 12648516,
"uid": "9eb83008-7c5e-45d0-9743-73d62ede782a",
"lat": 1.329019,
"lon": 103.862623,
"node_type": "dropoff",
"status": "assigned",
"booking_id": 6478564
}
],
"edges": [
{
"from_node_id": 12648515,
"to_node_id": 12648516,
"polyline5": "encoded_polyline_string",
"edge_type": "between_nodes"
}
]
},
"current_sim_ts": "2025-04-01T12:02:00+00:00",
"server_ts": "2025-04-01T12:02:00.123+00:00",
"transmit_to_websocket": true
}

車両ステータスイベント (Vehicle Status Events)

車両到着 (vehicle_arrival)

performance_tracker_enabled が true の場合、定期的に生成されます。今後のノードの ETA 情報が含まれます。

{
"simulation_id": 158066,
"agent_type": "vehicle",
"message_type": "vehicle_arrival",
"data": {
"booking_id": 6478565,
"booking_uid": "aa082b4c-e8b3-4caf-a9f2-aba007bdde63",
"node_id": 12648518,
"node_uid": "89bfed3c-6ec2-43de-b399-2767319aacb3",
"node_type": "dropoff",
"estimated_earliest_arrival_ts": "2025-04-01T00:45:55+00:00",
"estimated_scheduled_ts": "2025-04-01T07:00:00+00:00",
"scheduled_ts": "2025-04-01T07:00:00+00:00",
"vehicle_id": 1854644
},
"current_sim_ts": "2025-04-01T00:39:04+00:00",
"server_ts": "2025-04-01T00:39:04+00:00",
"transmit_to_websocket": false
}

車両到着グループ化 (vehicle_arrival_grouped)

車両ごとにグループ化された到着メッセージのリスト。

{
"simulation_id": 1,
"agent_type": "vehicle",
"message_type": "vehicle_arrival_grouped",
"data": {
"vehicle_id": 1,
"vehicle_agent_id": "12345",
"arrivals": [
{
"vehicle_id": 1,
"node_id": 1,
"estimated_earliest_arrival_ts": "2021-02-19T15:27:24+00:00"
}
]
},
"current_sim_ts": "2021-02-03T08:17:09+00:00",
"server_ts": "2021-02-03T08:17:09+00:00",
"transmit_to_websocket": false
}

ノードステータス (node_status)

車両がノードを完了したとき(例:ピックアップ成功、ドロップオフ)にトリガーされます。

{
"simulation_id": 158066,
"agent_type": "vehicle",
"message_type": "node_status",
"data": {
"node_uid": "cc90ed77-88c3-4f79-9aa6-b61d78d5ca44",
"status": "completed",
"vehicle_id": 1854644,
"node_type": "pickup",
"action_data": {
"action_type": "pickup_success",
"data": {
"driver_note": {
"additional_note": "notes"
}
}
}
},
"current_sim_ts": "2025-04-01T14:18:18+00:00",
"server_ts": "2025-04-01T01:18:18+00:00",
"transmit_to_websocket": false
}

車両状態変更 (vehicle_state_changed)

新しいルートの割り当てやステータスの変更など、車両状態の一般的な変更を示します。

{
"simulation_id": 158066,
"agent_type": "vehicle",
"message_type": "vehicle_state_changed",
"data": {
"vehicle_id": 1854644,
"instance_changed": true,
"nodes_changed": true,
"update": {
"path": "encoded_polyline_string"
}
},
"current_sim_ts": "2025-04-01T00:34:04+00:00",
"server_ts": "2025-04-01T00:34:04+00:00",
"transmit_to_websocket": false
}

車両状態 (vehicle_states)

車両の内部状態の詳細なスナップショット。

{
"simulation_id": 123,
"agent_type": "vehicle",
"message_type": "vehicle_states",
"data": {
"vehicle_states": [
{
"id": 1,
"lat": 1.3,
"lon": 103.8,
"status": "idle",
"current_route": []
}
]
},
"current_sim_ts": "2025-04-01T12:00:00+00:00",
"server_ts": "2025-04-01T12:00:00+00:00",
"transmit_to_websocket": false
}

GPS データ (gps_data)

生の場所更新イベント。

{
"simulation_id": 123,
"agent_type": "vehicle",
"message_type": "gps_data",
"data": {
"vehicle_event": "gps_data",
"vehicle_id": 1756,
"lat": 1.3,
"lon": 103.88,
"bearing": 100,
"speed": 9.8,
"device_ts": "2025-04-01T12:00:00+00:00"
},
"current_sim_ts": "2025-04-01T12:00:00+00:00",
"transmit_to_websocket": true
}

車両使用 (vehicle_use)

車両が有効または無効になったときにトリガーされます。

{
"simulation_id": 123,
"agent_type": "vehicle",
"message_type": "vehicle_use",
"data": {
"vehicle_id": 10,
"action": "disabled"
},
"current_sim_ts": "2025-04-01T12:00:00+00:00",
"server_ts": "2025-04-01T12:00:00+00:00",
"transmit_to_websocket": true
}

需要変更 (demand_modification)

{
"simulation_id": 123,
"agent_type": "vehicle_group",
"message_type": "demand_modification",
"data": {
"vehicle_id": 1,
"node_id": 100,
"tickets": [{ "demand": 1, "ticket_type": "passenger" }]
},
"current_sim_ts": "2025-04-01T12:00:00+00:00",
"server_ts": "2025-04-01T12:00:00+00:00",
"transmit_to_websocket": true
}

ウェブフックのテスト (Testing Webhooks)

smee.io などのサードパーティのプロキシサービスを使用して、ウェブフックをテストできます。

  1. チャネルの作成: https://smee.io/ にアクセスし、「Start a new channel」をクリックします。
  2. シミュレーションの構成: シミュレーションの messaging_webhook_url を Smee URL で更新します。
  3. ローカルプロキシ (オプション): メッセージをローカルで処理する場合は、Smee クライアントをインストールします。
    npm install --global smee-client
    smee -u https://smee.io/your_token -p 3001
  4. メッセージの表示: smee.io ページでメッセージを直接表示するか、ローカルサーバーで処理できます。

単純な Node.js ロガー (Simple Node.js Logger)

このスクリプトを実行して、着信ウェブフックペイロードをコンソールにログ記録します。

const http = require('http');

const server = http.createServer((req, res) => {
let body = [];
req.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
try {
body = Buffer.concat(body).toString();
// Try to parse JSON for prettier output if possible, otherwise print string
console.log(`==== ${req.method} ${req.url}`);
console.log('> Headers:', req.headers);
console.log('> Body:', body);
} catch(e) {
console.error("Error processing body", e)
}
res.end();
});
});

server.listen(3001, () => {
console.log('Listening on port 3001...');
});