openvibers/openvibe.bot Commits

Bot: bot.robot.online/offline name the robot's owner (contracts 0.192.0), for Quest's robot quest (#129)

OP OpenVibers committed 29 days ago · a63927e0e7 · 6 files, +16 −9

Changes

ddiff --git a/README.md b/README.md
iindex f3b22d9..24777db 100644
---- a/README.md
++++ b/README.md
@@@ -146,7 +146,7 @@ Set `BOT_ONVIF_CAMERAS` (JSON, unset by default) to the server-side cameras Bot
OpenVibe.Sites no longer generates `deploy/nginx/openvibe.bot.conf` (sites.json marks the vhost as owned by OpenVibe.Bot), and Bot serves nothing from a Sites checkout: the legal pages, `robots.txt`, `sitemap.xml`, `manifest.webmanifest` and the 404 page all come from the app. A Sites deploy leaves an installed vhost it no longer generates in place, so the current Sites vhost keeps serving openvibe.bot until Bot's first deploy installs this file over it; later Sites deploys never overwrite Bot's `/device` and `/control` routes.
<!-- versions:start -->
--- openvibe-contracts: v0.188.2
++- openvibe-contracts: v0.192.0
- openvibe-sdk: v0.46.0
- openvibe-shared: v4.2.1
<!-- versions:end -->
ddiff --git a/STATUS.json b/STATUS.json
iindex 67c5614..a99d7f8 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -5,11 +5,11 @@
"runtime": "node 22, express 4, ws; PostgreSQL 18 via openvibe-sdk/db (pg, or embedded PGlite in tests); Valkey optional; no build step",
"port": 4630,
"domain": "openvibe.bot (www -> apex; /device and /control WebSockets; /install)",
-- "contracts": "openvibe-contracts v0.188.2",
++ "contracts": "openvibe-contracts v0.192.0",
"sdk": "openvibe-sdk v0.46.0",
"shared": "openvibe-shared v4.2.1",
"packages": [
-- "openvibe-contracts v0.188.2",
++ "openvibe-contracts v0.192.0",
"openvibe-sdk v0.46.0",
"openvibe-shared v4.2.1"
],
ddiff --git a/package-lock.json b/package-lock.json
iindex d34405f..3ddf486 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -13,7 +13,7 @@
"dotenv": "^16.4.7",
"express": "^4.21.2",
"iovalkey": "^0.4.0",
-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.188.2",
++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.192.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.46.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.2.1",
"pg": "^8.23.0",
@@@ -845,9 +845,9 @@
}
},
"node_modules/openvibe-contracts": {
-- "version": "0.188.2",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.188.2",
-- "integrity": "sha512-E64gQI7roKudmmJFnenyh1BjViJyI0j0MoVT4o35/jUD4rpzMkElwEh/fGbsPpnstdDFIcJR6gEcScbL0ZQhbg==",
++ "version": "0.192.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.192.0",
++ "integrity": "sha512-cNHARCKL9EqhXVsHTNT79JCSLwWimER8MxRH22Ko11h+ITxOPONmzQjPnLMScIEStQfGiFlbpVrbCXvSE9/GVw==",
"license": "AGPL-3.0-only",
"dependencies": {
"ajv": "^8.17.1",
ddiff --git a/package.json b/package.json
iindex 0024cb8..272aa20 100644
---- a/package.json
++++ b/package.json
@@@ -25,7 +25,7 @@
"dotenv": "^16.4.7",
"express": "^4.21.2",
"iovalkey": "^0.4.0",
-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.188.2",
++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.192.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.46.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.2.1",
"pg": "^8.23.0",
ddiff --git a/server/domain/index.js b/server/domain/index.js
iindex 034a4ce..baa7835 100644
---- a/server/domain/index.js
++++ b/server/domain/index.js
@@@ -794,9 +794,12 @@ function createDomain({ db, config, outbox, link = null, nodes = null, openre =
const at = iso(now());
await db.tx(async (t) => {
if (online) await t.query('UPDATE devices SET last_seen = $2 WHERE id = $1', [device.id, at]);
++ // The owner rides along (contracts 0.192.0): OpenVibe.Quest credits "Bring a robot online" from it.
++ const owners = new Map(robotIds.length ? (await t.many('SELECT id, owner_subject FROM robots WHERE id = ANY($1::text[])', [robotIds])).map((r) => [r.id, r.owner_subject]) : []);
for (const robotId of robotIds) {
++ const owner = owners.get(robotId);
await emit(t, online ? 'bot.robot.online' : 'bot.robot.offline', { type: 'robot', id: robotId },
-- { robot_id: robotId, device_id: device.id });
++ { robot_id: robotId, device_id: device.id, ...(/^usr_[0-9A-HJKMNP-TV-Z]{26}$/.test(String(owner || '')) ? { owner } : {}) });
}
});
}
ddiff --git a/test/device.test.js b/test/device.test.js
iindex 9a66805..957dc73 100644
---- a/test/device.test.js
++++ b/test/device.test.js
@@@ -73,6 +73,10 @@ const { boot, check, done } = require('./helpers/app');
await t.wait(50);
const rows = await t.outboxRows('bot.robot.offline');
assert.ok(rows.some((e) => e.payload.robot_id === robot.id), 'bot.robot.offline for the robot');
++ // Both events name the robot's owner (contracts 0.192.0), so Quest can credit "Bring a robot online".
++ assert.ok(rows.some((e) => e.payload.robot_id === robot.id && e.payload.owner === alex.subject), 'the owner on bot.robot.offline');
++ const online = await t.outboxRows('bot.robot.online');
++ assert.ok(online.some((e) => e.payload.robot_id === robot.id && e.payload.owner === alex.subject), 'the owner on bot.robot.online');
dev.close();
});