diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index ac734f9639..63a0895d5a 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -820,14 +820,15 @@ def do_send_messages(messages_maybe_none): if user_profile.bot_type != UserProfile.OUTGOING_WEBHOOK_BOT: continue - # Currently, we only support mentions as triggers, but - # this code structure should make it easy to add more. - + # Mention triggers, primarily for stream messages if user_profile.id in mentioned_ids: trigger = "mention" - + # PM triggers for personal and huddle messsages + if message['message'].recipient.type != Recipient.STREAM: + trigger = "private_message" if trigger is None: continue + message['message'].outgoing_webhook_bot_triggers.append({ 'trigger': trigger, 'user_profile': user_profile, diff --git a/zerver/tests/test_outgoing_webhook_system.py b/zerver/tests/test_outgoing_webhook_system.py index be83873f31..5560166dec 100644 --- a/zerver/tests/test_outgoing_webhook_system.py +++ b/zerver/tests/test_outgoing_webhook_system.py @@ -3,7 +3,7 @@ from __future__ import absolute_import from __future__ import print_function import mock -from typing import Any, Union, Mapping, Callable +from typing import Any, Union, Mapping, Callable, Text, List from zerver.lib.test_classes import ZulipTestCase @@ -110,3 +110,87 @@ class TestMentionMessageTrigger(ZulipTestCase): self.subscribe_to_stream(self.bot_profile.email, "Denmark") self.send_message(self.user_profile.email, "Denmark", Recipient.STREAM, self.content) self.assertTrue(mock_queue_json_publish.called) + +class PersonalMessageTriggersTest(ZulipTestCase): + + def setUp(self): + # type: () -> None + user_profile = self.example_user("othello") + self.bot_user = do_create_user(email="testvabs-bot@zulip.com", + password="test", + realm=get_realm_by_email_domain("zulip.com"), + full_name="The Test Bot", + short_name="bot", + bot_type=UserProfile.OUTGOING_WEBHOOK_BOT, + bot_owner=user_profile) + self.temp_bot = do_create_user(email="temp-bot@zulip.com", + password="temp", + realm=get_realm_by_email_domain("zulip.com"), + full_name="The Temp test Bot", + short_name="tempbot", + bot_type=UserProfile.OUTGOING_WEBHOOK_BOT, + bot_owner=user_profile) + + def test_no_trigger_on_stream_message(self): + # type: () -> None + sender_email = "othello@zulip.com" + recipients = "Denmark" + message_type = Recipient.STREAM + with mock.patch('zerver.lib.actions.queue_json_publish') as queue_json_publish: + self.send_message(sender_email, recipients, message_type) + self.assertFalse(queue_json_publish.called) + + def test_no_trigger_on_message_by_bot(self): + # type: () -> None + sender_email = "testvabs-bot@zulip.com" + recipients = "othello@zulip.com" + message_type = Recipient.PERSONAL + + with mock.patch('zerver.lib.actions.queue_json_publish') as queue_json_publish: + self.send_message(sender_email, recipients, message_type) + self.assertFalse(queue_json_publish.called) + + @mock.patch('zerver.lib.actions.queue_json_publish') + def test_trigger_on_private_message_by_user(self, mock_queue_json_publish): + # type: (mock.Mock) -> None + sender_email = "othello@zulip.com" + recipients = "testvabs-bot@zulip.com" + message_type = Recipient.PERSONAL + profile_id = self.bot_user.id + + def check_values_passed(queue_name, trigger_event, x): + # type: (Any, Union[Mapping[Any, Any], Any], Callable[[Any], None]) -> None + self.assertEqual(queue_name, "outgoing_webhooks") + self.assertEqual(trigger_event["user_profile_id"], profile_id) + self.assertEqual(trigger_event["trigger"], "private_message") + self.assertEqual(trigger_event["failed_tries"], 0) + self.assertEqual(trigger_event["message"]["sender_email"], sender_email) + self.assertEqual(trigger_event["message"]["display_recipient"][0]["email"], sender_email) + self.assertEqual(trigger_event["message"]["display_recipient"][1]["email"], recipients) + self.assertEqual(trigger_event["message"]["type"], u'private') + + mock_queue_json_publish.side_effect = check_values_passed + self.send_message(sender_email, recipients, message_type, subject='', content='test') + self.assertTrue(mock_queue_json_publish.called) + + @mock.patch('zerver.lib.actions.queue_json_publish') + def test_trigger_on_huddle_message_by_user(self, mock_queue_json_publish): + # type: (mock.Mock) -> None + sender_email = "othello@zulip.com" + recipients = [u"testvabs-bot@zulip.com", u"temp-bot@zulip.com"] + message_type = Recipient.HUDDLE + profile_ids = [self.bot_user.id, self.temp_bot.id] + + def check_values_passed(queue_name, trigger_event, x): + # type: (Any, Union[Mapping[Any, Any], Any], Callable[[Any], None]) -> None + self.assertEqual(queue_name, "outgoing_webhooks") + self.assertIn(trigger_event["user_profile_id"], profile_ids) + profile_ids.remove(trigger_event["user_profile_id"]) + self.assertEqual(trigger_event["trigger"], "private_message") + self.assertEqual(trigger_event["failed_tries"], 0) + self.assertEqual(trigger_event["message"]["sender_email"], sender_email) + self.assertEqual(trigger_event["message"]["type"], u'private') + + mock_queue_json_publish.side_effect = check_values_passed + self.send_message(sender_email, recipients, message_type, subject='', content='test') + self.assertEqual(mock_queue_json_publish.call_count, 2)