def check_access_token(self, bot_handler: BotHandler) -> None: test_query_response = requests.get( f"https://api.trello.com/1/members/{self.user_name}/", params=self.auth_params ) if test_query_response.text == "invalid key": bot_handler.quit("Invalid Credentials. Please see doc.md to find out how to get them.")
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None: query = message["content"] if query == "new": try: start_new_quiz(message, bot_handler) return except NotAvailableException: bot_response = "Uh-Oh! Trivia service is down." bot_handler.send_reply(message, bot_response) return elif query.startswith("answer"): try: (quiz_id, answer) = parse_answer(query) except InvalidAnswerException: bot_response = "Invalid answer format" bot_handler.send_reply(message, bot_response) return try: quiz_payload = get_quiz_from_id(quiz_id, bot_handler) except (KeyError, TypeError): bot_response = "Invalid quiz id" bot_handler.send_reply(message, bot_response) return quiz = json.loads(quiz_payload) start_new_question, bot_response = handle_answer( quiz, answer, quiz_id, bot_handler, message["sender_full_name"]) bot_handler.send_reply(message, bot_response) if start_new_question: start_new_quiz(message, bot_handler) return else: bot_response = 'type "new" for a new question' bot_handler.send_reply(message, bot_response)
def start_new_quiz(message: Dict[str, Any], bot_handler: BotHandler) -> None: quiz = get_trivia_quiz() quiz_id = generate_quiz_id(bot_handler.storage) bot_response = format_quiz_for_markdown(quiz_id, quiz) widget_content = format_quiz_for_widget(quiz_id, quiz) bot_handler.storage.put(quiz_id, json.dumps(quiz)) bot_handler.send_reply(message, bot_response, widget_content)
def validate_move(self, message: Dict[str, str], bot_handler: BotHandler, last_board: chess.Board, move_san: str, is_computer: object) -> Optional[chess.Move]: """Validates a move based on its SAN string and the current board. Replies to the bot handler if there is an error with the move. Parameters: - message: The Zulip Bots message object. - bot_handler: The Zulip Bots bot handler object. - last_board: The board object before the move. - move_san: The SAN of the move. - is_computer: Whether or not the user is playing against a computer (used in the response if the move is not legal). Returns: `False` if the move didn't pass, or the move object itself if it did. """ try: move = last_board.parse_san(move_san) except ValueError: bot_handler.send_reply( message, make_not_legal_response(last_board, move_san)) return None if move not in last_board.legal_moves: bot_handler.send_reply( message, make_not_legal_response(last_board, move_san)) return None return move
def move_computer_first(self, message: Dict[str, str], bot_handler: BotHandler, last_fen: str) -> None: """Preforms a move for the computer without having the user go first in a game with the computer. Replies to the bot handler. Like `move_computer`, but doesn't have the user move first. This is usually only useful at the beginning of a game. Parameters: - message: The Zulip Bots message object. - bot_handler: The Zulip Bots bot handler object. - last_fen: The FEN string of the board before the computer's move. """ last_board = self.validate_board(message, bot_handler, last_fen) computer_move = calculate_computer_move(last_board, self.engine) new_board_after_computer_move = copy.copy( last_board) # type: chess.Board new_board_after_computer_move.push(computer_move) if self.check_game_over(message, bot_handler, new_board_after_computer_move): return bot_handler.send_reply( message, make_move_reponse(last_board, new_board_after_computer_move, computer_move)) bot_handler.storage.put('last_fen', new_board_after_computer_move.fen()) # `bot_handler`'s `storage` only accepts `str` values. bot_handler.storage.put('is_with_computer', str(True))
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None: try: bot_response = self.get_salesforce_response(message["content"]) bot_handler.send_reply(message, bot_response) except Exception as e: bot_handler.send_reply(message, f"Error. {e}.", bot_response)
def start_computer(self, message: Dict[str, str], bot_handler: BotHandler, is_white_user: bool) -> None: """Starts a game with the computer. Replies to the bot handler. Parameters: - message: The Zulip Bots message object. - bot_handler: The Zulip Bots bot handler object. - is_white_user: Whether or not the player wants to be white. If false, the user is black. If the user is white, they will get to make the first move; if they are black the computer will make the first move. """ new_board = chess.Board() if is_white_user: bot_handler.send_reply(message, make_start_computer_reponse(new_board)) # `bot_handler`'s `storage` only accepts `str` values. bot_handler.storage.put("is_with_computer", str(True)) bot_handler.storage.put("last_fen", new_board.fen()) else: self.move_computer_first( message, bot_handler, new_board.fen(), )
def move(self, message: Dict[str, str], bot_handler: BotHandler, last_fen: str, move_san: str) -> None: """Makes a move for a user in a game with another user. Replies to the bot handler. Parameters: - message: The Zulip Bots message object. - bot_handler: The Zulip Bots bot handler object. - last_fen: The FEN string of the board before the move. - move_san: The SAN of the move to make. """ last_board = self.validate_board(message, bot_handler, last_fen) if not last_board: return move = self.validate_move(message, bot_handler, last_board, move_san, False) if not move: return new_board = copy.copy(last_board) new_board.push(move) if self.check_game_over(message, bot_handler, new_board): return bot_handler.send_reply(message, make_move_reponse(last_board, new_board, move)) bot_handler.storage.put("last_fen", new_board.fen())
def handle_input(self, message: Dict[str, str], bot_handler: BotHandler) -> None: original_content = message['content'] if self.is_help(original_content) or (original_content == ""): bot_handler.send_reply(message, HELP_MESSAGE) else: sentence = self.format_input(original_content) try: reply_message = self.send_to_yoda_api(sentence) if len(reply_message) == 0: reply_message = 'Invalid input, please check the sentence you have entered.' except (ssl.SSLError, 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.md` file?' logging.error(reply_message) bot_handler.send_reply(message, reply_message)
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None: command = message["content"] if command == "": command = "help" sender = message["sender_email"] recipient = message["display_recipient"] if isinstance(recipient, list): # If not a stream, then hash on list of emails recipient = " ".join(x["email"] for x in recipient) storage = bot_handler.storage if not storage.contains(recipient): storage.put(recipient, fs_new()) fs = storage.get(recipient) if sender not in fs["user_paths"]: fs["user_paths"][sender] = "/" fs, msg = fs_command(fs, sender, command) prependix = f"{sender}:\n" msg = prependix + msg storage.put(recipient, fs) bot_handler.send_reply(message, msg)
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None: command = message['content'] if command == "": command = "help" sender = message['sender_email'] recipient = message['display_recipient'] if isinstance(recipient, list): # If not a stream, then hash on list of emails recipient = " ".join([x['email'] for x in recipient]) storage = bot_handler.storage if not storage.contains(recipient): storage.put(recipient, fs_new()) fs = storage.get(recipient) if sender not in fs['user_paths']: fs['user_paths'][sender] = '/' fs, msg = fs_command(fs, sender, command) prependix = '{}:\n'.format(sender) msg = prependix + msg storage.put(recipient, fs) bot_handler.send_reply(message, msg)
def check_api_key(self, bot_handler: BotHandler) -> None: test_request_data = self.call_link_shorten_service('www.youtube.com/watch') # type: Any try: if self.is_invalid_token_error(test_request_data): bot_handler.quit('Invalid key. Follow the instructions in doc.md for setting API key.') except KeyError: pass
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None: command = message['content'] if command == "": command = "help" msg = dbx_command(self.client, command) bot_handler.send_reply(message, msg)
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None: content = message["content"] response = parse.execute(content, self.api_key) bot_handler.send_reply(message, response)
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None: content = 'beep boop' # type: str bot_handler.send_reply(message, content) emoji_name = 'wave' # type: str bot_handler.react(message, emoji_name) return
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None: if message["content"] == "" or message["content"] == "help": bot_handler.send_reply(message, self.help_content) else: cmd, query = get_command_query(message) bot_response = get_bot_response(query, cmd, self.config_info) logging.info(bot_response.format()) bot_handler.send_reply(message, bot_response)
def check_api_key(self, bot_handler: BotHandler) -> None: url = "https://api.baremetrics.com/v1/account" test_query_response = requests.get(url, headers=self.auth_header) test_query_data = test_query_response.json() try: if test_query_data["error"] == "Unauthorized. Token not found (001)": bot_handler.quit("API Key not valid. Please see doc.md to find out how to get it.") except KeyError: pass
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None: HELP_STR = ( "Use this bot with any of the following commands:" "\n* `@uploader <local_file_path>` : Upload a file, where `<local_file_path>` is the path to the file" "\n* `@uploader help` : Display help message") content = message["content"].strip() if content == "help": bot_handler.send_reply(message, HELP_STR) return path = Path(os.path.expanduser(content)) if not path.is_file(): bot_handler.send_reply(message, f"File `{content}` not found") return path = path.resolve() upload = bot_handler.upload_file_from_path(str(path)) if upload["result"] != "success": msg = upload["msg"] bot_handler.send_reply(message, f"Failed to upload `{path}` file: {msg}") return uploaded_file_reply = "[{}]({})".format(path.name, upload["uri"]) bot_handler.send_reply(message, uploaded_file_reply)
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None: HELP_STR = ( 'Use this bot with any of the following commands:' '\n* `@uploader <local_file_path>` : Upload a file, where `<local_file_path>` is the path to the file' '\n* `@uploader help` : Display help message' ) content = message['content'].strip() if content == 'help': bot_handler.send_reply(message, HELP_STR) return path = Path(os.path.expanduser(content)) if not path.is_file(): bot_handler.send_reply(message, 'File `{}` not found'.format(content)) return path = path.resolve() upload = bot_handler.upload_file_from_path(str(path)) if upload['result'] != 'success': msg = upload['msg'] bot_handler.send_reply(message, 'Failed to upload `{}` file: {}'.format(path, msg)) return uploaded_file_reply = '[{}]({})'.format(path.name, upload['uri']) bot_handler.send_reply(message, uploaded_file_reply)
def initialize(self, bot_handler: BotHandler) -> None: self.config_info = bot_handler.get_config_info('beeminder') # Check for valid auth_token auth_token = self.config_info['auth_token'] try: r = requests.get("https://www.beeminder.com/api/v1/users/me.json", params={'auth_token': auth_token}) if r.status_code == 401: bot_handler.quit('Invalid key!') except ConnectionError as e: logging.exception(str(e))
def initialize(self, bot_handler: BotHandler) -> None: self.config_info = bot_handler.get_config_info("salesforce") try: self.sf = simple_salesforce.Salesforce( username=self.config_info["username"], password=self.config_info["password"], security_token=self.config_info["security_token"], ) except simple_salesforce.exceptions.SalesforceAuthenticationFailed as err: bot_handler.quit( f"Failed to log in to Salesforce. {err.code} {err.message}")
def check_api_key(self, bot_handler: BotHandler) -> None: api_params = dict(q="nyc", APPID=self.api_key) test_response = requests.get(api_url, params=api_params) try: test_response_data = test_response.json() if test_response_data["cod"] == 401: bot_handler.quit( "API Key not valid. Please see doc.md to find out how to get it." ) except KeyError: pass
def move_computer(self, message: Dict[str, str], bot_handler: BotHandler, last_fen: str, move_san: str) -> None: """Preforms a move for a user in a game with the computer and then makes the computer's move. Replies to the bot handler. Unlike `move`, replies only once to the bot handler every two moves (only after the computer moves) instead of after every move. Doesn't require a call in order to make the computer move. To make the computer move without the user going first, use `move_computer_first`. Parameters: - message: The Zulip Bots message object. - bot_handler: The Zulip Bots bot handler object. - last_fen: The FEN string of the board before the user's move. - move_san: The SAN of the user's move to make. """ last_board = self.validate_board(message, bot_handler, last_fen) if not last_board: return move = self.validate_move(message, bot_handler, last_board, move_san, True) if not move: return new_board = copy.copy(last_board) new_board.push(move) if self.check_game_over(message, bot_handler, new_board): return computer_move = calculate_computer_move(new_board, self.engine) if not computer_move: bot_handler.send_reply(message, make_engine_failed_response()) return new_board_after_computer_move = copy.copy(new_board) new_board_after_computer_move.push(computer_move) if self.check_game_over(message, bot_handler, new_board_after_computer_move): return bot_handler.send_reply( message, make_move_reponse(new_board, new_board_after_computer_move, computer_move)) bot_handler.storage.put("last_fen", new_board_after_computer_move.fen())
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None: msg = message["content"] if msg == "help" or msg == "": bot_handler.send_reply(message, self.usage()) return reply = requests.get("https://api.susi.ai/susi/chat.json", params=dict(q=msg)) try: answer = reply.json()["answers"][0]["actions"][0]["expression"] except Exception: answer = "I don't understand. Can you rephrase?" bot_handler.send_reply(message, answer)
def start_new_incident(query: str, message: Dict[str, Any], bot_handler: BotHandler) -> None: # Here is where we would enter the incident in some sort of backend # system. We just simulate everything by having an incident id that # we generate here. incident = query[len("new "):] ticket_id = generate_ticket_id(bot_handler.storage) bot_response = format_incident_for_markdown(ticket_id, incident) widget_content = format_incident_for_widget(ticket_id, incident) bot_handler.send_reply(message, bot_response, widget_content)
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None: req = message['content'].strip().split() if req == []: bot_handler.send_reply(message, 'No Command Specified') return req[0] = req[0].lower() response = '' if req == ['my-events']: response = helpers.get_my_events(message['sender_id']) if response: bot_handler.send_reply(message, response) elif req == ['all-events']: response = helpers.get_all_events() if response: bot_handler.send_reply(message, response) else: bot_handler.send_reply( message, "I don't understand what you're saying...try again :)") return
def initialize(self, bot_handler: BotHandler) -> None: self.config_info = bot_handler.get_config_info("youtube") # Check if API key is valid. If it is not valid, don't run the bot. try: search_youtube("test", self.config_info["key"], self.config_info["video_region"]) except HTTPError as e: if e.response.json()["error"]["errors"][0]["reason"] == "keyInvalid": bot_handler.quit( "Invalid key." "Follow the instructions in doc.md for setting API key." ) else: raise except ConnectionError: logging.warning("Bad connection")
def start(self, message: Dict[str, str], bot_handler: BotHandler) -> None: """Starts a game with another user, with the current user as white. Replies to the bot handler. Parameters: - message: The Zulip Bots message object. - bot_handler: The Zulip Bots bot handler object. """ new_board = chess.Board() bot_handler.send_reply(message, make_start_reponse(new_board)) # `bot_handler`'s `storage` only accepts `str` values. bot_handler.storage.put("is_with_computer", str(False)) bot_handler.storage.put("last_fen", new_board.fen())
def initialize(self, bot_handler: BotHandler) -> None: config = bot_handler.get_config_info("jira") username = config.get("username") password = config.get("password") domain = config.get("domain") if not username: raise KeyError("No `username` was specified") if not password: raise KeyError("No `password` was specified") if not domain: raise KeyError("No `domain` was specified") self.auth = make_jira_auth(username, password) # Allow users to override the HTTP scheme if re.match(r"^https?://", domain, re.IGNORECASE): self.domain_with_protocol = domain else: self.domain_with_protocol = "https://" + domain # Use the front facing URL in output self.display_url = config.get("display_url") if not self.display_url: self.display_url = self.domain_with_protocol
def initialize(self, bot_handler: BotHandler) -> None: self.config_info = bot_handler.get_config_info('youtube') # Check if API key is valid. If it is not valid, don't run the bot. try: search_youtube('test', self.config_info['key'], self.config_info['video_region']) except HTTPError as e: if (e.response.json()['error']['errors'][0]['reason'] == 'keyInvalid'): bot_handler.quit( 'Invalid key.' 'Follow the instructions in doc.md for setting API key.') else: raise except ConnectionError: logging.warning('Bad connection')