mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 15:03:34 +00:00
webhooks: Support configuring destination stream by id.
This commit is contained in:
@@ -2680,6 +2680,20 @@ def check_send_stream_message(
|
|||||||
return do_send_messages([message])[0]
|
return do_send_messages([message])[0]
|
||||||
|
|
||||||
|
|
||||||
|
def check_send_stream_message_by_id(
|
||||||
|
sender: UserProfile,
|
||||||
|
client: Client,
|
||||||
|
stream_id: int,
|
||||||
|
topic: str,
|
||||||
|
body: str,
|
||||||
|
realm: Optional[Realm] = None,
|
||||||
|
) -> int:
|
||||||
|
addressee = Addressee.for_stream_id(stream_id, topic)
|
||||||
|
message = check_message(sender, client, addressee, body, realm)
|
||||||
|
|
||||||
|
return do_send_messages([message])[0]
|
||||||
|
|
||||||
|
|
||||||
def check_send_private_message(
|
def check_send_private_message(
|
||||||
sender: UserProfile, client: Client, receiving_user: UserProfile, body: str
|
sender: UserProfile, client: Client, receiving_user: UserProfile, body: str
|
||||||
) -> int:
|
) -> int:
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from django.utils.translation import gettext as _
|
|||||||
from zerver.lib.actions import (
|
from zerver.lib.actions import (
|
||||||
check_send_private_message,
|
check_send_private_message,
|
||||||
check_send_stream_message,
|
check_send_stream_message,
|
||||||
|
check_send_stream_message_by_id,
|
||||||
send_rate_limited_pm_notification_to_bot_owner,
|
send_rate_limited_pm_notification_to_bot_owner,
|
||||||
)
|
)
|
||||||
from zerver.lib.exceptions import ErrorCode, JsonableError, StreamDoesNotExistError
|
from zerver.lib.exceptions import ErrorCode, JsonableError, StreamDoesNotExistError
|
||||||
@@ -114,7 +115,7 @@ def check_send_webhook_message(
|
|||||||
# double escape their URLs in a manner that escaped space characters
|
# double escape their URLs in a manner that escaped space characters
|
||||||
# (%20) are never properly decoded. We work around that by making sure
|
# (%20) are never properly decoded. We work around that by making sure
|
||||||
# that the URL parameters are decoded on our end.
|
# that the URL parameters are decoded on our end.
|
||||||
if unquote_url_parameters:
|
if stream is not None and unquote_url_parameters:
|
||||||
stream = unquote(stream)
|
stream = unquote(stream)
|
||||||
|
|
||||||
if user_specified_topic is not None:
|
if user_specified_topic is not None:
|
||||||
@@ -123,7 +124,12 @@ def check_send_webhook_message(
|
|||||||
topic = unquote(topic)
|
topic = unquote(topic)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
check_send_stream_message(user_profile, request.client, stream, topic, body)
|
if stream.isdecimal():
|
||||||
|
check_send_stream_message_by_id(
|
||||||
|
user_profile, request.client, int(stream), topic, body
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
check_send_stream_message(user_profile, request.client, stream, topic, body)
|
||||||
except StreamDoesNotExistError:
|
except StreamDoesNotExistError:
|
||||||
# A PM will be sent to the bot_owner by check_message, notifying
|
# A PM will be sent to the bot_owner by check_message, notifying
|
||||||
# that the webhook bot just tried to send a message to a non-existent
|
# that the webhook bot just tried to send a message to a non-existent
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from unittest.mock import MagicMock, patch
|
|||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
|
|
||||||
from zerver.decorator import webhook_view
|
from zerver.decorator import webhook_view
|
||||||
|
from zerver.lib.actions import do_rename_stream
|
||||||
from zerver.lib.exceptions import InvalidJSONError, JsonableError
|
from zerver.lib.exceptions import InvalidJSONError, JsonableError
|
||||||
from zerver.lib.send_email import FromAddress
|
from zerver.lib.send_email import FromAddress
|
||||||
from zerver.lib.test_classes import WebhookTestCase, ZulipTestCase
|
from zerver.lib.test_classes import WebhookTestCase, ZulipTestCase
|
||||||
@@ -134,6 +135,43 @@ class WebhooksCommonTestCase(ZulipTestCase):
|
|||||||
self.assertEqual(djangoified_headers, expected_djangoified_headers)
|
self.assertEqual(djangoified_headers, expected_djangoified_headers)
|
||||||
|
|
||||||
|
|
||||||
|
class WebhookURLConfigurationTestCase(WebhookTestCase):
|
||||||
|
STREAM_NAME = "helloworld"
|
||||||
|
WEBHOOK_DIR_NAME = "helloworld"
|
||||||
|
URL_TEMPLATE = "/api/v1/external/helloworld?stream={stream}&api_key={api_key}"
|
||||||
|
|
||||||
|
def setUp(self) -> None:
|
||||||
|
super().setUp()
|
||||||
|
stream = self.subscribe(self.test_user, self.STREAM_NAME)
|
||||||
|
|
||||||
|
# In actual webhook tests, we will not need to use stream id.
|
||||||
|
# We assign stream id to STREAM_NAME for testing URL configuration only.
|
||||||
|
self.STREAM_NAME = str(stream.id)
|
||||||
|
do_rename_stream(stream, "helloworld_renamed", self.test_user)
|
||||||
|
|
||||||
|
self.url = self.build_webhook_url()
|
||||||
|
|
||||||
|
def test_trigger_stream_message_by_id(self) -> None:
|
||||||
|
# check_webhook cannot be used here as it
|
||||||
|
# subscribes the test user to self.STREAM_NAME
|
||||||
|
payload = self.get_body("hello")
|
||||||
|
|
||||||
|
self.send_webhook_payload(
|
||||||
|
self.test_user, self.url, payload, content_type="application/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
expected_topic = "Hello World"
|
||||||
|
expected_message = "Hello! I am happy to be here! :smile:\nThe Wikipedia featured article for today is **[Marilyn Monroe](https://en.wikipedia.org/wiki/Marilyn_Monroe)**"
|
||||||
|
|
||||||
|
msg = self.get_last_message()
|
||||||
|
self.assert_stream_message(
|
||||||
|
message=msg,
|
||||||
|
stream_name="helloworld_renamed",
|
||||||
|
topic_name=expected_topic,
|
||||||
|
content=expected_message,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MissingEventHeaderTestCase(WebhookTestCase):
|
class MissingEventHeaderTestCase(WebhookTestCase):
|
||||||
STREAM_NAME = "groove"
|
STREAM_NAME = "groove"
|
||||||
URL_TEMPLATE = "/api/v1/external/groove?stream={stream}&api_key={api_key}"
|
URL_TEMPLATE = "/api/v1/external/groove?stream={stream}&api_key={api_key}"
|
||||||
|
|||||||
Reference in New Issue
Block a user