docs/documentation/integrations.md
In order for a Zulip
integration to be useful
to users, it must be documented. Zulip's common system for documenting
integrations involves writing Markdown files, either at
zerver/webhooks/{webhook_name}/doc.md (for webhook integrations) or
templates/zerver/integrations/{integration_name}.md (for other
integrations).
The integrations in
zulip/python-zulip-api have their corresponding Markdown files
at zulip/integrations/{integration_name}/doc.md, which are imported into
zulip/zulip at
static/generated/integrations/{integration_name}/doc.md using the
tools/setup/generate_bots_integrations_static_files.py script.
Typically, the documentation process involves the following steps:
Add text explaining all of the steps required to set up the integration, including what URLs to use, etc. See Writing guidelines for detailed writing guidelines.
Zulip's pre-defined Markdown macros can be used for some of these steps. See Markdown macros for further details.
Make sure you've added your integration to zerver/lib/integrations.py in
the relevant *_INTEGRATIONS list, such as the
INCOMING_WEBHOOK_INTEGRATIONS list for incoming webhook integrations.
These lists get aggregated into the INTEGRATIONS registry which
configures your integration to appear on the /integrations page, and
makes it possible to automatically generate the screenshot of an example
message, which is important so that these screenshots can be easily
updated as Zulip's design changes.
You'll need to add an SVG graphic of your integration's logo under the
static/images/integrations/logos/<name>.svg, where <name> is the
name of the integration, all in lower case; you can usually find them in the
product branding or press page. Make sure to optimize the SVG graphic by
running tools/setup/optimize-svg. This will also run
tools/setup/generate_integration_bots_avatars.py automatically to generate
a smaller version of the image you just added and optimized. This smaller
image will be used as the bot avatar in the documentation screenshot that
will be generated in the next step.
If you cannot find an SVG graphic of the logo, please find and include a PNG image of the logo instead.
Finally, you will need to generate a message sent by the integration, and generate a screenshot of the message to provide an example message in the integration's documentation.
If your new integration is not an incoming webhook and does not have fixtures, add a
message template and topic to zerver/webhooks/fixtureless_integrations.py.
Then, add your integration's name to FIXTURELESS_INTEGRATIONS_WITH_SCREENSHOTS
in zerver/lib/integrations.py. See this commit for an
example.
Otherwise, you should have already added your integration along with its
screenshot config to INCOMING_WEBHOOK_INTEGRATIONS.
Generate the screenshot using tools/screenshots/generate-integration-docs-screenshot,
where integrationname is the name of the integration:
./tools/screenshots/generate-integration-docs-screenshot --integration integrationname
If you have trouble using this tool, you can also manually generate the
screenshot using manage.py send_webhook_fixture_message. When generating the
screenshot of a sample message using this method, give your test bot a nice
name like "GitHub Bot", use the project's logo as the bot's avatar, and take
the screenshot showing the channel/topic bar for the message, not just the
message body.
Macros are elements in the format of {!macro.md!} that insert common
phrases and steps at the location of the macros. Macros help eliminate
repeated content in our documentation.
The source for macros is the Markdown files under
templates/zerver/integrations/include/ in the
main Zulip server repository. If you find
multiple instances of particular content in the documentation, you can
always create a new macro by adding a new file to that folder.
Here are a few common macros used to document Zulip's integrations:
{!create-channel.md!} macro - Recommends that users create a dedicated
channel for a given integration. Usually the first step is setting up an
integration or incoming webhook. For an example rendering, see Step 1 of
the docs for Zulip's Zendesk integration.
{!create-an-incoming-webhook.md!} macro - Instructs users to create a bot
for a given integration and select Incoming webhook as the Bot type.
This macro is usually used right after {!create-channel.md!}. For an example
rendering, see Step 2 of the docs for Zulip's Zendesk integration.
{!create-a-generic-bot.md!} macro - Instructs users to create a bot
for a given integration and select Generic bot as the Bot type. For an
example rendering, see the docs for Zulip's Matrix integration.
{!generate-webhook-url-basic.md!} - Instructs user how to get the URL for a
bot for a given integration. Note that this macro should not be used with the
{!create-channel.md!} macro. For an example rendering, see Step 2 of
the docs for Zulip's GitHub integration.
{!generate-integration-url.md!} - Instructs user how to get the URL for a
bot for a given integration. An example URL is generated automatically for
every incoming webhook by using attributes in the IncomingWebhookIntegration class
in zerver/lib/integrations.py.
Note: If special configuration is required to set up the URL and you can't
use these macros, be sure to use the {{ api_url }} template variable, so
that your integration documentation will provide the correct URL for whatever
server it is deployed on.
{!congrats.md!} macro - Inserts congratulatory lines signifying the
successful setup of a given integration. This macro is usually used at
the end of the documentation, right before the sample message screenshot.
For an example rendering, see the end of
the docs for Zulip's GitHub integration.
{!event-filtering-additional-feature.md!} macro - If a webhook integration
supports event filtering, then this adds a section with the specific
events that can be filtered for the integration. Should be included in
the documentation if all_event_types is set in the webhook integration
view. For an example see, the Filtering incoming events section in
Zulip's GitLab integration.
{!download-python-bindings.md!} macro - Links to Zulip's
API page to download and install Zulip's
API bindings. This macro is usually used in non-webhook integration docs under
templates/zerver/integrations/<integration_name>.md. For an example
rendering, see Step 3 of
the docs for Zulip's Codebase integration.
{!change-zulip-config-file.md!} macro - Instructs users to create a bot and
specify said bot's credentials in the config file for a given non-webhook
integration. This macro is usually used in non-webhook integration docs under
templates/zerver/integrations/<integration_name>.md. For an example
rendering, see Step 4 of
the docs for Zulip's Codebase integration.
{!webhook-url-with-bot-email.md!} - Used in certain non-webhook integrations
to generate URLs of the form:
https://bot_email:[email protected]/api/v1/external/beanstalk
For an example rendering, see Zulip's Beanstalk integration.
For the vast majority of integrations, you should just copy the docs for a similar integration and edit it. Basecamp is a good one to copy.
At a high level, the goals are for the instructions to feel simple, be easy to follow, and be easy to maintain. Easier said than done, but here are a few concrete guidelines.
Most doc files should start with a generic sentence about the
integration, for example, "Get webhook name notifications in Zulip!"
A typical doc will then have the following steps.
create-channel macro. This step should be omitted if the
integration only supports notifications via direct messages.create-an-incoming-webhook and
generate-integration-url macros.Lastly, end with the congrats.md macro and a screenshot of a sample message
within Zulip.
Screenshots are hard to maintain, so we generally err on the side of not including screenshots. That being said, screenshots may be used to aid the process if the third-party UI is confusing or a specific UI element is hard to find. A few things to keep in mind:
Zulip's Markdown processor allows you to include several special features in your documentation to help improve its readability:
Since raw HTML is supported in Markdown, you can include arbitrary HTML/CSS in your documentation as needed.
Code blocks allow you to highlight syntax, similar to Zulip's own Markdown.
Anchor tags can be used to link to headers in other documents.
Inline icons are used to refer to features in the Zulip UI.
Utilize macros to limit repeated content in the documentation.
Create special highlight warning blocks using tips and warnings.
Format instructions with tabs using Markdown tab switcher.
See icons documentation. Icons should always be referred to with their in-app tooltip or a brief action name, not the name of the icon in the code.
A tip is any suggestion for the user that is not part of the main set of instructions. For instance, it may address a common problem users may encounter while following the instructions, or point to an option for power users.
!!! tip ""
If you want notifications for issues, as well as events, you can
scroll down to **Webhooks** on the same page, and toggle the
**issue** checkbox.
A keyboard tip is a note for users to let them know that the same action can also be accomplished via a keyboard shortcut.
!!! keyboard_tip ""
Use <kbd>D</kbd> to bring up your list of drafts.
A warning is a note on what happens when there is some kind of problem. Tips are more common than warnings.
!!! warn ""
**Note**: Zulip also supports configuring this integration as a
webhook in Sentry.
All tips/warnings should appear inside tip/warning blocks. There should be only one tip/warning inside each block, and they usually should be formatted as a continuation of a numbered step.
Our Markdown processor supports easily creating a tab switcher widget design to easily show the instructions for different languages in API docs, etc. To create a tab switcher, write:
{start_tabs}
{tab|python}
# First tab's content
{tab|js}
# Second tab's content
{tab|curl}
# Third tab's content
{end_tabs}
The tab identifiers (e.g., python above) and their mappings to
the tabs' labels are declared in
zerver/lib/markdown/tabbed_sections.py.
This widget can also be used just to create a nice box around a set of instructions (example) by only declaring a single tab, which is often used for the main set of instructions for setting up an integration.