react-ssml-dom
Advanced tools
Comparing version 1.0.4 to 1.0.5
{ | ||
"name": "react-ssml-dom", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "A proof of concept react host implementation for ssml strings", | ||
@@ -24,2 +24,3 @@ "main": "./dist/index.js", | ||
"dependencies": { | ||
"prop-types": "^15.7.2", | ||
"react-reconciler": "^0.25.1" | ||
@@ -50,3 +51,2 @@ }, | ||
"prettier": "^1.19.1", | ||
"prop-types": "^15.7.2", | ||
"react": "^16.13.1", | ||
@@ -53,0 +53,0 @@ "rollup": "^2.26.5", |
235
README.md
@@ -8,3 +8,3 @@ <h1 align="center"> | ||
## ❓What is this? | ||
## | ||
@@ -15,2 +15,11 @@ Utilize the full power of React to develop voice UIs. ReactSSML provides a simple custom React renderer that let's you use React and JSX to create [SSML](https://www.w3.org/TR/speech-synthesis11/) output. | ||
## Contents | ||
- [Motivation](##-motivation) | ||
- [Installation Guide](##-installing-reactssml) | ||
- [Demo](##-try-out-the-demo) | ||
- [Documentation](##-documentation) | ||
- [Architecture](##-how-it-works) | ||
- [Example Apps](##-example-apps-using-reactssml) | ||
## 🌟 Motivation | ||
@@ -96,3 +105,3 @@ | ||
## 🌟 Next steps | ||
## 🌟 Try out the demo | ||
@@ -126,6 +135,10 @@ ***Clone this repo and play around with the demo application*** | ||
Use Postman or a tool of your choice to hit the fulfillment endpoint. | ||
Use Postman or a tool of your choice to hit the fulfillment endpoint. | ||
You can find a collection of valid requests in `index.http` | ||
If you are using VS Code, checkout [this plugin](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) to run curl commands with VS Code. | ||
```bash | ||
curl -X POST http://localhost:8888 | ||
curl -X POST http://localhost:8888/hello-world | ||
``` | ||
@@ -137,6 +150,214 @@ | ||
{ | ||
"reply": "<speak> <audio src=\"https://s3-bucket.com/mock-song.ogg\"> Oh, I am sorry, this file seems not to work, please try another song</audio> </speak>" | ||
"ssml": "<speak version=\"1.1\" xml:lang=\"en-US\" xmlns=\"http://www.w3.org/2001/10/synthesis\">Hello World!</speak>" | ||
} | ||
``` | ||
## 📖 Documentation | ||
### Content | ||
- ReactSSML | ||
- ***ssml-dom*** | ||
- Document | ||
- XMLDeclaration | ||
- Root | ||
- Node | ||
- TextNoode | ||
- ***conversation*** | ||
- Conversation | ||
- ***builders*** | ||
- withRaw | ||
- withAoG | ||
### ReactSSML | ||
ReactSSML works like ReactDOM. It provides one function `render` that takes your react App component and your `ssml-dom` node that your app should render in. Typically, that would be your root node. | ||
```javascript | ||
import ReactSMML from 'react-ssml-dom'; | ||
ReactSMML.render(<App />, root); | ||
``` | ||
### ssml-dom: Document | ||
Document works similar to the `document` global variable. Initialize a new Document with the following constructor parameters: | ||
***constructor*** | ||
| param | default | description | | ||
|----------------|-------------|-----------------------------------------------------------------------| | ||
| locale | 'en-locale' | document locale | | ||
| addDefaultRoot | true | if true, it will add a default Root node of type as the document body | | ||
| includeProlog | false | if true, it will add a default XMLDeclaration to the document | | ||
```javascript | ||
import { Document } from 'react-ssml-dom'; | ||
// those are the default parameters | ||
const doc = new Document('en-US', true, false); | ||
``` | ||
***toString*** | ||
Call the `toString` to create a string representation of the SSML document. | ||
Note: You can use the `documentType` propType if you are using `prop-types` in your project. | ||
### smml-dom: XMLDeclaration | ||
By definition [SSML](https://www.w3.org/TR/speech-synthesis11/) documents start with a XML declaration. Some speech synthesizer will require a valid declaration to parse the SSML. | ||
- Add a default XMLDeclaration to the Document by setting the `includeProlog` parameter to true | ||
- You can always alter the XMLDeclaration like so: | ||
```javascript | ||
import { Document } from 'react-ssml-dom'; | ||
const doc = new Document('en-US', true, false); | ||
doc.includeProlog = true; | ||
doc.xmlDeclaration.version = '1.1'; // '1.0' is the default | ||
``` | ||
### smml-dom: Root | ||
Root extends Node and defaults its type to 'speak'. You can create your own Root node and set it to `doc.body`. Initialize a new Root node with the following constructor parameters: | ||
***constructor*** | ||
| param | default | description | | ||
|----------------|-------------|-----------------------------------------------------------------------| | ||
| locale | 'en-locale' | document locale | | ||
| addDefaults | true | if true, it will add default attributes to the node | | ||
The default attributes: | ||
``` | ||
version="1.1" | ||
xml:lang="en-US" | ||
xmlns="http://www.w3.org/2001/10/synthesis" | ||
``` | ||
```javascript | ||
import { Document, Root } from 'react-ssml-dom'; | ||
const doc = new Document('en-US', false, false); | ||
// those are the default parameters | ||
doc.body = new Root('en-US', false); | ||
``` | ||
### smml-dom: Node | ||
Similar to a DOM node of the browser DOM implementation. It has a `type` and a list of `attributes` and can render to a string by calling `toString`. | ||
***type*** | ||
All possible SSML tags are allowed types. | ||
***toString*** | ||
### smml-dom: TextNode | ||
Similar to a DOM textNode of the browser DOM implementation. It has a `text` field and can render to a string by calling `toString`. | ||
***toString*** | ||
### conversation: Conversation (optional) | ||
Similar to the `window` global variable in the browser environment. | ||
You don't need to work with the conversation model, it is entierly optional and might be abstracted into it's own package in the future. `Conversation` provides a abstraction layer for a voice dialog and could be a way for you to access the request (intent, parameters, ...) and the response (endConversation, reply, contexts, ...) of the ongoing conversation within your React component. | ||
The idea is that all requests and responses can be abstracetd into the conversation model. Most likely you will use `ReactSSML` to create voice apps for Amazon Alexa, or Google Assistant or any other popular nlu provider or voice assistant. `Conversation` aims to provide a abstraction layer to and from any target environment. | ||
This is how it works: | ||
```javascript | ||
import { Conversation } from 'react-ssm-dom'; | ||
// parse request body (e.g. express.js request body) to conversation model | ||
const conv = new Conversation(req.body); | ||
// access common parameters of any voice environment | ||
const intent = conv.intent; | ||
conv.response.endConversation = false; | ||
// and parse the final user response back to the target environment model | ||
const payload = conv.buildPayload(ssmlReply); | ||
``` | ||
Note: You can use `conversationType` propType if you are using the conversation object within your React app and want to utilize `prop-types`. | ||
***Conversation Model*** | ||
| fields | default | type | description | | ||
|-----------------|----------------------------------------------------|--------|-------------------------------------------------------------------| | ||
| locale | 'en-locale' | string | the locale of the conversation | | ||
| intent | undefined | string | the current intent of the user | | ||
| target | undefined | string | the target env, e.g. default, aog, ... | | ||
| parameters | {} | object | list of parameters / slots the user filled | | ||
| originalRequest | undefined | object | the actual request object | | ||
| user | undefined | object | the user object | | ||
| queryText | undefined | string | the actual query of the user | | ||
| sessionId | undefined | string | the sessionId unique across all conversations | | ||
| response | { reply: '', contexts: [], endConversation: true } | object | the response object that will be filled and sent back to the user | | ||
### conversation: builders (withAoG, withRaw) | ||
You can create your own mappers to build a conversation model from your request and | ||
build a payload back from that conversation once your conversation is ready. | ||
This package comes with a set of builders already | ||
- withRaw | ||
- withAoG | ||
### conversation: builder withRaw | ||
The default builder is registered by default. If no other builder `canBuildConversation` the default builder will try to build the conversation. | ||
### conversation: builder withAoG | ||
A builder to parse the dialogflow actions on google request to the conversation model and the conversation back to a dialogflow response. | ||
***register a builder*** | ||
You can register that builder or any costumer builder like follows: | ||
```javascript | ||
import { Conversation, withAoG } from 'react-smml-dom' | ||
// similar to how express use function works, you can add as many builders as you want | ||
Conversation.useBuilder(withAoG); | ||
``` | ||
***useBuilder*** | ||
`useBuilder` takes two arguments. | ||
| param | default | description | | ||
|----------------|-------------|-----------------------------------------------------------------------| | ||
| builder | required! | the builder | | ||
| map | {} | a map that can be used to help the builder parse to the conv model | | ||
A map for the `withAoG` builder could look like follows: | ||
```javascript | ||
const aogMap = { | ||
parameters: { | ||
'geo-country': value => (Array.isArray(value) ? 'countries' : 'country'), | ||
}, | ||
}; | ||
``` | ||
This map will take any AoG parameter with the key `geo-country` and parse it depending on it's value as a parameter with the key name `countries` or `country`. | ||
### Build your own builder | ||
a builder has to offer the following functions and fields: | ||
| fields | type | expected return value | parameters | description | | ||
|----------------------|----------|-----------------------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||
| target | string | - | - | the name of the target environment. | | ||
| canBuildConversation | function | boolean | request | should return true if the builder can handle the given request and false if not, the first builder that return true will be picked to build the conversation. | | ||
| buildConversation | function | object | request, map | should return an object with all the fields that the request can fill for the conversation. | | ||
| buildPayload | function | object | conversation | should return the payload that can be sent to the user. | | ||
## 🔍 How it works | ||
@@ -146,3 +367,3 @@ | ||
See: `./src/ReactSSML.js` which replaces `react-dom` | ||
See: `./src/ReactSSML.js` which works like `react-dom`. | ||
@@ -153,2 +374,4 @@ On top of that this project implements a (proof-of-concept) version of the web's DOM for SSML. | ||
The `./src/conversation/*` folder implements a conversation model that abstracts away the target environment. You can think of the `conversation` object to something similar as the `window` on the web. On top of that it enables abstracting away the target environment. The vision is to use the same code base (React App) for Actions on Google, Alexa Skills and all possible target environments and translate the different requests into the `conversation` model. | ||
The demo folder contains a demo React App. The demo express server runes via `.index.js` | ||
@@ -155,0 +378,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
2163748
29
16189
378
2
17
+ Addedprop-types@^15.7.2