interactive bots: Create yoda translator bot
ADD
contrib_bots/lib/readme-yoda-bot.md
+# 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

ADD
contrib_bots/lib/yoda-speak-api.png
contrib_bots/lib/yoda-speak-api.png
Binary files /dev/null and b/contrib_bots/lib/yoda-speak-api.png differ

ADD
contrib_bots/lib/yoda_bot.py
+# 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

interactive bots: Create yoda translator bot