> ## Documentation Index
> Fetch the complete documentation index at: https://docs.novu.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Zulip Chat Integration with Novu

> Connect Zulip to Novu to send chat notifications through workflows. Create a bot in Zulip, generate the webhook URL, and store credentials for stream delivery.

Zulip does not need any API Key or client ID to push messages in it. All it needs is the webhook URL of the channel you want to send messages to. That itself acts as the credential.

Similar to Discord, the credential for this provider needs to be stored in the subscriber entity.

## Getting a Zulip webhook URL

* Sign up or Login to your Zulip account.

* Click on the Settings icon in the top right corner of the screen, and then click "Personal settings" from the drop-down menu.

<img src="https://mintcdn.com/novu-c5de82d9/GgsvkDH1Mx055NRY/images/channels-and-providers/chat/zulip/step_01.png?fit=max&auto=format&n=GgsvkDH1Mx055NRY&q=85&s=0c2eea24eff75299f37ba5436d5b6890" alt="Zulip settings menu" width="1920" height="1080" data-path="images/channels-and-providers/chat/zulip/step_01.png" />

* Click "Add a new bot" button in "Bots" tab.

<img src="https://mintcdn.com/novu-c5de82d9/GgsvkDH1Mx055NRY/images/channels-and-providers/chat/zulip/step_02.png?fit=max&auto=format&n=GgsvkDH1Mx055NRY&q=85&s=07549d7edf037ac5cea4ad727f4a583e" alt="Add new bot button" width="1920" height="1080" data-path="images/channels-and-providers/chat/zulip/step_02.png" />

* Set bot type as "Incoming webhook".

<img src="https://mintcdn.com/novu-c5de82d9/GgsvkDH1Mx055NRY/images/channels-and-providers/chat/zulip/step_03.png?fit=max&auto=format&n=GgsvkDH1Mx055NRY&q=85&s=1aca9f9d055acf81fc57b15b944bcdca" alt="Set bot type" width="1920" height="1080" data-path="images/channels-and-providers/chat/zulip/step_03.png" />

* Click the small link icon to generate webhook URL for provider. Set Integration as `Slack compatible webhook`, choose your channel and copy webhook URL.

<img src="https://mintcdn.com/novu-c5de82d9/GgsvkDH1Mx055NRY/images/channels-and-providers/chat/zulip/step_04.png?fit=max&auto=format&n=GgsvkDH1Mx055NRY&q=85&s=2b333a7214150420300eb6573d0e9857" alt="Generate webhook URL" width="1920" height="1080" data-path="images/channels-and-providers/chat/zulip/step_04.png" />

## Connecting our subscribers to Zulip

The URL generated above will be the target channel of a subscriber that you want to integrate with. To make this connection, you have to:

1. Copy the URL that you generated above

2. Update the subscriber credentials with this URL using the Zulip provider id. You can do this step by using the `@novu/api` library, as shown below:

## Update credential webhookUrl

<Tabs>
  <Tab title="Node.js">
    ```typescript theme={null}
    import { Novu } from '@novu/api';
    import { ChatOrPushProviderEnum } from "@novu/api/models/components";

    const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>" });

    await novu.subscribers.credentials.update(
      {
        providerId: ChatOrPushProviderEnum.Zulip,
        integrationIdentifier: "zulip-MnGLxp8uy",
        credentials: { webhookUrl: "<WEBHOOK_URL>", },
      },
      "subscriberId"
    );
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import os
    import novu_py
    from novu_py import Novu

    with Novu(secret_key=os.getenv("NOVU_SECRET_KEY", "")) as novu:
        novu.subscribers.credentials.update(
            subscriber_id="subscriberId",
            update_subscriber_channel_request_dto={
                "provider_id": novu_py.ChatOrPushProviderEnum.ZULIP,
                "credentials": {"webhookUrl": "<WEBHOOK_URL>"},
                "integration_identifier": "zulip-MnGLxp8uy",
            },
        )
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    import (
        "context"
        "os"

        novugo "github.com/novuhq/novu-go"
        "github.com/novuhq/novu-go/models/components"
    )

    s := novugo.New(novugo.WithSecurity(os.Getenv("NOVU_SECRET_KEY")))

    res, err := s.Subscribers.Credentials.Update(context.Background(), "subscriberId", components.UpdateSubscriberChannelRequestDto{
        ProviderID: components.ChatOrPushProviderEnumZulip,
            IntegrationIdentifier: novugo.String("zulip-MnGLxp8uy"),
        Credentials: components.ChannelCredentials{
            WebhookURL: novugo.String("<WEBHOOK_URL>"),
        },
    }, nil)
    ```
  </Tab>

  <Tab title="PHP">
    ```php theme={null}
    use novu;
    use novu\Models\Components;

    $sdk = novu\Novu::builder()->setSecurity('<NOVU_SECRET_KEY>')->build();

    $sdk->subscribersCredentials->update(
        subscriberId: 'subscriberId',
        updateSubscriberChannelRequestDto: new Components\UpdateSubscriberChannelRequestDto(
            providerId: Components\ChatOrPushProviderEnum::Zulip,
            integrationIdentifier: 'zulip-MnGLxp8uy',
            credentials: new Components\ChannelCredentials(
                webhookUrl: '<WEBHOOK_URL>',
            ),
        ),
    );
    ```
  </Tab>

  <Tab title=".NET">
    ```csharp theme={null}
    using Novu;
    using Novu.Models.Components;
    using System.Collections.Generic;

    var sdk = new NovuSDK(secretKey: "<NOVU_SECRET_KEY>");

    await sdk.Subscribers.Credentials.UpdateAsync(
        subscriberId: "subscriberId",
        updateSubscriberChannelRequestDto: new UpdateSubscriberChannelRequestDto() {
            ProviderId = ChatOrPushProviderEnum.Zulip,
            IntegrationIdentifier = "zulip-MnGLxp8uy",
            Credentials = new ChannelCredentials() {
                WebhookUrl = "<WEBHOOK_URL>",
            },
        });
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    import co.novu.Novu;
    import co.novu.models.components.*;
    import java.util.List;

    Novu novu = Novu.builder().secretKey("<NOVU_SECRET_KEY>").build();

    novu.subscribers().credentials().update()
        .subscriberId("subscriberId")
        .body(UpdateSubscriberChannelRequestDto.builder()
            .providerId(ChatOrPushProviderEnum.ZULIP)
                .integrationIdentifier("zulip-MnGLxp8uy")
            .credentials(ChannelCredentials.builder()
                .webhookUrl("<WEBHOOK_URL>")
                .build())
            .build())
        .call();
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -L -X PUT 'https://api.novu.co/v1/subscribers/<SUBSCRIBER_ID>/credentials' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: ApiKey <NOVU_SECRET_KEY>' \
    -d '{
      "providerId": "zulip",
      "credentials": {
        "webhookUrl": "<WEBHOOK_URL>"
      },
      "integrationIdentifier": "zulip-MnGLxp8uy"
    }'
    ```
  </Tab>
</Tabs>

* `subscriberId` is a custom identifier used when identifying your users within the Novu platform.
* `providerId` is a unique provider identifier. We recommend using our ChatOrPushProviderEnum to specify the provider.
* The third parameter is the credentials object, in this case, we use the `webhookUrl` property to specify the Zulip channel webhook URL or by calling the `Update Subscriber Credentials` endpoint on Novu API. Check endpoint details [here](/api-reference/subscribers/update-provider-credentials).

3. You are all set up and ready to send your first chat message via our \`@novu/api package or directly using the REST API.
