docs: Rename "webhooks" to "incoming webhooks".

I only renamed references that I thought were absolutely necessary
and only if the resulting sentence structure wasn't awkward.

If the renaming resulted in awkward structure, I replaced the term
"webhook" with "integration" (but only in some very obvious cases).

Fixes #9500.
This commit is contained in:
Eeshan Garg 2018-05-30 21:26:18 -02:30 committed by Tim Abbott
parent 8abaca1457
commit 4f98a45507
11 changed files with 60 additions and 58 deletions

View File

@ -25,7 +25,7 @@ paths will be familiar to Django developers.
* `zerver/views/*.py` Most [Django views](https://docs.djangoproject.com/en/1.8/topics/http/views/). * `zerver/views/*.py` Most [Django views](https://docs.djangoproject.com/en/1.8/topics/http/views/).
* `zerver/webhooks/` Webhook views and tests for [Zulip webhook integrations]( * `zerver/webhooks/` Webhook views and tests for [Zulip's incoming webhook integrations](
https://zulipchat.com/api/integration-guide). https://zulipchat.com/api/integration-guide).
* `zerver/tornado/views.py` Tornado views. * `zerver/tornado/views.py` Tornado views.

View File

@ -35,4 +35,4 @@ object as `request.client`.
In most integrations, `request.client` is then passed to In most integrations, `request.client` is then passed to
`check_send_stream_message`, where it is used to keep track of which client `check_send_stream_message`, where it is used to keep track of which client
sent the message (which in turn is used by analytics). For more sent the message (which in turn is used by analytics). For more
information, see [the webhook walkthrough](https://zulipchat.com/api/webhook-walkthrough). information, see [the incoming webhook walkthrough](https://zulipchat.com/api/webhook-walkthrough).

View File

@ -181,9 +181,9 @@ The [three different integration models](https://zulipchat.com/api/integration-g
basically differ in where they perform the main functions of a basically differ in where they perform the main functions of a
**World Reader**. **World Reader**.
#### Webhook integrations #### Incoming webhook integrations
In a **webhook** integration, the deployment model is usually this:: In an **incoming webhook** integration, the deployment model is usually this::
**3rd party hardware**: **3rd party hardware**:
- detect event - detect event

View File

@ -88,7 +88,7 @@ Note the `zh-hans` prefix--that url pattern gets added by `i18n_patterns`.
Our example is a REST API endpoint. It's a PUT to `/users`. Our example is a REST API endpoint. It's a PUT to `/users`.
With the exception of Webhooks (which we do not usually control the With the exception of incoming webhooks (which we do not usually control the
format of), legacy endpoints, and logged-out endpoints, Zulip uses REST format of), legacy endpoints, and logged-out endpoints, Zulip uses REST
for its API. This means that we use: for its API. This means that we use:
@ -154,7 +154,7 @@ mind. They are used extensively by the web client, and use POST.
You can see them in You can see them in
[zproject/legacy_urls.py](https://github.com/zulip/zulip/blob/master/zproject/legacy_urls.py). [zproject/legacy_urls.py](https://github.com/zulip/zulip/blob/master/zproject/legacy_urls.py).
### Webhook integrations may not be RESTful ### Incoming webhook integrations may not be RESTful
Zulip endpoints that are called by other services for integrations have Zulip endpoints that are called by other services for integrations have
to conform to the service's request format. They are likely to use to conform to the service's request format. They are likely to use

View File

@ -345,9 +345,9 @@ These endpoints make use of some older authentication decorators,
`authenticated_json_api_view`, `authenticated_json_post_view`, and `authenticated_json_api_view`, `authenticated_json_post_view`, and
`authenticated_json_view`, so you may see them in the code. `authenticated_json_view`, so you may see them in the code.
## Webhook integration endpoints ## Incoming webhook integrations
Webhooks are called by other services, often to send a message as part Incoming webhooks are called by other services, often to send a message as part
of those services' integrations. They are most often POST requests, and of those services' integrations. They are most often POST requests, and
often there is very little you can customize about them. Usually you can often there is very little you can customize about them. Usually you can
expect that the webhook for a service will allow specification for the expect that the webhook for a service will allow specification for the

View File

@ -10,7 +10,7 @@ guide should help you find the API you need:
Zulip's native integrations with Zapier and IFTTT often allow Zulip's native integrations with Zapier and IFTTT often allow
integrating a new service with Zulip without writing any code. integrating a new service with Zulip without writing any code.
* If you'd like to send content into Zulip, you can * If you'd like to send content into Zulip, you can
[write a native incoming webhook integration](/api/integration-guide#webhook-integrations) [write a native incoming webhook integration](/api/integration-guide#incoming-webhook-integrations)
or use [Zulip's API for sending messages](/api/stream-message). or use [Zulip's API for sending messages](/api/stream-message).
* If you're building an interactive bot that reacts to activity inside * If you're building an interactive bot that reacts to activity inside
Zulip, you'll want to look at Zulip's Zulip, you'll want to look at Zulip's
@ -19,4 +19,3 @@ guide should help you find the API you need:
* If you'd like to do something else, check out the full * If you'd like to do something else, check out the full
[REST API](/api/rest), generally starting with [REST API](/api/rest), generally starting with
[installing the API client bindings](/api/installation-instructions). [installing the API client bindings](/api/installation-instructions).

View File

@ -30,9 +30,9 @@ Usually, this involves a few steps:
* Finally, generate a message sent by the integration and take a * Finally, generate a message sent by the integration and take a
screenshot of the message to provide an example message in the screenshot of the message to provide an example message in the
documentation. If your new integration is a webhook integration, documentation. If your new integration is an incoming webhook
you can generate such a message from your test fixtures integration, you can generate such a message from your test
using `send_webhook_fixture_message`: fixtures using `send_webhook_fixture_message`:
``` ```
./manage.py send_webhook_fixture_message \ ./manage.py send_webhook_fixture_message \
@ -61,13 +61,13 @@ Here are a few common macros used to document Zulip's integrations:
* `{!create-stream.md!}` macro - Recommends that users create a dedicated * `{!create-stream.md!}` macro - Recommends that users create a dedicated
stream for a given integration. Usually the first step in setting up an stream for a given integration. Usually the first step in setting up an
integration or webhook. For an example rendering, see **Step 1** of integration or incoming webhook. For an example rendering, see **Step 1** of
[the docs for Zulip's GitHub integration][GitHub]. [the docs for Zulip's GitHub integration][GitHub].
* `{!create-bot-construct-url.md!}` macro - Instructs users to create a bot * `{!create-bot-construct-url.md!}` macro - Instructs users to create a bot
for a given integration and construct a webhook URL using the bot API key for a given integration and construct a webhook URL using the bot API key
and stream name. The URL is generated automatically for every webhook by using and stream name. The URL is generated automatically for every incoming webhook
attributes in the [WebhookIntegration][1] class. by using attributes in the [WebhookIntegration][1] class.
This macro is usually used right after `{!create-stream!}`. For an example This macro is usually used right after `{!create-stream!}`. For an example
rendering, see **Step 2** of [the docs for Zulip's GitHub integration][GitHub]. rendering, see **Step 2** of [the docs for Zulip's GitHub integration][GitHub].

View File

@ -11,7 +11,7 @@ On this page you'll find:
* An overview of the different [types of integrations](#types-of-integrations) * An overview of the different [types of integrations](#types-of-integrations)
possible with Zulip. possible with Zulip.
* [General advice](#general-advice) for writing integrations. * [General advice](#general-advice) for writing integrations.
* Details about writing [webhook integrations](#webhook-integrations). * Details about writing [incoming webhook integrations](#incoming-webhook-integrations).
* Details about writing [Python script and plugin * Details about writing [Python script and plugin
integrations](#python-script-and-plugin-integrations). integrations](#python-script-and-plugin-integrations).
* A guide to * A guide to
@ -19,7 +19,7 @@ On this page you'll find:
separate page. separate page.
A detailed walkthrough of a simple "Hello World" integration can be A detailed walkthrough of a simple "Hello World" integration can be
found in the [webhook walkthrough](webhook-walkthrough). found in the [incoming webhook walkthrough](webhook-walkthrough).
Contributions to this guide are very welcome, so if you run into any 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 issues following these instructions or come up with any tips or tools
@ -32,7 +32,7 @@ to share your ideas!
We have several different ways that we integrate with 3rd party We have several different ways that we integrate with 3rd party
products, ordered here by which types we prefer to write: products, ordered here by which types we prefer to write:
1. **[Webhook integrations](#webhook-integrations)** (examples: 1. **[Incoming webhook integrations](#incoming-webhook-integrations)** (examples:
Freshdesk, GitHub), where the third-party service supports posting Freshdesk, GitHub), where the third-party service supports posting
content to a particular URI on our site with data about the event. content to a particular URI on our site with data about the event.
For these, you usually just need to create a new python package in For these, you usually just need to create a new python package in
@ -86,11 +86,11 @@ products, ordered here by which types we prefer to write:
spot why something isn't working or if the service is using custom HTTP spot why something isn't working or if the service is using custom HTTP
headers. headers.
## Webhook integrations ## Incoming webhook integrations
A webhook allows a third-party service to push data to you when something An incoming webhook allows a third-party service to push data to you when something
happens. It's different from making a REST API call, where you send a request happens. It's different from making a REST API call, where you send a request
to the service's API and wait for a response. With a webhook, the third-party to the service's API and wait for a response. With an incoming webhook, the third-party
service sends you an HTTP POST when it has something for you. Your webhook service sends you an HTTP POST when it has something for you. Your webhook
integration defines the URI the service uses to communicate with Zulip, and integration defines the URI the service uses to communicate with Zulip, and
handles that incoming data. handles that incoming data.
@ -133,7 +133,7 @@ For a quick guide, read on.
[this guide](https://zulip.readthedocs.io/en/latest/testing/testing.html) [this guide](https://zulip.readthedocs.io/en/latest/testing/testing.html)
for more details on the Zulip test runner.* for more details on the Zulip test runner.*
* Once you've gotten your webhook working and passing a test, capture * Once you've gotten your incoming webhook working and passing a test, capture
payloads for the other common types of posts the service's webhook payloads for the other common types of posts the service's webhook
will make, and add tests for them; usually this part of the will make, and add tests for them; usually this part of the
process is pretty fast. Webhook integration tests should all use process is pretty fast. Webhook integration tests should all use
@ -146,8 +146,8 @@ For a quick guide, read on.
### Files that need to be created ### Files that need to be created
Select a name for your webhook and use it consistently. The examples below are Select a name for your incoming webhook and use it consistently. The examples
for a webhook named 'MyWebHook'. below are for a webhook named 'MyWebHook'.
* `static/images/integrations/logos/mywebhook.svg`: An image to represent * `static/images/integrations/logos/mywebhook.svg`: An image to represent
your integration in the user interface. Generally this should be the logo of the your integration in the user interface. Generally this should be the logo of the
@ -175,7 +175,7 @@ for a webhook named 'MyWebHook'.
* `zerver/lib/integrations.py`: Add your integration to * `zerver/lib/integrations.py`: Add your integration to
`WEBHOOK_INTEGRATIONS` to register it. This will automatically `WEBHOOK_INTEGRATIONS` to register it. This will automatically
register a url for the webhook of the form `api/v1/external/mywebhook` register a url for the incoming webhook of the form `api/v1/external/mywebhook`
and associate with the function called `api_mywebhook_webhook` in and associate with the function called `api_mywebhook_webhook` in
`zerver/webhooks/mywebhook/view.py`. `zerver/webhooks/mywebhook/view.py`.

View File

@ -3,9 +3,9 @@
* [Overview](/api/integration-guide) * [Overview](/api/integration-guide)
* [Existing integrations](/integrations) * [Existing integrations](/integrations)
## Writing webhook integrations ## Incoming webhooks
* [Overview](/api/integration-guide#webhook-integrations) * [Overview](/api/integration-guide#incoming-webhook-integrations)
* [Walkthrough](/api/webhook-walkthrough) * [Walkthrough](/api/webhook-walkthrough)
* [Documenting integrations](/api/integration-docs-guide) * [Documenting integrations](/api/integration-docs-guide)

View File

@ -1,7 +1,7 @@
# Webhook walkthrough # Incoming webhook walkthrough
Below, we explain each part of a simple webhook integration, called Below, we explain each part of a simple incoming webhook integration,
**Hello World**. This webhook sends a "hello" message to the `test` called **Hello World**. This integration sends a "hello" message to the `test`
stream and includes a link to the Wikipedia article of the day, which stream and includes a link to the Wikipedia article of the day, which
it formats from json data it receives in the http request. it formats from json data it receives in the http request.
@ -10,7 +10,7 @@ integration.
## Step 0: Create fixtures ## Step 0: Create fixtures
The first step in creating a webhook is to examine the data that the The first step in creating an incoming webhook is to examine the data that the
service you want to integrate will be sending to Zulip. service you want to integrate will be sending to Zulip.
You can use <http://requestb.in> or a similar tool to capture You can use <http://requestb.in> or a similar tool to capture
@ -25,8 +25,9 @@ A test fixture is a small file containing test data, one for each test.
Fixtures enable the testing of webhook integration code without the need to Fixtures enable the testing of webhook integration code without the need to
actually contact the service being integrated. actually contact the service being integrated.
Because `Hello World` is a very simple webhook that does one thing, it requires Because `Hello World` is a very simple integration that does one
only one fixture, `zerver/webhooks/helloworld/fixtures/hello.json`: thing, it requires only one fixture,
`zerver/webhooks/helloworld/fixtures/hello.json`:
``` ```
{ {
@ -35,8 +36,8 @@ only one fixture, `zerver/webhooks/helloworld/fixtures/hello.json`:
} }
``` ```
When writing your own webhook integration, you'll want to write a test function When writing your own incoming webhook integration, you'll want to write a test function
for each distinct message condition your webhook supports. You'll also need a for each distinct message condition your integration supports. You'll also need a
corresponding fixture for each of these tests. Depending on the type of data corresponding fixture for each of these tests. Depending on the type of data
the 3rd party service sends, your fixture may contain JSON, URL encoded text, or the 3rd party service sends, your fixture may contain JSON, URL encoded text, or
some other kind of data. See [Step 4: Create tests](#step-4-create-tests) or some other kind of data. See [Step 4: Create tests](#step-4-create-tests) or
@ -52,7 +53,7 @@ to create an empty `__init__.py` file in that directory via e.g.
## Step 2: Create main webhook code ## Step 2: Create main webhook code
The majority of the code for your webhook integration will be in a single The majority of the code for your new integration will be in a single
python file, `zerver/webhooks/mywebhook/view.py`. python file, `zerver/webhooks/mywebhook/view.py`.
The Hello World integration is in `zerver/webhooks/helloworld/view.py`: The Hello World integration is in `zerver/webhooks/helloworld/view.py`:
@ -99,20 +100,22 @@ access request variables with `REQ()`. You can find more about `REQ` and request
variables in [Writing views]( variables in [Writing views](
https://zulip.readthedocs.io/en/latest/tutorials/writing-views.html#request-variables). https://zulip.readthedocs.io/en/latest/tutorials/writing-views.html#request-variables).
You must pass the name of your webhook to the `api_key_only_webhook_view` You must pass the name of your integration to the
decorator so your webhook can access the `user_profile` and `request.client` `api_key_only_webhook_view` decorator; that name will be used to
(Zulip's analogue of UserAgent) fields from the request. Here we have used describe your integration in Zulip's analytics (e.g. the `/stats`
`HelloWorld`. To be consistent with Zulip code style, use the name of the page). Here we have used `HelloWorld`. To be consistent with other
product you are integrating in camel case, spelled as the product spells integrations, use the name of the product you are integrating in camel
its own name (except always first letter upper-case). case, spelled as the product spells its own name (except always first
letter upper-case).
The `api_key_only_webhook_view` decorator indicates that the 3rd party service will The `api_key_only_webhook_view` decorator indicates that the 3rd party service will
send the authorization as an API key in the query parameters. If your service uses send the authorization as an API key in the query parameters. If your service uses
HTTP Basic authentication, you would instead use the `authenticated_rest_api_view` HTTP Basic authentication, you would instead use the `authenticated_rest_api_view`
decorator. decorator.
You should name your webhook function as such `api_webhookname_webhook` where You should name your webhook function as such
`webhookname` is the name of your webhook and is always lower-case. `api_webhookname_webhook` where `webhookname` is the name of your
integration and is always lower-case.
At minimum, the webhook function must accept `request` (Django At minimum, the webhook function must accept `request` (Django
[HttpRequest](https://docs.djangoproject.com/en/1.8/ref/request-response/#django.http.HttpRequest) [HttpRequest](https://docs.djangoproject.com/en/1.8/ref/request-response/#django.http.HttpRequest)
@ -151,8 +154,8 @@ Finally, we return a 200 http status with a JSON format success message via
## Step 3: Create an api endpoint for the webhook ## Step 3: Create an api endpoint for the webhook
In order for a webhook to be externally available, it must be mapped to a url. In order for an incoming webhook to be externally available, it must be mapped
This is done in `zerver/lib/integrations.py`. to a url. This is done in `zerver/lib/integrations.py`.
Look for the lines beginning with: Look for the lines beginning with:
@ -256,7 +259,7 @@ and the value you set for `STREAM_NAME` must match. The test helpers use `STREAM
to create the destination stream, and then create the message to send using the to create the destination stream, and then create the message to send using the
value from the fixture. If these don't match, the test will fail. value from the fixture. If these don't match, the test will fail.
`URL_TEMPLATE` defines how the test runner will call your webhook, in the same way `URL_TEMPLATE` defines how the test runner will call your incoming webhook, in the same way
you would provide a webhook URL to the 3rd party service. `api_key={api_key}` says you would provide a webhook URL to the 3rd party service. `api_key={api_key}` says
that an API key is expected. that an API key is expected.
@ -318,7 +321,7 @@ DONE!
## Step 5: Create documentation ## Step 5: Create documentation
Next, we add end-user documentation for our webhook integration. You Next, we add end-user documentation for our integration. You
can see the existing examples at <https://zulipchat.com/integrations> can see the existing examples at <https://zulipchat.com/integrations>
or by accessing `/integrations` in your Zulip development environment. or by accessing `/integrations` in your Zulip development environment.
@ -388,7 +391,7 @@ request:
3. Take a look at your git history to ensure your commits have been clear and 3. Take a look at your git history to ensure your commits have been clear and
logical (see [Version Control]( logical (see [Version Control](
https://zulip.readthedocs.io/en/latest/contributing/version-control.html) for tips). If not, https://zulip.readthedocs.io/en/latest/contributing/version-control.html) for tips). If not,
consider revising them with `git rebase --interactive`. For most webhooks, consider revising them with `git rebase --interactive`. For most incoming webhooks,
you'll want to squash your changes into a single commit and include a good, you'll want to squash your changes into a single commit and include a good,
clear commit message. clear commit message.
4. Push code to your fork. 4. Push code to your fork.
@ -416,7 +419,7 @@ be a successful test of an error condition. To correctly test these cases, you
must explicitly code your test's execution (using other helpers, as needed) must explicitly code your test's execution (using other helpers, as needed)
rather than call the usual helper function. rather than call the usual helper function.
Here is an example from the WordPress webhook: Here is an example from the WordPress integration:
``` ```
def test_unknown_action_no_data(self) -> None: def test_unknown_action_no_data(self) -> None:
@ -438,7 +441,7 @@ def test_unknown_action_no_data(self) -> None:
``` ```
In a normal test, `send_and_test_stream_message` would handle all the setup In a normal test, `send_and_test_stream_message` would handle all the setup
and then check that the webhook's response matches the expected result. If and then check that the incoming webhook's response matches the expected result. If
the webhook returns an error, the test fails. Instead, explicitly do the the webhook returns an error, the test fails. Instead, explicitly do the
setup it would have done, and check the result yourself. setup it would have done, and check the result yourself.
@ -446,8 +449,8 @@ Here, `subscribe_to_stream` is a test helper that uses `TEST_USER_EMAIL` and
`STREAM_NAME` (attributes from the base class) to register the user to receive `STREAM_NAME` (attributes from the base class) to register the user to receive
messages in the given stream. If the stream doesn't exist, it creates it. messages in the given stream. If the stream doesn't exist, it creates it.
`client_post`, another helper, performs the HTTP POST that calls the webhook. `client_post`, another helper, performs the HTTP POST that calls the incoming
As long as `self.url` is correct, you don't need to construct the webhook webhook. As long as `self.url` is correct, you don't need to construct the webhook
URL yourself. (In most cases, it is.) URL yourself. (In most cases, it is.)
`assert_json_error` then checks if the result matches the expected error. `assert_json_error` then checks if the result matches the expected error.
@ -548,5 +551,5 @@ recommend raising `UnexpectedWebhookEventType` (found in
raise UnexpectedWebhookEventType(webhook_name, event_type) raise UnexpectedWebhookEventType(webhook_name, event_type)
``` ```
`webhook_name` is the name of the webhook that raises the exception. `event_type` `webhook_name` is the name of the integration that raises the exception.
is the name of the unexpected webhook event. `event_type` is the name of the unexpected webhook event.

View File

@ -92,8 +92,8 @@ the escape key.
An **integration** is a tool that combines Zulip with another service or An **integration** is a tool that combines Zulip with another service or
application. Zulip offers a variety of integrations for version control, issue application. Zulip offers a variety of integrations for version control, issue
tracker, CI system, monitoring tools, and other tools used for development. The tracker, CI system, monitoring tools, and other tools used for development. The
three types of integrations that Zulip supports are webhook integrations, Python three types of integrations that Zulip supports are incoming webhook integrations,
script integrations, and plugin integrations. Python script integrations, and plugin integrations.
### mention ### mention