bots/flock: Add flock bot.
This commit is contained in:
parent
bb4c9c9bdb
commit
b6afa030c5
BIN
zulip_bots/zulip_bots/bots/flock/assests/1.png
Normal file
BIN
zulip_bots/zulip_bots/bots/flock/assests/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
27
zulip_bots/zulip_bots/bots/flock/doc.md
Normal file
27
zulip_bots/zulip_bots/bots/flock/doc.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Flock Bot
|
||||
|
||||
With [Flock](https://flock.com/) bot, you can send messages to any of your
|
||||
flock contact without having to leave Zulip.
|
||||
|
||||
Sending messages to a user is quite easy, syntax is:
|
||||
`@botname recipient_name: hello`
|
||||
where `recipient_name` is name of recipient and `hello` is the sample message.
|
||||
|
||||
## Configuration
|
||||
|
||||
1. Before running Flock bot, you'll need a `token`. In order to get `token`,
|
||||
Go to [Flock apps](https://dev.flock.com/apps) and create an app.
|
||||
After successful installation, you'll get an `token` in response from servers.
|
||||
|
||||
1. Once you have `token`, you should supply it in `flock.conf` file.
|
||||
|
||||
## Usage
|
||||
|
||||
Run this bot as described in
|
||||
[here](https://zulipchat.com/api/running-bots#running-a-bot).
|
||||
|
||||
You can use this bot in one easy step:
|
||||
|
||||
`@botname recipient_firstName: message`
|
||||
|
||||
For help, do `@botname help`.
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"request": {
|
||||
"api_url": "https://api.flock.co/v1/chat.sendMessage",
|
||||
"method": "GET",
|
||||
"params": {
|
||||
"token": "12345",
|
||||
"text": "hi there",
|
||||
"to": "u:invalid"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"error": "InvalidParameter",
|
||||
"description": "A required parameter for the method call is missing or invalid",
|
||||
"parameter": "to"
|
||||
},
|
||||
"response-headers": {
|
||||
"content-type": "application/json; charset=utf-8"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"request": {
|
||||
"api_url": "https://api.flock.co/v1/chat.sendMessage",
|
||||
"method": "GET",
|
||||
"params": {
|
||||
"token": "12345",
|
||||
"to": "u:userid",
|
||||
"text": "hi there"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"uid": "15207048523"
|
||||
},
|
||||
"response-headers": {
|
||||
"content-type": "application/json; charset=utf-8"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"request": {
|
||||
"api_url": "https://api.flock.co/v1/roster.listContacts",
|
||||
"method": "GET",
|
||||
"params": {
|
||||
"token": "12345"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"error": "No user found. Make sure you typed it correctly."
|
||||
},
|
||||
"response-headers": {
|
||||
"content-type": "application/json; charset=utf-8"
|
||||
}
|
||||
}
|
2
zulip_bots/zulip_bots/bots/flock/flock.conf
Normal file
2
zulip_bots/zulip_bots/bots/flock/flock.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
[flock]
|
||||
token=12345
|
98
zulip_bots/zulip_bots/bots/flock/flock.py
Normal file
98
zulip_bots/zulip_bots/bots/flock/flock.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
import logging
|
||||
import requests
|
||||
from typing import Any, Dict
|
||||
from requests.exceptions import ConnectionError
|
||||
|
||||
USERS_LIST_URL = 'https://api.flock.co/v1/roster.listContacts'
|
||||
SEND_MESSAGE_URL = 'https://api.flock.co/v1/chat.sendMessage'
|
||||
|
||||
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.
|
||||
'''
|
||||
|
||||
# Matches the recipient name provided by user with list of users in his contacts.
|
||||
# If matches, returns the matched User's ID
|
||||
def find_recipient(res: str, to: str) -> 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
|
1
zulip_bots/zulip_bots/bots/flock/requirements.txt
Normal file
1
zulip_bots/zulip_bots/bots/flock/requirements.txt
Normal file
|
@ -0,0 +1 @@
|
|||
requests
|
62
zulip_bots/zulip_bots/bots/flock/test_flock.py
Normal file
62
zulip_bots/zulip_bots/bots/flock/test_flock.py
Normal file
|
@ -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)
|
Loading…
Reference in a new issue