mirror of https://github.com/zulip/zulip.git
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:
parent
b6106ca7ac
commit
543500bab5
|
@ -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`
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue