interactive bots: Create yoda translator bot
This commit is contained in:
parent
082fbf631f
commit
3574017297
79
contrib_bots/lib/readme-yoda-bot.md
Normal file
79
contrib_bots/lib/readme-yoda-bot.md
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
# Overview
|
||||||
|
|
||||||
|
This is the documentation for how to set up and run the yoda_bot. (`yoda_bot.py`)
|
||||||
|
|
||||||
|
This directory contains library code for running Zulip
|
||||||
|
bots that react to messages sent by users.
|
||||||
|
|
||||||
|
This bot will allow users to translate a sentence into 'Yoda speak'.
|
||||||
|
It looks for messages starting with '@yoda'. You will need to have a
|
||||||
|
Mashape API key. Please see instructions for getting one below.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
This bot uses the python library `unirest` which is not a
|
||||||
|
dependency of Zulip. To use this module, you will have to
|
||||||
|
install it in your local machine. In your terminal, enter
|
||||||
|
the following command:
|
||||||
|
* $ sudo pip install unirest --upgrade
|
||||||
|
Note:
|
||||||
|
|
||||||
|
You might have to use `pip3` if you are using python 3.
|
||||||
|
The install command would also download any dependency
|
||||||
|
required by `unirest`.
|
||||||
|
|
||||||
|
Before running this bot, make sure to get a Mashape API Key.
|
||||||
|
Go to this link:
|
||||||
|
<https://market.mashape.com/ismaelc/yoda-speak/overview>
|
||||||
|
This is the API that powers the `yoda_bot`. You can read more about it
|
||||||
|
on this page.
|
||||||
|
|
||||||
|
![yoda api overview](yoda-speak-api.png)
|
||||||
|
|
||||||
|
Click on the **Sign Up Free** button at the top and create
|
||||||
|
an account. Then click on the **Documentation** tab. Scroll down to the
|
||||||
|
bottom, and click on the **Test Endpoint** button.
|
||||||
|
This will add the Yoda Speak API to your default application. You can
|
||||||
|
also add it to a different application if you wish. Now click on the
|
||||||
|
**Applications** tab at the top. Select the application that you added
|
||||||
|
the Yoda Speak API to. Click on the blue **GET THE KEYS** button.
|
||||||
|
|
||||||
|
On the pop-up that comes up, click on the **COPY** button.
|
||||||
|
This is your Mashape API Key. It is used
|
||||||
|
to authenticate. Store it in the `yoda_api_key.txt` file.
|
||||||
|
|
||||||
|
The `yoda_api_key.txt` file should be located at `~/yoda_api_key.txt`.
|
||||||
|
|
||||||
|
Example input:
|
||||||
|
|
||||||
|
@yoda You will learn how to speak like me someday.
|
||||||
|
|
||||||
|
If you need help while the bot is running just input `@yoda help`.
|
||||||
|
|
||||||
|
## Running the bot
|
||||||
|
|
||||||
|
Here is an example of running the "yoda_bot" bot from
|
||||||
|
inside a Zulip repo:
|
||||||
|
|
||||||
|
cd ~/zulip/contrib_bots
|
||||||
|
./run.py lib/yoda_bot.py --config-file ~/.zuliprc-prod
|
||||||
|
|
||||||
|
Once the bot code starts running, you will see a
|
||||||
|
message explaining how to use the bot, as well as
|
||||||
|
some log messages. You can use the `--quiet` option
|
||||||
|
to suppress some of the informational messages.
|
||||||
|
|
||||||
|
The bot code will run continuously until you kill them with
|
||||||
|
control-C (or otherwise).
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
For this document we assume you have some prior experience
|
||||||
|
with using the Zulip API, but here is a quick review of
|
||||||
|
what a `.zuliprc` files looks like. You can connect to the
|
||||||
|
API as your own human user, or you can go into the Zulip settings
|
||||||
|
page to create a user-owned bot.
|
||||||
|
|
||||||
|
[api]
|
||||||
|
email=someuser@example.com
|
||||||
|
key=<your api key>
|
||||||
|
site=https://zulip.somewhere.com
|
BIN
contrib_bots/lib/yoda-speak-api.png
Executable file
BIN
contrib_bots/lib/yoda-speak-api.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 229 KiB |
166
contrib_bots/lib/yoda_bot.py
Normal file
166
contrib_bots/lib/yoda_bot.py
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
# See readme-yoda-bot.md for instructions on running this code.
|
||||||
|
|
||||||
|
"""
|
||||||
|
This bot uses the python library `unirest` which is not a
|
||||||
|
dependency of Zulip. To use this module, you will have to
|
||||||
|
install it in your local machine. In your terminal, enter
|
||||||
|
the following command:
|
||||||
|
$ sudo pip install unirest --upgrade
|
||||||
|
Note:
|
||||||
|
* You might have to use `pip3` if you are using python 3.
|
||||||
|
* The install command would also download any dependency
|
||||||
|
required by `unirest`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import ssl
|
||||||
|
import sys
|
||||||
|
|
||||||
|
try:
|
||||||
|
import unirest
|
||||||
|
except ImportError:
|
||||||
|
logging.error("Dependency missing!!\n%s" % (__doc__))
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
HELP_MESSAGE = '''
|
||||||
|
This bot allows users to translate a sentence into
|
||||||
|
'Yoda speak'.
|
||||||
|
Users should preface messages with '@yoda'.
|
||||||
|
|
||||||
|
Before running this, make sure to get a Mashape Api token.
|
||||||
|
Instructions are in the 'readme-yoda-bot.md' file.
|
||||||
|
Store it in the 'yoda_api_key.txt' file.
|
||||||
|
The 'yoda_api_key.txt' file should be located at '~/yoda_api_key.txt'.
|
||||||
|
Example input:
|
||||||
|
@yoda You will learn how to speak like me someday.
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
class ApiKeyError(Exception):
|
||||||
|
'''raise this when there is an error with the Mashape Api Key'''
|
||||||
|
|
||||||
|
|
||||||
|
class YodaSpeakHandler(object):
|
||||||
|
'''
|
||||||
|
This bot will allow users to translate a sentence into 'Yoda speak'.
|
||||||
|
It looks for messages starting with '@yoda'.
|
||||||
|
'''
|
||||||
|
|
||||||
|
def usage(self):
|
||||||
|
return '''
|
||||||
|
This bot will allow users to translate a sentence into
|
||||||
|
'Yoda speak'.
|
||||||
|
Users should preface messages with '@yoda'.
|
||||||
|
|
||||||
|
Before running this, make sure to get a Mashape Api token.
|
||||||
|
Instructions are in the 'readme-yoda-bot.md' file.
|
||||||
|
Store it in the 'yoda_api_key.txt' file.
|
||||||
|
The 'yoda_api_key.txt' file should be located at '~/yoda_api_key.txt'.
|
||||||
|
Example input:
|
||||||
|
@yoda You will learn how to speak like me someday.
|
||||||
|
'''
|
||||||
|
|
||||||
|
def triage_message(self, message):
|
||||||
|
# return True iff we want to (possibly) response to this message
|
||||||
|
|
||||||
|
original_content = message['content']
|
||||||
|
|
||||||
|
return original_content.startswith('@yoda')
|
||||||
|
|
||||||
|
def handle_message(self, message, client, state_handler):
|
||||||
|
original_content = message['content']
|
||||||
|
stream = message['display_recipient']
|
||||||
|
subject = message['subject']
|
||||||
|
|
||||||
|
# this handles the message if its starts with @yoda
|
||||||
|
if original_content.startswith('@yoda'):
|
||||||
|
handle_input(client, original_content, stream, subject)
|
||||||
|
|
||||||
|
handler_class = YodaSpeakHandler
|
||||||
|
|
||||||
|
|
||||||
|
def send_to_yoda_api(sentence, api_key):
|
||||||
|
# function for sending sentence to api
|
||||||
|
|
||||||
|
response = unirest.get("https://yoda.p.mashape.com/yoda?sentence=" + sentence,
|
||||||
|
headers={
|
||||||
|
"X-Mashape-Key": api_key,
|
||||||
|
"Accept": "text/plain"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.code == 200:
|
||||||
|
return response.body
|
||||||
|
if response.code == 403:
|
||||||
|
raise ApiKeyError
|
||||||
|
else:
|
||||||
|
error_message = response.body['message']
|
||||||
|
logging.error(error_message)
|
||||||
|
error_code = response.code
|
||||||
|
error_message = error_message + 'Error code: ' + error_code +\
|
||||||
|
' Did you follow the instructions in the `readme-yoda-bot.md` file?'
|
||||||
|
return error_message
|
||||||
|
|
||||||
|
|
||||||
|
def format_input(original_content):
|
||||||
|
# replaces the '@yoda' with nothing, so that '@yoda' doesn't get sent to the api
|
||||||
|
message_content = original_content.replace('@yoda', '')
|
||||||
|
# gets rid of whitespace around the edges, so that they aren't a problem in the future
|
||||||
|
message_content = message_content.strip()
|
||||||
|
# replaces all spaces with '+' to be in the format the api requires
|
||||||
|
sentence = message_content.replace(' ', '+')
|
||||||
|
return sentence
|
||||||
|
|
||||||
|
|
||||||
|
def handle_input(client, original_content, stream, subject):
|
||||||
|
|
||||||
|
if is_help(original_content):
|
||||||
|
send_message(client, HELP_MESSAGE, stream, subject)
|
||||||
|
|
||||||
|
else:
|
||||||
|
sentence = format_input(original_content)
|
||||||
|
try:
|
||||||
|
reply_message = send_to_yoda_api(sentence, get_api_key())
|
||||||
|
|
||||||
|
except ssl.SSLError or TypeError:
|
||||||
|
reply_message = 'The service is temporarily unavailable, please try again.'
|
||||||
|
logging.error(reply_message)
|
||||||
|
|
||||||
|
except ApiKeyError:
|
||||||
|
reply_message = 'Invalid Api Key. Did you follow the instructions in the ' \
|
||||||
|
'`readme-yoda-bot.md` file?'
|
||||||
|
logging.error(reply_message)
|
||||||
|
|
||||||
|
send_message(client, reply_message, stream, subject)
|
||||||
|
|
||||||
|
|
||||||
|
def get_api_key():
|
||||||
|
# function for getting Mashape api key
|
||||||
|
home = os.path.expanduser('~')
|
||||||
|
with open(home + '/yoda_api_key.txt') as api_key_file:
|
||||||
|
api_key = api_key_file.read().strip()
|
||||||
|
return api_key
|
||||||
|
|
||||||
|
|
||||||
|
def send_message(client, message, stream, subject):
|
||||||
|
# function for sending a message
|
||||||
|
client.send_message(dict(
|
||||||
|
type='stream',
|
||||||
|
to=stream,
|
||||||
|
subject=subject,
|
||||||
|
content=message
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
def is_help(original_content):
|
||||||
|
# replaces the '@yoda' with nothing, so that '@yoda' doesn't get sent to the api
|
||||||
|
message_content = original_content.replace('@yoda', '')
|
||||||
|
# gets rid of whitespace around the edges, so that they aren't a problem in the future
|
||||||
|
message_content = message_content.strip()
|
||||||
|
if message_content == 'help':
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
Loading…
Reference in a new issue