bots guides: Refactor layout.

This flattens the layout, shifts passages and unitizes headings to
use gerunds for the running and writing bots guides.
This commit is contained in:
derAnfaenger 2017-10-04 18:01:31 +02:00 committed by Tim Abbott
parent b6106ca7ac
commit 543500bab5
2 changed files with 90 additions and 102 deletions

View File

@ -6,23 +6,16 @@ Zulip's features can be extended by the means of bots and integrations.
If this is what you are looking for, please check out the [integrations guide]( If this is what you are looking for, please check out the [integrations guide](
http://zulip.readthedocs.io/en/latest/integration-guide.html?highlight=integrations). http://zulip.readthedocs.io/en/latest/integration-guide.html?highlight=integrations).
* **Bots**, as a more general concept, intercept and react to messages. * **Bots**, as a more general concept, intercept and react to messages.
If this is what you are looking for, read on!
The purpose of this documentation is to provide you with information about Zulip's *This guide is about running bots. If you want to write a bot, check out our [guide for
bot system. writing bots](writing-bots-in-zulip.html).*
On this page you'll find: On this page you'll find:
* A step-by-step [tutorial](#how-to-run-a-bot) on how to run a bot. * A step-by-step [tutorial](#running-a-bot) on how to run a bot.
* A [guide](#zulip-botserver) on running a Zulip botserver.
* Common [problems](#common-problems) when developing/running bots and their solutions. * Common [problems](#common-problems) when developing/running bots and their solutions.
Contributions to this guide are very welcome, so if you run into any
issues following these instructions or come up with any tips or tools
that help with writing bots, please visit
[#integrations](https://chat.zulip.org/#narrow/stream/integrations) on the
[Zulip development community server](https://chat.zulip.org), open an
issue, or submit a pull request to share your ideas!
## Installing the `zulip_bots` package ## Installing the `zulip_bots` package
The `zulip_bots` package comes with all you need to run a bot. The `zulip_bots` package comes with all you need to run a bot.
@ -32,7 +25,7 @@ To install it, run `pip install zulip_bots`.
*Hint: Do you want to install the latest version? Check out [this]( *Hint: Do you want to install the latest version? Check out [this](
writing-bots-guide.html#installing-a-development-version-of-the-zulip-bots-package) guide.* writing-bots-guide.html#installing-a-development-version-of-the-zulip-bots-package) guide.*
## How to run a bot ## Running a bot
This guide will show you how to run a bot on a running Zulip This guide will show you how to run a bot on a running Zulip
server. It assumes you want to use one of the existing `zulip_bots/bots` server. It assumes you want to use one of the existing `zulip_bots/bots`

View File

@ -6,60 +6,19 @@ Zulip's features can be extended by the means of bots and integrations.
If this is what you are looking for, please check out the [integrations guide]( If this is what you are looking for, please check out the [integrations guide](
http://zulip.readthedocs.io/en/latest/integration-guide.html?highlight=integrations). http://zulip.readthedocs.io/en/latest/integration-guide.html?highlight=integrations).
* **Bots**, as a more general concept, intercept and react to messages. * **Bots**, as a more general concept, intercept and react to messages.
If this is what you are looking for, read on!
The purpose of this documentation is to provide you with information about Zulip's *This guide is about writing and testing bots. If you just want to run a bot, check out our [guide for
bot system. running bots](running-bots-in-zulip.html).*
On this page you'll find: On this page you'll find:
* A step-by-step [guide](#installing-a-development-version-of-the-zulip-bots-package) on how to set up
* A step-by-step [tutorial](#how-to-develop-a-bot) on how to develop a bot. a development environment for bots.
* A [guide](#writing-a-bot) on writing a bot.
* A [guide](#adding-a-bot-to-zulip) on adding a bot to Zulip.
* A [guide](#testing-a-bot-s-output) on testing a bot's output.
* A [documentation](#bot-api) of the bot API. * A [documentation](#bot-api) of the bot API.
* Common [problems](#common-problems) when developing/running bots and their solutions. * Common [problems](#common-problems) when developing/running bots and their solutions.
Contributions to this guide are very welcome, so if you run into any
issues following these instructions or come up with any tips or tools
that help with writing bots, please visit
[#integrations](https://chat.zulip.org/#narrow/stream/integrations) on the
[Zulip development community server](https://chat.zulip.org), open an
issue, or submit a pull request to share your ideas!
## The bots system
Zulip's bot system resides in the [python-zulip-api](
https://github.com/zulip/python-zulip-api) repository.
The structure of the bots ecosystem looks like the following:
```
zulip_bots
└───zulip_bots
├───bots
│ ├───bot1
│ └───bot2
│ │
│ ├───bot2.py
│ ├───bot2.conf
│ ├───doc.md
│ ├───test_bot2.py
│ ├───assets
│ │ │
│ │ └───pic.png
│ ├───fixtures
│ │ │
│ │ └───test1.json
│ └───libraries
│ │
│ └───lib1.py
   ├─── lib.py
   ├─── test_lib.py
   ├─── run.py
   └─── provision.py
```
Each subdirectory in `bots` contains a bot. When developing bots, try to use the structure outlined
above as an orientation.
## Installing a development version of the `zulip_bots` package ## Installing a development version of the `zulip_bots` package
1. `git clone https://github.com/zulip/python-zulip-api.git` - clone the [python-zulip-api]( 1. `git clone https://github.com/zulip/python-zulip-api.git` - clone the [python-zulip-api](
@ -76,27 +35,7 @@ above as an orientation.
*Hint: `./tools/provision` installs `zulip`, `zulip_bots`, and `zulip_botserver` in developer *Hint: `./tools/provision` installs `zulip`, `zulip_bots`, and `zulip_botserver` in developer
mode. This enables you to make changes to the code after the packages are installed.* mode. This enables you to make changes to the code after the packages are installed.*
### Testing a bot's output ## Writing a bot
If you just want to see how a bot reacts to a message, but don't want to set it up on a server,
we have a little tool to help you out: `zulip-bot-output`
* [Install all requirements](#installing-a-development-version-of-the-zulip-bots-package).
* Run `zulip-bot-output <bot-name> --message "<your-message>"` to test one of the bots in
[`zulip_bots/bots`](https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots)
* Example: `zulip-bot-output converter --message "12 meter yard"`
Response: `12.0 meter = 13.12336 yard`
* Run `zulip-bot-output <path/to/bot.py> --message "<your-message>"` to specify the bot's path yourself.
* Example: `zulip-bot-output zulip_bots/zulip_bots/bots/converter/converter.py --message "12 meter yard"`
Response: `12.0 meter = 13.12336 yard`
## How to develop a bot
The tutorial below explains the structure of a bot `<my-bot>.py`, The tutorial below explains the structure of a bot `<my-bot>.py`,
which is the only file you need to create for a new bot. You which is the only file you need to create for a new bot. You
@ -130,7 +69,63 @@ handler_class = MyBotHandler
* These functions are documented in the [next section](#bot-api). * These functions are documented in the [next section](#bot-api).
### Bot API ## Adding a bot to Zulip
Zulip's bot system resides in the [python-zulip-api](
https://github.com/zulip/python-zulip-api) repository.
The structure of the bots ecosystem looks like the following:
```
zulip_bots
└───zulip_bots
├───bots
│ ├───bot1
│ └───bot2
│ │
│ ├───bot2.py
│ ├───bot2.conf
│ ├───doc.md
│ ├───test_bot2.py
│ ├───assets
│ │ │
│ │ └───pic.png
│ ├───fixtures
│ │ │
│ │ └───test1.json
│ └───libraries
│ │
│ └───lib1.py
   ├─── lib.py
   ├─── test_lib.py
   ├─── run.py
   └─── provision.py
```
Each subdirectory in `bots` contains a bot. When writing bots, try to use the structure outlined
above as an orientation.
## Testing a bot's output
If you just want to see how a bot reacts to a message, but don't want to set it up on a server,
we have a little tool to help you out: `zulip-bot-output`
* [Install all requirements](#installing-a-development-version-of-the-zulip-bots-package).
* Run `zulip-bot-output <bot-name> --message "<your-message>"` to test one of the bots in
[`zulip_bots/bots`](https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots)
* Example: `zulip-bot-output converter --message "12 meter yard"`
Response: `12.0 meter = 13.12336 yard`
* Run `zulip-bot-output <path/to/bot.py> --message "<your-message>"` to specify the bot's path yourself.
* Example: `zulip-bot-output zulip_bots/zulip_bots/bots/converter/converter.py --message "12 meter yard"`
Response: `12.0 meter = 13.12336 yard`
## Bot API
This section documents functions available to the bot and the structure of the bot's config file. This section documents functions available to the bot and the structure of the bot's config file.
@ -146,21 +141,21 @@ With this API, you *cannot*
* intercept private messages (except for PMs with the bot as an * intercept private messages (except for PMs with the bot as an
explicit recipient). explicit recipient).
#### usage ### usage
*usage(self)* *usage(self)*
is called to retrieve information about the bot. is called to retrieve information about the bot.
###### Arguments #### Arguments
* self - the instance the method is called on. * self - the instance the method is called on.
##### Return values #### Return values
* A string describing the bot's functionality * A string describing the bot's functionality
##### Example implementation #### Example implementation
``` ```
def usage(self): def usage(self):
@ -173,13 +168,13 @@ def usage(self):
''' '''
``` ```
#### handle_message ### handle_message
*handle_message(self, message, bot_handler)* *handle_message(self, message, bot_handler)*
handles user message. handles user message.
##### Arguments #### Arguments
* self - the instance the method is called on. * self - the instance the method is called on.
@ -191,11 +186,11 @@ handles user message.
* use `state_handler.set_state(state)` to set a state (any object) * use `state_handler.set_state(state)` to set a state (any object)
* use `state_handler.get_state()` to retrieve the state set; returns a `NoneType` object if no state is set * use `state_handler.get_state()` to retrieve the state set; returns a `NoneType` object if no state is set
##### Return values #### Return values
None. None.
##### Example implementation #### Example implementation
``` ```
def handle_message(self, message, bot_handler, state_handler): def handle_message(self, message, bot_handler, state_handler):
@ -211,7 +206,7 @@ None.
content=new_content, content=new_content,
)) ))
``` ```
#### bot_handler.send_message ### bot_handler.send_message
*bot_handler.send_message(message)* *bot_handler.send_message(message)*
@ -234,7 +229,7 @@ bot_handler.send_message(dict(
)) ))
``` ```
#### bot_handler.send_reply ### bot_handler.send_reply
*bot_handler.send_reply(message, response)* *bot_handler.send_reply(message, response)*
@ -247,7 +242,7 @@ message was sent to, with the content of the reply being *response*.
(provided by `handle_message`). (provided by `handle_message`).
* response - Response message from the bot (string). * response - Response message from the bot (string).
#### bot_handler.update_message ### bot_handler.update_message
*bot_handler.update_message(message)* *bot_handler.update_message(message)*
@ -286,7 +281,7 @@ bot_handler.update_message(dict(
development environment hosted on your computer, use development environment hosted on your computer, use
`localhost:9991` `localhost:9991`
### Writing tests for bots ## Writing tests for bots
Bots, like most software that you want to work, should have unit tests. In this section, Bots, like most software that you want to work, should have unit tests. In this section,
we detail our framework for writing unit tests for bots. We require that bots in the main we detail our framework for writing unit tests for bots. We require that bots in the main
@ -298,7 +293,7 @@ refactor them.
mocking strategies, etc. you should check out our [mocking guide]( mocking strategies, etc. you should check out our [mocking guide](
testing-with-django.html#testing-with-mocks).* testing-with-django.html#testing-with-mocks).*
#### A simple example ### A simple example
Let's have a look at a simple test suite for the [`helloworld`]( Let's have a look at a simple test suite for the [`helloworld`](
https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots/helloworld) https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots/helloworld)
@ -325,7 +320,7 @@ case, we want to assert that the bot always replies with "beep boop". To do so,
several test messages ("", "foo", "Hi, my name is abc") and assert that the response is always several test messages ("", "foo", "Hi, my name is abc") and assert that the response is always
correct, which for this simple bot, means always sending a reply with the content "beep boop". correct, which for this simple bot, means always sending a reply with the content "beep boop".
#### Test your test ### Testing your test
Once you have written a test suite, you want to verify that everything works as expected. Once you have written a test suite, you want to verify that everything works as expected.
@ -337,14 +332,14 @@ Once you have written a test suite, you want to verify that everything works as
* To run all bot tests: `tools/test-bots` * To run all bot tests: `tools/test-bots`
#### Advanced testing ### Advanced testing
This section shows advanced testing techniques for more complicated bots that have This section shows advanced testing techniques for more complicated bots that have
configuration files or interact with third-party APIs. configuration files or interact with third-party APIs.
*The code for the bot testing library can be found [here]( *The code for the bot testing library can be found [here](
https://github.com/zulip/python-zulip-api/blob/master/zulip_bots/zulip_bots/test_lib.py).* https://github.com/zulip/python-zulip-api/blob/master/zulip_bots/zulip_bots/test_lib.py).*
##### Asserting individual messages #### Asserting individual messages
self.assert_bot_response( self.assert_bot_response(
message = {'content': 'foo'}, message = {'content': 'foo'},
@ -355,7 +350,7 @@ configuration files or interact with third-party APIs.
Use `assert_bot_response()` to test individual messages. Specify additional message Use `assert_bot_response()` to test individual messages. Specify additional message
settings, such as the stream or subject, in the `message` and `response` dicts. settings, such as the stream or subject, in the `message` and `response` dicts.
##### Testing bots with config files #### Testing bots with config files
Some bots, such as [Giphy]( Some bots, such as [Giphy](
https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots/giphy), https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots/giphy),
@ -369,7 +364,7 @@ a bot, you can use the following helper method:
.ini format, with one default section. The dict passed to `mock_config_info()` specifies .ini format, with one default section. The dict passed to `mock_config_info()` specifies
the keys and values of that section. the keys and values of that section.
##### Testing bots with internet access #### Testing bots with internet access
Some bots, such as [Giphy]( Some bots, such as [Giphy](
https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots/giphy), https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots/giphy),
@ -389,7 +384,7 @@ https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots
*Tip: You can use [requestb.in](http://requestb.in) or a similar tool to capture payloads from the *Tip: You can use [requestb.in](http://requestb.in) or a similar tool to capture payloads from the
service your bot is interacting with.* service your bot is interacting with.*
##### Testing bots that specify `initialize()` #### Testing bots that specify `initialize()`
Some bots, such as [Giphy]( Some bots, such as [Giphy](
https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots/giphy), https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots/giphy),
@ -400,7 +395,7 @@ such a bot, you can call its `initialize()` method with the following helper met
Calling `initialize_bot()` invokes the `initialize()` method specified by the bot. Calling `initialize_bot()` invokes the `initialize()` method specified by the bot.
##### Examples #### Examples
Check out our [bots](https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots) Check out our [bots](https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots)
to see examples of bot tests. to see examples of bot tests.