2017-07-19 06:16:27 +02:00
|
|
|
# Outgoing Webhooks
|
|
|
|
|
|
|
|
Outgoing Webhooks allow you to build or set up Zulip integrations
|
|
|
|
which are notified when certain types of messages are sent in
|
|
|
|
Zulip. When one of those events is triggered, we'll send a HTTP POST
|
|
|
|
payload to the webhook's configured URL. Webhooks can be used to
|
|
|
|
power a wide range of Zulip integrations. For example, the
|
2018-05-29 10:53:45 +02:00
|
|
|
[Zulip Botserver][zulip-botserver] is built on top of this API.
|
2017-07-19 06:16:27 +02:00
|
|
|
|
|
|
|
Zulip supports outgoing webhooks both in a clean native Zulip format,
|
|
|
|
as well as a format that's compatible with
|
|
|
|
[Slack's outgoing webhook API][slack-outgoing-webhook], which can help
|
|
|
|
with porting an existing Slack integration to work with Zulip.
|
|
|
|
|
2020-05-20 20:47:44 +02:00
|
|
|
[zulip-botserver]: /api/deploying-bots#zulip-botserver
|
2017-07-19 06:16:27 +02:00
|
|
|
[slack-outgoing-webhook]: https://api.slack.com/custom-integrations/outgoing-webhooks
|
|
|
|
|
|
|
|
To register an outgoing webhook:
|
|
|
|
|
|
|
|
* Log in to the Zulip server.
|
|
|
|
* Navigate to *Settings (<i class="fa fa-cog"></i>)* -> *Your bots* ->
|
|
|
|
*Add a new bot*. Select *Outgoing webhook* for bot type, the URL
|
|
|
|
you'd like Zulip to post to as the **Endpoint URL**, the format you
|
|
|
|
want, and click on *Create bot*. to submit the form/
|
|
|
|
* Your new bot user will appear in the *Active bots* panel, which you
|
|
|
|
can use to edit the bot's settings.
|
|
|
|
|
|
|
|
## Triggering
|
|
|
|
|
|
|
|
There are currently two ways to trigger an outgoing webhook:
|
2020-08-29 01:43:12 +02:00
|
|
|
|
2017-07-19 06:16:27 +02:00
|
|
|
1. **@-mention** the bot user in a stream. If the bot replies, its
|
|
|
|
reply will be sent to that stream and topic.
|
|
|
|
2. **Send a private message** with the bot as one of the recipients.
|
|
|
|
If the bot replies, its reply will be sent to that thread.
|
|
|
|
|
2020-08-29 01:43:12 +02:00
|
|
|
## Outgoing webhook format
|
|
|
|
|
|
|
|
This is an example of the JSON payload that the Zulip server will `POST`
|
|
|
|
to your server:
|
|
|
|
|
|
|
|
{generate_code_example|/zulip-outgoing-webhook:post|fixture(200)}
|
2017-07-19 06:16:27 +02:00
|
|
|
|
2020-08-29 01:43:12 +02:00
|
|
|
### Fields documentation
|
2017-07-19 06:16:27 +02:00
|
|
|
|
2020-08-27 22:54:56 +02:00
|
|
|
{generate_return_values_table|zulip.yaml|/zulip-outgoing-webhook:post}
|
2017-07-19 06:16:27 +02:00
|
|
|
|
2020-08-29 01:43:12 +02:00
|
|
|
## Replying with a message
|
|
|
|
|
|
|
|
Many bots implemented using this outgoing webhook API will want to
|
|
|
|
send a reply message into Zulip. Zulip's outgoing webhook API
|
|
|
|
provides a convenient way to do that by simply returning an
|
|
|
|
appropriate HTTP response to the Zulip server.
|
2017-07-19 06:16:27 +02:00
|
|
|
|
2020-08-29 01:43:12 +02:00
|
|
|
A correctly implemented bot will return a JSON object containing one
|
|
|
|
of two possible formats, described below.
|
|
|
|
|
|
|
|
### Example response payloads
|
2018-10-10 12:58:45 +02:00
|
|
|
|
|
|
|
If the bot code wants to opt out of responding, it can explicitly
|
|
|
|
encode a JSON dictionary that contains `response_not_required` set
|
|
|
|
to `True`, so that no response message is sent to the user. (This
|
|
|
|
is helpful to distinguish deliberate non-responses from bugs.)
|
|
|
|
|
2018-09-11 00:16:34 +02:00
|
|
|
Here's an example of the JSON your server should respond with if
|
|
|
|
you would not like to send a response message:
|
|
|
|
|
|
|
|
```
|
|
|
|
{
|
|
|
|
"response_not_required": true
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Here's an example of the JSON your server should respond with if
|
|
|
|
you would like to send a response message:
|
|
|
|
|
|
|
|
```
|
|
|
|
{
|
2020-08-29 01:43:12 +02:00
|
|
|
"content": "Hey, we just received **something** from Zulip!"
|
2018-09-11 00:16:34 +02:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2020-08-29 01:43:12 +02:00
|
|
|
The `content` field should contain Zulip-format markdown.
|
|
|
|
|
|
|
|
Note that an outgoing webhook bot can use the [Zulip REST
|
|
|
|
API](/api/rest) with its API key in case your bot needs to do
|
|
|
|
something else, like add an emoji reaction or upload a file.
|
|
|
|
|
2017-07-19 06:16:27 +02:00
|
|
|
## Slack-format webhook format
|
|
|
|
|
2018-11-09 07:13:03 +01:00
|
|
|
This interface translates Zulip's outgoing webhook's request into the
|
|
|
|
format that Slack's outgoing webhook interface sends. As a result,
|
|
|
|
one should be able to use this to interact with third-party
|
|
|
|
integrations designed to work with Slack's outgoing webhook interface.
|
|
|
|
Here's how we fill in the fields that a Slack-format webhook expects:
|
2017-07-19 06:16:27 +02:00
|
|
|
|
2018-06-02 16:05:49 +02:00
|
|
|
<table class="table">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Name</th>
|
|
|
|
<th>Description</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<td><code>token</code></td>
|
|
|
|
<td>A string of alphanumeric characters you can use to
|
|
|
|
authenticate the webhook request (each bot user uses a fixed token)</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><code>team_id</code></td>
|
|
|
|
<td>String ID of the Zulip organization</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><code>team_domain</code></td>
|
|
|
|
<td>Domain of the Zulip organization</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><code>channel_id</code></td>
|
|
|
|
<td>Stream ID</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><code>channel_name</code></td>
|
|
|
|
<td>Stream name</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><code>timestamp</code></td>
|
|
|
|
<td>Timestamp for when message was sent</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><code>user_id</code></td>
|
|
|
|
<td>ID of the user who sent the message</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><code>user_name</code></td>
|
|
|
|
<td>Full name of sender</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><code>text</code></td>
|
|
|
|
<td>The content of the message (in Markdown)</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><code>trigger_word</code></td>
|
|
|
|
<td>Trigger method</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><code>service_id</code></td>
|
|
|
|
<td>ID of the bot user</td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
2017-07-19 06:16:27 +02:00
|
|
|
|
2018-06-02 15:45:18 +02:00
|
|
|
The above data is posted as list of tuples (not JSON), here's an example:
|
|
|
|
|
|
|
|
```
|
2018-07-20 11:49:14 +02:00
|
|
|
[('token', 'v9fpCdldZIej2bco3uoUvGp06PowKFOf'),
|
2018-06-02 15:45:18 +02:00
|
|
|
('team_id', 'zulip'),
|
|
|
|
('team_domain', 'zulip.com'),
|
|
|
|
('channel_id', '123'),
|
|
|
|
('channel_name', 'integrations'),
|
2018-07-20 11:49:14 +02:00
|
|
|
('timestamp', 1532078950),
|
2018-06-02 15:45:18 +02:00
|
|
|
('user_id', 21),
|
|
|
|
('user_name', 'Sample User'),
|
|
|
|
('text', '@**test**'),
|
|
|
|
('trigger_word', 'mention'),
|
2018-07-20 11:49:14 +02:00
|
|
|
('service_id', 27)]
|
2018-06-02 15:45:18 +02:00
|
|
|
```
|
2017-07-19 06:16:27 +02:00
|
|
|
|
|
|
|
* For successful request, if data is returned, it returns that data,
|
|
|
|
else it returns a blank response.
|
|
|
|
* For failed request, it returns the reason of failure, as returned by
|
|
|
|
the server, or the exception message.
|