2017-01-27 00:09:18 +01:00
|
|
|
# Contrib bots
|
2016-08-17 18:34:11 +02:00
|
|
|
|
2016-08-23 04:53:16 +02:00
|
|
|
This is the documentation for an experimental new system for writing
|
2017-01-27 00:09:18 +01:00
|
|
|
bots that react to messages. It explains how to run the code, and also
|
|
|
|
talks about the architecture for creating such bots.
|
2016-08-23 04:53:16 +02:00
|
|
|
|
2017-01-27 00:09:18 +01:00
|
|
|
This directory contains library code for running them.
|
2016-08-17 18:34:11 +02:00
|
|
|
|
2017-01-27 00:09:18 +01:00
|
|
|
## Design goals
|
2016-08-23 04:53:16 +02:00
|
|
|
|
|
|
|
The goal is to have a common framework for hosting a bot that reacts
|
|
|
|
to messages in any of the following settings:
|
|
|
|
|
2017-01-08 15:59:13 +01:00
|
|
|
* Run as a long-running process using `call_on_each_event`.
|
2016-08-23 04:53:16 +02:00
|
|
|
|
|
|
|
* Run via a simple web service that can be deployed to PAAS providers
|
|
|
|
and handles outgoing webhook requests from Zulip.
|
|
|
|
|
|
|
|
* Embedded into the Zulip server (so that no hosting is required),
|
|
|
|
which would be done for high quality, reusable bots; we would have a
|
|
|
|
nice "bot store" sort of UI for browsing and activating them.
|
|
|
|
|
2017-01-08 15:59:13 +01:00
|
|
|
* Run locally by our technically inclined users for bots that require
|
|
|
|
account specific authentication, for example: a gmail bot that lets
|
|
|
|
one send emails directly through Zulip.
|
|
|
|
|
2017-01-27 00:09:18 +01:00
|
|
|
## Running bots
|
2016-08-17 18:34:11 +02:00
|
|
|
|
|
|
|
Here is an example of running the "follow-up" bot from
|
2017-01-08 12:28:11 +01:00
|
|
|
inside a Zulip repo (and in your remote instance):
|
2016-08-17 18:34:11 +02:00
|
|
|
|
|
|
|
cd ~/zulip/contrib_bots
|
2017-01-22 11:38:34 +01:00
|
|
|
./run.py bots/followup/followup.py --config-file ~/.zuliprc-prod
|
2016-08-17 18:34:11 +02:00
|
|
|
|
|
|
|
Once the bot code starts running, you will see a
|
|
|
|
message explaining how to use the bot, as well as
|
2017-01-27 00:09:18 +01:00
|
|
|
some log messages. You can use the `--quiet` option
|
2016-08-17 18:34:11 +02:00
|
|
|
to suppress these messages.
|
|
|
|
|
2017-01-08 12:28:11 +01:00
|
|
|
The bot code will run continuously until you end the program with
|
2016-08-17 18:34:11 +02:00
|
|
|
control-C (or otherwise).
|
|
|
|
|
2017-01-27 00:09:18 +01:00
|
|
|
### Zulip configuration
|
2016-08-24 21:09:11 +02:00
|
|
|
|
|
|
|
For this document we assume you have some prior experience
|
|
|
|
with using the Zulip API, but here is a quick review of
|
2017-01-27 00:09:18 +01:00
|
|
|
what a `.zuliprc` files looks like. You can connect to the
|
2016-08-24 21:09:11 +02:00
|
|
|
API as your own human user, or you can go into the Zulip settings
|
|
|
|
page to create a user-owned bot.
|
|
|
|
|
|
|
|
[api]
|
|
|
|
email=someuser@example.com
|
|
|
|
key=<your api key>
|
|
|
|
site=https://zulip.somewhere.com
|
|
|
|
|
2017-01-08 15:59:13 +01:00
|
|
|
When you run your bot, make sure to point it to the correct location
|
|
|
|
of your `.zuliprc`.
|
2016-12-14 23:54:24 +01:00
|
|
|
|
2017-01-27 00:09:18 +01:00
|
|
|
### Third party configuration
|
2016-12-14 23:54:24 +01:00
|
|
|
|
|
|
|
If your bot interacts with a non-Zulip service, you may
|
|
|
|
have to configure keys or usernames or URLs or similar
|
|
|
|
information to hit the other service.
|
|
|
|
|
2017-01-08 12:28:11 +01:00
|
|
|
Do **NOT** put third party configuration information in your
|
2017-01-27 00:09:18 +01:00
|
|
|
`.zuliprc` file. Do not put third party configuration
|
|
|
|
information anywhere in your Zulip directory. Instead,
|
2016-12-14 23:54:24 +01:00
|
|
|
create a separate configuration file for the third party's
|
|
|
|
configuration in your home directory.
|
|
|
|
|
2017-01-08 15:59:13 +01:00
|
|
|
Any bots that require this will have instructions on
|
|
|
|
exactly how to create or access this information.
|
|
|
|
|
2017-01-27 00:09:18 +01:00
|
|
|
### Python dependencies
|
2016-12-15 00:00:32 +01:00
|
|
|
|
|
|
|
If your module requires Python modules that are not either
|
|
|
|
part of the standard Python library or the Zulip API
|
|
|
|
distribution, we ask that you put a comment at the top
|
2017-01-08 12:28:11 +01:00
|
|
|
of your bot explaining how to install the dependencies/modules.
|
2016-12-15 00:00:32 +01:00
|
|
|
|
|
|
|
Right now we don't support any kind of automatic build
|
|
|
|
environment for bots, so it's currently up to the users
|
2017-01-27 00:09:18 +01:00
|
|
|
of the bots to manage their dependencies. This may change
|
2016-12-15 00:00:32 +01:00
|
|
|
in the future.
|
|
|
|
|
2016-08-17 18:34:11 +02:00
|
|
|
## Architecture
|
|
|
|
|
|
|
|
In order to make bot development easy, we separate
|
|
|
|
out boilerplate code (loading up the Client API, etc.)
|
2017-01-08 12:28:11 +01:00
|
|
|
from bot-specific code (actions of the bot/what the bot does).
|
2016-08-17 18:34:11 +02:00
|
|
|
|
2017-01-27 00:09:18 +01:00
|
|
|
All of the boilerplate code lives in `../run.py`. The
|
2016-08-17 18:34:11 +02:00
|
|
|
runner code does things like find where it can import
|
|
|
|
the Zulip API, instantiate a client with correct
|
|
|
|
credentials, set up the logging level, find the
|
|
|
|
library code for the specific bot, etc.
|
|
|
|
|
|
|
|
Then, for bot-specific logic, you will find `.py` files
|
|
|
|
in the `lib` directory (i.e. the same directory as the
|
|
|
|
document you are reading now).
|
|
|
|
|
|
|
|
Each bot library simply needs to do the following:
|
|
|
|
|
2017-03-05 14:52:12 +01:00
|
|
|
- Define a class that supports the methods `usage`
|
|
|
|
and `handle_message`.
|
2016-08-17 18:34:11 +02:00
|
|
|
- Set `handler_class` to be the name of that class.
|
|
|
|
|
2017-01-08 15:59:13 +01:00
|
|
|
(We make this a two-step process to reduce code repetition
|
|
|
|
and to add abstraction.)
|
2016-08-17 18:34:11 +02:00
|
|
|
|
|
|
|
## Portability
|
|
|
|
|
|
|
|
Creating a handler class for each bot allows your bot
|
2017-01-08 15:59:13 +01:00
|
|
|
code to be more portable. For example, if you want to
|
2016-08-17 18:34:11 +02:00
|
|
|
use your bot code in some other kind of bot platform, then
|
|
|
|
if all of your bots conform to the `handler_class` protocol,
|
|
|
|
you can write simple adapter code to use them elsewhere.
|
|
|
|
|
|
|
|
Another future direction to consider is that Zulip will
|
|
|
|
eventually support running certain types of bots on
|
|
|
|
the server side, to essentially implement post-send
|
|
|
|
hooks and things of those nature.
|
|
|
|
|
|
|
|
Conforming to the `handler_class` protocol will make
|
|
|
|
it easier for Zulip admins to integrate custom bots.
|
|
|
|
|
|
|
|
In particular, `run.py` already passes in instances
|
|
|
|
of a restricted variant of the Client class to your
|
|
|
|
library code, which helps you ensure that your bot
|
|
|
|
does only things that would be acceptable for running
|
|
|
|
in a server-side environment.
|
|
|
|
|
|
|
|
## Other approaches
|
|
|
|
|
|
|
|
If you are not interested in running your bots on the
|
2017-01-08 15:59:13 +01:00
|
|
|
server, then you can still use the full Zulip API and run
|
2017-01-27 00:09:18 +01:00
|
|
|
them locally. The hope, though, is that this
|
2017-01-08 15:59:13 +01:00
|
|
|
architecture will make writing simple bots a quick/easy
|
|
|
|
process.
|