Add Introduction to the Status Chat API guide

This commit is contained in:
Smouki 2017-04-24 16:27:52 +03:00
parent 76730b655d
commit 7b6faa1e69
9 changed files with 319 additions and 0 deletions

View File

@ -0,0 +1,319 @@
## Giving Your DApp Commands on Status: Introduction to the Status Chat API
*(warning: the Chat API is still a work in progress. Come ask in the Slack if you hit bumps!)*
## Introduction
One of the first things youll notice when you start using Status is that you can send and receive funds just by issuing simple commands.
![Easily send or request eth](../img/introduction-to-status-chat-api_01.png)
*Easily send or request eth*
This is no accident! Today, more people use smartphones than computers, and when people are on their smartphones, they spend a lot of their time in messaging applications. Smartphone users enjoy using messaging to control applications, because its simple and convenient.
Status allows users to interact with a wide array of DApps using the same intuitive chat interface. In the near future, Status users will be able to have group chats where most of the participants are DApp chatbots. All DApp developers will benefit from this synergy, because a common chat interface for multiple DApps makes using your DApp more convenient, and effectively makes your DApp more powerful.
In this guide, well explore how you can use the Status Chat API while developing your DApp on Status to create custom commands for your users. As a result of developing on Status, youll have a DApp that your users can access on MetaMask, Mist, and Status — and that invites mobile users with native mobile commands. With little extra developer time invested, youll gain a mobile app.
If you havent already, you can [join our Slack](https://slack.status.im), and download the [Android binary](https://test.status.im). Wed love to chat with you as you get started.
## Delivering Your Commands to Status
The majority of this tutorial covers the Status Chat API. First, though, lets touch on how youll make your commands available after youve written them using the API.
To add a command to your DApp in Status, youll write your commands in JavaScript, put them in a file named `commands.js`, and make the file publicly available at `https://yourAwesomeDApp.com/commands.js`. When your DApp goes live and is added to Status, Status will take the file from that URL and create your commands.
If you decide to use the Truffle or Embark DApp development frameworks, they have standard locations which will put your commands.js file at the right URL. For Truffle, thats the folder `public`, and for Embark, thats the folder dist. So in Truffle, youll have `public/commands.js`, and in Embark, youll have `dist/commands.js`.
![](../img/introduction-to-status-chat-api_02.png)
![commands.js locations on a Mac: Embark on the left, Truffle on the right](../img/introduction-to-status-chat-api_03.png)
*commands.js locations on a Mac: Embark on the left, Truffle on the right*
The file itself will be the same whether you develop with Truffle, with Embark, or a different framework or no framework. You just need to place the file at the right location to make it available during development and after your DApp goes live.
During development, this location will be part of your local computer file system. If youre developing with `truffle-box-status` or the `embark-status` plugin, youll be able to see your DApp on Status at `localhost:8080/commands.js` (for example), and Status will create your commands the same way. After youve finished development, youll need to host your DApp in the traditional way or in a decentralized way such as Swarm to make the whole thing publicly available.
Your users can see possible commands in one of two ways. If theyre chatting directly with your DApp, they can type a forward slash, “/”, and that will bring up a list of suggestions. Or they can click the bullet point icon to the left of the chat input box. If you havent defined any commands, clicking the bullet point list icon will just fill in the command `/browse`, which is a globally available Status command.
Your users will be able to access your DApps commands in a group chat as well, as long as your DApp has been added to the chat. In that case, your commands will show as `/yourAwesomeDApp/your-command`.
## The Status Commands
You can take advantage of three methods: `status.command()`, `status.response()`, and `status.on()`. These methods (along with a few methods used only by Status) are defined in the [Status GitHub repo](https://github.com/status-im/status-react/blob/develop/resources/status.js) at `resources/status.js`, in the `status` var.
Lets walk through each, and the parameters each command takes. Well also build a toy `hello` example as we go. For easy reference, youll find the code for that example, as well as a summary of the methods and parameters, at the end of this article.
### status.command()
Well start with the the most important method available to you, the one that youll use for your DApps unique commands. Youre allowed to pass up to 12 parameters into `status.command()`.
1. `name`. This is what your users will type in following a forward slash to invoke the command. For instance, if you wrote `name: “hello”`, your user might invoke `/hello`.
2. `title`. Remember that when your user starts typing a command, a list of suggestions appears. In the list of suggestions, the title appears on the left, above the description.
3. `description`. Similarly, in the list of suggestions, the description appears on the left, below the title.
4. `color`. This parameter defines the background color of the name of your command as it appears in the list of suggestions. Give commands different colors to help your users easily distinguish commands, and to harmonize with your DApps brand and color scheme.
You can see that these first four parameters control how your command will appear to your users in the list of suggestions. In addition, the `name` parameter gives your users a way to invoke your command. Heres an example of the first four parameters defining a `/hello` command:
status.command({
name: “hello”,
title: “HelloBot”,
description: “Helps you say hello”,
color: “#7099e6”,
});
5. `preview`. This option defines what your user will see as a result of *their* action, before any other response. The `preview` parameter takes a function, which should return a `status.component`.
![](../img/introduction-to-status-chat-api_04.png)
For instance, if you use the command `/location`, from the Mailman DApp on Status, youll see a preview of a geographic location. This command is intended to send the users location to someone else, and so it doesnt depend on the recipients response.
To continue with our `hello` example, you could add to the parameters youve already written above:
preview: function () {
return status.components.text({}, “youre saying hello”);
},
Well discuss the `status.components` — there are only seven! — in the next section, after covering the other parameters to `status.command`.
6. `short-preview`. While `preview` controls how your command appears within your DApps chat, the `short-preview` parameter controls how your commands get shown in the list of chats, before your users tap on your chat.
![](../img/introduction-to-status-chat-api_05.png)
7. `icon`. Suppose your user is interacting with your command. Each command can have a custom icon to appear in the command preview. For instance, if you request ETH from someone, a green two-way arrow appears in the preview. Or you can look again at the result of the `/location` command in the picture above. Next to `/location`, and above the map, theres a small pin icon. Both are examples of command icons, another way to improve your design for your users.
8. params. This important option is where you define possible inputs to your command. It requires an array holding an object, with possible parameters `name`, `placeholder`, `suggestions`, and one of the `status.types`.
Heres a simple example, which you might add to your `/hello` command:
params: [{
name: “hello”,
type: status.types.TEXT
placeholder: "Why not say hello"
}],
These `params` are available in any parameter, including in `params` itself. For instance, if your users sends `/hello whatsup`, the input `whatsup` will be available in your command under `params.hello`.
Naturally, the `type` dictates what sort of data your users may input. The available Status types are: `status.types.TEXT`, `status.types.NUMBER`, `status.types.PHONE`, and `status.types.PASSWORD`.
![Notice the placeholder “Type your password”](../img/introduction-to-status-chat-api_06.png)
*Notice the placeholder “Type your password”*
The `placeholder` parameter here only applies if your users havent put any input into the command, not even the name of the command. You can use it to include helpful guidance where necessary. This parameter will probably prove useful if you end up using `status.response()`, one of the other methods available to you, which well cover in another section.
![After you enter /faucet, two suggestions pop up.](../img/introduction-to-status-chat-api_07.png)
*After you enter /faucet, two suggestions pop up.*
As another parameter inside `params`, you can also include `suggestions` for your users input. This should return a component to be rendered.
For instance, if you are using the Console DApp and you select the `/faucet` command, youll see two suggestions to choose from.
Lets add this idea to our `hello` example:
params: [{
name: “hello”,
type: status.types.TEXT
suggestions: helloSuggestions
}],
Thats simple, but whats `helloSuggestions`? Lets make a function, which will return a `scrollView` that will hold two suggestions: “Hello”, and “Goodbye”. Dont get intimidated by the length, theres actually not much to it.
*// Three little helpers - don't worry about them, they're just for
// style.*
function suggestionsContainerStyle(suggestionsCount) {
return {
marginVertical: 1,
marginHorizontal: 0,
keyboardShouldPersistTaps: true,
height: Math.min(150, (56 * suggestionsCount)),
backgroundColor: "white",
borderRadius: 5,
flexGrow: 1
};
}
var suggestionSubContainerStyle = {
height: 56,
borderBottomWidth: 1,
borderBottomColor: "#0000001f"
};
var valueStyle = {
marginTop: 9,
fontSize: 14,
fontFamily: "font",
color: "#000000de"
};
*// The main star of our show! It will return two touchable buttons.*
function helloSuggestions() {
var suggestions = ["Hello", "Goodbye"].map(function(entry) {
return status.components.touchable(
{onPress: [status.events.SET_VALUE, entry]},
status.components.view(
suggestionContainerStyle,
[status.components.view(
suggestionSubContainerStyle,
[
status.components.text(
{style: valueStyle},
entry
)
]
)]
)
);
});
*// Let's wrap those two touchable buttons in a scrollView*
var view = status.components.scrollView(
suggestionsContainerStyle(2),
suggestions
);
*// Give back the whole thing inside an object.*
return {markup: view};
}
The main point of this example is that your `suggestions` parameter should accept users input, and then return a component to be rendered.
9. `suggestionsTrigger`. Now that weve covered `params` and the possibility of `suggestions`, its easy to see that `suggestionsTrigger` will take a string corresponding to an event which triggers showing suggestions. If you dont include this parameter, the default is `"on-change"`, so your suggestions will show when your users select the command.
10. `fullscreen`. If your command has suggestions, this param controls whether that list of suggestions expands to fill the entire screen. If your command has a lot of suggestions, you might want set `fullscreen` to true, so that your users dont have to pull the list upwards. On the other hand, if your command has only a few suggestions and you set `fullscreen` to true, your users will have to pull the list downwards to keep it from hiding the screen. Choose whichever will be most convenient to your users, considering your commands suggestions.
![/sends validator function says “la la la” is not a valid amount of ETH!](../img/introduction-to-status-chat-api_08.png)
*/sends validator function says “la la la” is not a valid amount of ETH!*
11. `validator`. This parameter allows you to check your users input before sending off the command. It takes a function, which should return an error if the input is invalid.
You can easily see an example if you try to send an amount of ETH thats not a number! To continue with our `/hello` example, you might write something like:
validator: function(params) {
if (!params.hello) {
return status.components.text({}, “Say hello”);
}
}
This will raise an error if your user doesnt input a string. Notice that you should return your message inside one of the `status.components`.
12. `handler`. Of course, you probably want the command to do something when your users call it! The `handler` parameter takes a function to accomplish this. For instance, suppose your user inputs `/hello howdy`. “Howdy” is a valid string, and will pass the `hello` validator. From there, your `handler` could take over to send this greeting to another user:
handler: web3.shh.post(params.hello),
If you dont provide a `handler`, your user will issue the command and then see the `preview`, but nothing else will happen.
### The Status Components
There arent many of these components, and youll feel very comfortable with them if youre at all familiar with React. The [`scrollView`](https://facebook.github.io/react-native/docs/scrollview.html), [`webView`](https://facebook.github.io/react-native/docs/webview.html), [`text`](https://facebook.github.io/react-native/docs/text.html), [`image`](https://facebook.github.io/react-native/docs/image.html), [`view`](https://facebook.github.io/react-native/docs/view.html), and [`touchable`](https://facebook.github.io/react-native/docs/touchablehighlight.html) take standard React props (each of those underlined words is linked). `validationMessage` is a custom Status component that just takes two strings, and will return them wrapped in text components inside a `view`. Heres a list, taken straight from the Status code:
components: {
view: view,
text: text,
image: image,
touchable: touchable,
scrollView: scrollView,
webView: webView,
validationMessage: validationMessage
}
### status.response()
Now that youve covered all the parameters for `status.command()`, you can easily understand `status.response()`. This method takes the same parameters that `status.command()` does. The difference is that with this method you can actively ask a user to issue a command.
For example, the Status DApp Wallet allows you to `/request` money. In that case, the person youre requesting money from will see the result of `status.response(send)` — theyll be asked to give a command, `/send`, in response to your `/request` command.
The Wallet example illustrates that as a DApp developer, you may wish to use `status.command()` and `status.response()` together to create dialogues of commands. You could also use `status.response()` by itself to prompt your users to enter necessary information as part of the onboarding process for your DApp.
Because `status.command()` and `status.response()` take the same parameters, you can sometimes use nearly the same code for both of them. You simply have to consider when you want to ask a user to issue a command, and when you want to just make the command available. Most of the time, youll use `status.command()`.
To return to our `hello` example, if we used all the same code inside our method but used `status.response()`, a user would be asked to respond to another users greeting. Hello back!
### status.on()
The method `status.on()` allows your DApp to respond to events. This method requires an event name as a string, and a callback function. For instance, you might define:
status.on(“init”, function(params, context) {
status.sendMessage(“Hello, man!”);
});
With the `"init"` option, your DApp will trigger `status.sendMessage()` when the Status app loads your DApp — your DApp will greet your users even before they have clicked on it. Other options include `“text-change”` and `“message”`.
## Thats All For Now, Folks
Please join other DApp developers in [our Slack](https://slack.status.im) in the #dapp-chat or #dev-status channels.
Finally, heres the TL;DR of what weve covered.
### status.command()
1. `name`:string
1. `title`:string
1. `description`:string
1. `color`:string, containing valid hex color.
1. `preview`:function
1. `icon`:string
1. `params`:array holding object with parameters `name`, `type`, `placeholder`, and `suggestions`.
1. `suggestionsTrigger`
1. `fullscreen`:boolean. If not included, default is `false`.
1. `validator`:function
1. `handler`:function
1. `short-preview`
Example `commands.js` file to create `hello` command:
status.command({
name: “hello”,
title: “HelloBot”,
description: “Helps you say hello”,
color: “#7099e6”,
preview: function () {
return status.components.text({}, “youre saying hello”);
},
params: [{
name: “hello”,
type: status.types.TEXT
suggestions: helloSuggestions
}],
suggestionsTrigger: 'on-change',
fullscreen: false,
validator: function(params) {
if (!params.hello) {
return status.components.text({}, “Say hello”);
}
},
handler: web3.post.shh (params.hello)
});
### Status Components
Standard React Native components, except for `validationMessage`, which just wraps standard components.
components: {
view: view,
text: text,
image: image,
touchable: touchable,
scrollView: scrollView,
webView: webView,
validationMessage: validationMessage
}
### status.response()
Takes all the same parameters as `status.command()`. Use `status.response()` to ask a user to issue a command, whether in response to another command, or as part of your DApp setup.
### status.on()
Requires an event name as a string, and a callback function.

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB