From b6afa030c5854bfa69687d6c0ed86579fe2fdfed Mon Sep 17 00:00:00 2001 From: Ricky Date: Wed, 7 Mar 2018 20:52:01 +0530 Subject: [PATCH] bots/flock: Add flock bot. --- .../zulip_bots/bots/flock/assests/1.png | Bin 0 -> 41067 bytes zulip_bots/zulip_bots/bots/flock/doc.md | 27 +++++ .../fixtures/test_message_send_failed.json | 19 ++++ .../fixtures/test_message_send_success.json | 17 +++ .../fixtures/test_no_recipient_found.json | 15 +++ zulip_bots/zulip_bots/bots/flock/flock.conf | 2 + zulip_bots/zulip_bots/bots/flock/flock.py | 98 ++++++++++++++++++ .../zulip_bots/bots/flock/requirements.txt | 1 + .../zulip_bots/bots/flock/test_flock.py | 62 +++++++++++ 9 files changed, 241 insertions(+) create mode 100644 zulip_bots/zulip_bots/bots/flock/assests/1.png create mode 100644 zulip_bots/zulip_bots/bots/flock/doc.md create mode 100644 zulip_bots/zulip_bots/bots/flock/fixtures/test_message_send_failed.json create mode 100644 zulip_bots/zulip_bots/bots/flock/fixtures/test_message_send_success.json create mode 100644 zulip_bots/zulip_bots/bots/flock/fixtures/test_no_recipient_found.json create mode 100644 zulip_bots/zulip_bots/bots/flock/flock.conf create mode 100644 zulip_bots/zulip_bots/bots/flock/flock.py create mode 100644 zulip_bots/zulip_bots/bots/flock/requirements.txt create mode 100644 zulip_bots/zulip_bots/bots/flock/test_flock.py diff --git a/zulip_bots/zulip_bots/bots/flock/assests/1.png b/zulip_bots/zulip_bots/bots/flock/assests/1.png new file mode 100644 index 0000000000000000000000000000000000000000..7bb64a791c73819f6eb032e8eeb6ae77baecf07d GIT binary patch literal 41067 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 str: + for obj in res: + if to == obj['firstName']: + return obj['id'] + +# Returns User's ID, if not found, returns error message. +def get_recipient_id(content: str, config: Dict[str, str]) -> str: + token = config['token'] + content_pieces = content.split(':') + to = content_pieces[0].strip() + payload = { + 'token': token + } + + try: + res = requests.get(USERS_LIST_URL, params=payload) + except ConnectionError as e: + logging.exception(str(e)) + return "Uh-Oh, couldn't process the request \ +right now.\nPlease try again later" + + res = res.json() + to = find_recipient(res, to) + if to is None: + return "No user found. Make sure you typed it correctly." + else: + return to + +# This handles the message sending work. +def get_flock_response(content: str, config: Dict[str, str]) -> str: + token = config['token'] + content_pieces = content.split(':') + to = content_pieces[0].strip() + message = content_pieces[1].strip() + + to = get_recipient_id(content, config) + if len(str(to)) > 30: + return to + + payload = { + 'to': to, + 'text': message, + 'token': token + } + try: + r = requests.get(SEND_MESSAGE_URL, params=payload) + except ConnectionError as e: + logging.exception(str(e)) + return "Uh-Oh, couldn't process the request \ +right now.\nPlease try again later" + + r = r.json() + if "uid" in r: + return "Message sent." + else: + return "Message sending failed :slightly_frowning_face:. Please try again." + +def get_flock_bot_response(content: str, config: Dict[str, str]) -> None: + content = content.strip() + if content == '' or content == 'help': + return help_message + else: + result = get_flock_response(content, config) + return result + +class FlockHandler(object): + ''' + This is flock bot. Now you can send messages to any of your + flock user without having to leave Zulip. + ''' + + def initialize(self, bot_handler: Any) -> None: + self.config_info = bot_handler.get_config_info('flock') + + def usage(self) -> str: + return '''Hello from Flock Bot. You can send messages to any Flock user +right from Zulip.''' + + def handle_message(self, message: Dict[str, str], bot_handler: Any) -> None: + response = get_flock_bot_response(message['content'], self.config_info) + bot_handler.send_reply(message, response) + +handler_class = FlockHandler diff --git a/zulip_bots/zulip_bots/bots/flock/requirements.txt b/zulip_bots/zulip_bots/bots/flock/requirements.txt new file mode 100644 index 0000000..f229360 --- /dev/null +++ b/zulip_bots/zulip_bots/bots/flock/requirements.txt @@ -0,0 +1 @@ +requests diff --git a/zulip_bots/zulip_bots/bots/flock/test_flock.py b/zulip_bots/zulip_bots/bots/flock/test_flock.py new file mode 100644 index 0000000..15dd3a5 --- /dev/null +++ b/zulip_bots/zulip_bots/bots/flock/test_flock.py @@ -0,0 +1,62 @@ +from unittest.mock import patch +from zulip_bots.test_lib import BotTestCase +from requests.exceptions import ConnectionError + +class TestFlockBot(BotTestCase): + bot_name = "flock" + normal_config = {"token": "12345"} + + message_config = { + "token": "12345", + "text": "Ricky: test message", + "to": "u:somekey" + } + + help_message = ''' +You can send messages to any Flock user associated with your account from Zulip. +*Syntax*: **@botname to: message** where `to` is **firstName** of recipient. +''' + + def test_bot_responds_to_empty_message(self) -> None: + self.verify_reply('', self.help_message) + + def test_help_message(self) -> None: + self.verify_reply('', self.help_message) + + def test_fetch_id_connection_error(self) -> None: + with self.mock_config_info(self.normal_config), \ + patch('requests.get', side_effect=ConnectionError()), \ + patch('logging.exception'): + self.verify_reply('tyler: Hey tyler', "Uh-Oh, couldn\'t process the request \ +right now.\nPlease try again later") + + def test_response_connection_error(self) -> None: + with self.mock_config_info(self.message_config), \ + patch('requests.get', side_effect=ConnectionError()), \ + patch('logging.exception'): + self.verify_reply('Ricky: test message', "Uh-Oh, couldn\'t process the request \ +right now.\nPlease try again later") + + @patch('zulip_bots.bots.flock.flock.find_recipient') + def test_no_recipient_found(self, find_recipient: str) -> None: + bot_response = "No user found. Make sure you typed it correctly." + find_recipient.return_value = None + with self.mock_config_info(self.normal_config), \ + self.mock_http_conversation('test_no_recipient_found'): + self.verify_reply('david: hello', bot_response) + + @patch('zulip_bots.bots.flock.flock.get_recipient_id') + def test_message_send_success(self, get_recipient_id: str) -> None: + bot_response = "Message sent." + get_recipient_id.return_value = "u:userid" + with self.mock_config_info(self.normal_config), \ + self.mock_http_conversation('test_message_send_success'): + self.verify_reply('Rishabh: hi there', bot_response) + + @patch('zulip_bots.bots.flock.flock.get_recipient_id') + def test_message_send_failed(self, get_recipient_id: str) -> None: + bot_response = "Message sending failed :slightly_frowning_face:. Please try again." + get_recipient_id.return_value = "u:invalid" + with self.mock_config_info(self.normal_config), \ + self.mock_http_conversation('test_message_send_failed'): + self.verify_reply('Rishabh: hi there', bot_response)