UNPKG

adam-sdk

Version:

A JavaScript SDK for integrating A.D.A.M. 3D avatars into web applications.

255 lines (188 loc) 9.64 kB
# adam-sdk A JavaScript SDK for integrating A.D.A.M. 3D avatars into your web applications. ## Installation ```bash npm install adam-sdk ``` ## Quick Start ```javascript import { AvatarSDK } from 'adam-sdk'; // Get the iframe element from your page const avatarIframe = document.getElementById('avatar-iframe'); // Instantiate the SDK const sdk = new AvatarSDK(avatarIframe); // Listen for the 'ready' event, which fires after a successful and secure connection sdk.on('ready', () => { console.log('SDK is ready! The avatar can now receive commands.'); sdk.speak('Hello from the packaged SDK!'); }); // Always handle potential connection errors sdk.connect().catch(error => { console.error("Failed to connect to avatar:", error); }); ``` ## Important Changes All SDK commands wait for handshake completion before sending messages to the avatar iframe. This ensures consistent behavior and reliable communication between the parent application and the avatar. All commands, including `speak`, `playAnimation`, and `setExpression`, follow the same pattern of verifying the connection before sending messages. ## Security Architecture Protecting user data and sensitive API keys is the most critical aspect of the A.D.A.M. platform. Our security model is designed to be robust and transparent, ensuring that your keys are never exposed to the client-side. The responsibility for security is intentionally separated between this SDK and the A.D.A.M. iframe application. * **The SDK (`adam-sdk`):** Acts as a well-behaved **messenger**. Its only job is to send commands and listen for events. It has no access to your configuration or API keys. * **The A.D.A.M. Iframe (`adam-speaks.com`):** Acts as the **security gatekeeper**. It is solely responsible for verifying the identity of the website it is embedded on *before* loading any sensitive data. ### The Secure Handshake Process When you call `sdk.connect()`, the following secure handshake takes place: 1. **SDK Sends Handshake Request:** The SDK sends a non-sensitive `CHECK_READY_STATUS` message to the iframe. 2. **Iframe Receives Request:** The iframe receives the message and inspects the `event.origin` property, which is a browser-verified value indicating the domain of your website. 3. **Origin Verification:** The iframe's internal `IframeSecurityService` sends the `origin` to a secure backend Cloud Function. This function retrieves the **Trusted Origins** list associated with your avatar's configuration from Firestore. 4. **The Critical Check:** The backend function compares the calling `origin` against your list of trusted domains. * **If it matches:** The function signals success to the iframe. * **If it does not match:** The process is immediately halted. The iframe remains silent and does not respond to the SDK. 5. **Secure Config Loading:** Only after a successful origin check does the `IframeSecurityService` call a second, separate Cloud Function to fetch the sensitive configuration, including your API keys. 6. **Connection Complete:** The iframe, now fully configured, sends the `AVATAR_READY` message back to the SDK. The `ready` event is fired, and your application can begin sending commands. ### Firestore Security Rules To complete this security model, our Firestore database is locked down with the following rule, making it impossible for any client-side code to read or write to the avatar configuration collection. All data access is brokered through secure, server-side Cloud Functions. ``` // firestore.rules rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // Disallow ALL client-side reads/writes to the avatars collection. match /avatars/{avatarId} { allow read, write: if false; } } } ``` ### Troubleshooting Connection Timeouts **If the `sdk.connect()` promise rejects with a timeout error, it is a direct result of the security model working as intended.** This error means that the domain of the website where you are running the SDK has **not** been added to the **"Trusted Origins"** list in your A.D.A.M. admin console. To fix this, simply add the required domain (e.g., `https://www.your-production-site.com` or `http://localhost:3000` for development) to the list. ## Common Message Contract The SDK and example templates communicate with the avatar iframe using `window.postMessage`. Messages are simple JSON objects with a `type` and an optional `payload`. Security note: Always set the `targetOrigin` to your trusted iframe origin (e.g., `https://your-avatar-host.example`) instead of `*` in production. ### Outgoing Commands (parent → iframe) - `speak` ```json { "type": "speak", "requestId": "optional-uuid", "payload": { "text": "Hello world", "animation": { "name": "wave" }, "expression": { "name": "smile", "intensity": 0.8 }, "voice": { "id": "en-US-JennyNeural" } } } ``` - `animation` ```json { "type": "animation", "payload": { "name": "wave" }, "requestId": "optional-uuid" } ``` - `expression` ```json { "type": "expression", "payload": { "name": "smile", "intensity": 0.8 }, "requestId": "optional-uuid" } ``` Fields: - `type`: Command name. - `payload`: Command parameters (`text` is required; `animation`, `expression`, and `voice` are optional). - `requestId` (optional): Provide to correlate command responses. ### Incoming Events (iframe → parent) - Ready ```json { "type": "ready" } ``` - Speech start/end ```json { "type": "speech:start", "payload": { "utteranceId": "u1" } } { "type": "speech:end", "payload": { "utteranceId": "u1" } } ``` - Command success/error ```json { "type": "command:success", "payload": { "requestId": "optional-uuid", "result": { } } } { "type": "command:error", "payload": { "requestId": "optional-uuid", "message": "details" } } ``` Event notes: - Always validate `event.origin` against your trusted domain list before acting on events. - If you use `requestId` on commands, include it in success/error payloads for correlation. ## Starter Templates (React, Angular, Vue) We include minimal, no-bloat starter templates under `adam-sdk/examples/` that are ready to embed the avatar via an iframe and communicate using `window.postMessage`. Each template exposes simple placeholder methods and event handling: - `speak(text)` - `animation(name)` - `expression(name, intensity)` - `onEvent(handler)` for iframe-emitted events like `ready`, `speech:start`, `speech:end`, etc. Important: In the example bridges, the postMessage `origin` is `*` for convenience. For production, replace `*` with your real iframe origin (e.g., `https://your-avatar-host.example`). ### React (Vite) Directory: `adam-sdk/examples/react/` 1. Install and run: ```bash cd adam-sdk/examples/react npm install npm run dev ``` 2. Edit `src/avatarBridge.js` to lock the `origin` and update the `<iframe src>` in `src/App.jsx` to your hosted avatar URL. ### Angular (Standalone + Vite) Directory: `adam-sdk/examples/angular/` 1. Install and run: ```bash cd adam-sdk/examples/angular npm install npm run start ``` 2. Edit `src/app/avatar-bridge.ts` to lock the `origin` and update the `<iframe>` `src` in `src/app/app.component.html`. 3. Template is separate from the class, following the project guideline. ### Vue 3 (Vite) Directory: `adam-sdk/examples/vue/` 1. Install and run: ```bash cd adam-sdk/examples/vue npm install npm run dev ``` 2. Edit `src/avatarBridge.js` to lock the `origin` and update the `<iframe src>` in `src/App.vue`. All templates are intentionally small, with just enough structure to demonstrate: - Embedding the iframe and sending commands - Receiving events and basic logging - Where to securely configure origins and endpoints ## Additional Docs - Message Contract: `docs/message-contract.html` - Starter Templates: `docs/examples-starters.html` ## API Documentation To view the full, detailed API documentation: 1. **Generate the docs:** ```bash npm run docs ``` 2. **Serve the docs locally:** ```bash npm run docs:serve ``` This will start a local web server and provide a URL to view the documentation in your browser. ## Events Listen for events using the `sdk.on()` method: - `ready`: Fired when the SDK has successfully and securely connected to the avatar iframe. - `speech:start`: Fired when the avatar starts speaking. - `speech:end`: Fired when the avatar finishes speaking. - `command:success`: Fired when a command is successfully executed. - `command:error`: Fired when a command fails. ## Release & Publish We include the built API docs (`docs/`) in the npm package alongside the compiled library (`dist/`). The publish flow automatically builds both via `prepublishOnly`. * __Version__: set in `package.json` (current: `1.0.3`). For future releases: `npm version patch|minor|major -m "chore(release): %s"`. * __Build__: `npm run build` (Vite) * __Docs__: `npm run docs` (TypeDoc → `docs/`) * __Auto step on publish__: `prepublishOnly` runs `build` and `docs` automatically. ### Steps to publish Run from `adam-sdk/adam-sdk/`: ```bash # 1) Verify npm login and access npm whoami # 2) Install clean deps npm ci # 3) (Optional) Test/build/docs locally npm test || true npm run build npm run docs # 4) Publish (triggers prepublishOnly: build + docs) npm publish --access public ``` Notes: * If your npm account uses 2FA for publishing, be ready to enter your OTP. * The published tarball includes `dist/` and `docs/` (see the `files` field).