|
|
|
import os
|
|
|
|
import time
|
|
|
|
import re
|
|
|
|
import logging
|
|
|
|
import json
|
|
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
from slackclient import SlackClient
|
|
|
|
from json import JSONDecoder
|
|
|
|
from random import randint
|
|
|
|
from functools import partial
|
|
|
|
|
|
|
|
# instantiate Slack client
|
|
|
|
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
|
|
|
|
# starterbot's user ID in Slack: value is assigned after the bot starts up
|
|
|
|
starterbot_id = None
|
|
|
|
# channel i want to get ID from
|
|
|
|
bot_channel = "inmyimo"
|
|
|
|
|
|
|
|
# constants
|
|
|
|
RTM_READ_DELAY = 1 # 1 second delay between reading from RTM
|
|
|
|
EXAMPLE_COMMAND = "do"
|
|
|
|
MENTION_REGEX = "^<@(|[WU].+)>(.*)"
|
|
|
|
|
|
|
|
|
|
|
|
def parse_bot_commands(slack_events):
|
|
|
|
"""
|
|
|
|
Parses a list of events coming from the Slack RTM API to find bot commands.
|
|
|
|
If a bot command is found, this function returns a tuple of command and channel.
|
|
|
|
If its not found, then this function returns None, None.
|
|
|
|
"""
|
|
|
|
if event["type"] == "message" and not "subtype" in event:
|
|
|
|
user_id, message = parse_direct_mention(event["text"])
|
|
|
|
if user_id == starterbot_id:
|
|
|
|
return message, event["channel"]
|
|
|
|
return None, None
|
|
|
|
|
|
|
|
|
|
|
|
def parse_direct_mention(message_text):
|
|
|
|
"""
|
|
|
|
Finds a direct mention (a mention that is at the beginning) in message text
|
|
|
|
and returns the user ID which was mentioned. If there is no direct mention, returns None
|
|
|
|
"""
|
|
|
|
matches = re.search(MENTION_REGEX, message_text)
|
|
|
|
# the first group contains the username, the second group contains the remaining message
|
|
|
|
return (matches.group(1), matches.group(2).strip()) if matches else (None, None)
|
|
|
|
|
|
|
|
|
|
|
|
def select_noun():
|
|
|
|
with open('/mjj1/corpora.json', 'r') as infh:
|
|
|
|
for data in json_parse(infh):
|
|
|
|
upper_Limit = len(data["nouns"])
|
|
|
|
x = randint(0, upper_Limit)
|
|
|
|
if data["nouns"][x]:
|
|
|
|
return(data["nouns"][x])
|
|
|
|
else:
|
|
|
|
return("car")
|
|
|
|
|
|
|
|
|
|
|
|
def json_parse(fileobj, decoder=JSONDecoder(), buffersize=2048):
|
|
|
|
buffer = ''
|
|
|
|
for chunk in iter(partial(fileobj.read, buffersize), ''):
|
|
|
|
buffer += chunk
|
|
|
|
while buffer:
|
|
|
|
try:
|
|
|
|
result, index = decoder.raw_decode(buffer)
|
|
|
|
yield result
|
|
|
|
buffer = buffer[index:]
|
|
|
|
except ValueError:
|
|
|
|
# Not enough data to decode, read more
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
def handle_command(command, channel):
|
|
|
|
"""
|
|
|
|
Executes bot command if the command is known
|
|
|
|
"""
|
|
|
|
# Default response is help text for the user
|
|
|
|
default_response = "tell j- to actually fucking write somthing."
|
|
|
|
response = None
|
|
|
|
|
|
|
|
if command.startswith(EXAMPLE_COMMAND):
|
|
|
|
response = "Sure...write some more code then I can do that!"
|
|
|
|
if command.startswith("say"):
|
|
|
|
response = "you're not my real dad"
|
|
|
|
if command.startswith("download"):
|
|
|
|
response = "you wouldn't download a %s" % (select_noun())
|
|
|
|
if "arke" in command:
|
|
|
|
results_file = Path("/shared/results.json")
|
|
|
|
if results_file.is_file():
|
|
|
|
open_file = open(results_file)
|
|
|
|
for line in open_file:
|
|
|
|
response = line
|
|
|
|
else:
|
|
|
|
response = "Most recent status failed to write to file :("
|
|
|
|
if "pence" in command:
|
|
|
|
response = "Mother wouldn't want me to say that"
|
|
|
|
|
|
|
|
# Sends the response back to the channel
|
|
|
|
slack_client.api_call(
|
|
|
|
"chat.postMessage",
|
|
|
|
channel=channel,
|
|
|
|
text=response or default_response
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def reactable_message(event):
|
|
|
|
"""Test whether a (Slack) event is a reaction-able message
|
|
|
|
|
|
|
|
Check whether it's not a DM, it's not empty, and it's actually a message
|
|
|
|
"""
|
|
|
|
return 'channel' in event and 'text' in event and event.get('type') == 'message'
|
|
|
|
|
|
|
|
|
|
|
|
def reactable_string(text):
|
|
|
|
"""Return regex objects matching interesting strings
|
|
|
|
"""
|
|
|
|
reactable_array = []
|
|
|
|
if re.search(r"\bai\b", text.lower()) is not None:
|
|
|
|
reactable_array.append('ai')
|
|
|
|
if 'furry' in text.lower() or 'furries' in text.lower() or 'fursuit' in text.lower():
|
|
|
|
# no processing needed because: honestly its funnier even if it gets the word boundary wrong.
|
|
|
|
reactable_array.append('furry')
|
|
|
|
if 'flavor town' in text.lower() or 'flavortown' in text.lower() or 'guy fieri' in text.lower():
|
|
|
|
# no processing needed because: honestly its funnier even if it gets the word boundary wrong.
|
|
|
|
reactable_array.append('flavortown')
|
|
|
|
return reactable_array
|
|
|
|
|
|
|
|
|
|
|
|
def react_to_message(reaction):
|
|
|
|
slack_client.api_call(
|
|
|
|
'reactions.add',
|
|
|
|
channel = get_channel_ID("inmyimo"),
|
|
|
|
name = reaction,
|
|
|
|
timestamp = event.get('ts')
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def react_to_monitoring():
|
|
|
|
results_file = Path("/shared/alerts.log")
|
|
|
|
does_file_exist = results_file.is_file()
|
|
|
|
logging.info(f"file exists: {does_file_exist}")
|
|
|
|
if results_file.is_file():
|
|
|
|
open_file = open("/shared/alerts.log","r")
|
|
|
|
logging.info('in file exists conditional')
|
|
|
|
for line in open_file:
|
|
|
|
logging.info('examining item: '+line)
|
|
|
|
slack_client.api_call(
|
|
|
|
"chat.postMessage",
|
|
|
|
channel = get_channel_ID("bots-like-gaston"),
|
|
|
|
text = line
|
|
|
|
)
|
|
|
|
os.remove("/shared/alerts.log")
|
|
|
|
|
|
|
|
|
|
|
|
def get_channel_ID(channelName):
|
|
|
|
for channel in slack_client.api_call('channels.list')["channels"]:
|
|
|
|
if channel["name"] == channelName:
|
|
|
|
return channel["id"]
|
|
|
|
raise Exception("couldn't find channel requested.")
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
logging.basicConfig(filename='mojojojo.log', level=logging.INFO)
|
|
|
|
logging.info('Started')
|
|
|
|
results_file = Path("/shared/alerts.log")
|
|
|
|
if slack_client.rtm_connect(with_team_state=False):
|
|
|
|
print("mojo jojo online, connected, and running!")
|
|
|
|
# Read bot's user ID by calling Web API method `auth.test`
|
|
|
|
starterbot_id = slack_client.api_call("auth.test")["user_id"]
|
|
|
|
while True:
|
|
|
|
if results_file.is_file():
|
|
|
|
logging.info("results_file ifstatement passed!")
|
|
|
|
react_to_monitoring()
|
|
|
|
for event in (slack_client.rtm_read()):
|
|
|
|
command, channel = parse_bot_commands(event)
|
|
|
|
if command:
|
|
|
|
handle_command(command, channel)
|
|
|
|
if reactable_message(event):
|
|
|
|
channel = event['channel']
|
|
|
|
text = event['text']
|
|
|
|
reactions_needed = reactable_string(text)
|
|
|
|
if 'ai' in reactions_needed:
|
|
|
|
react_to_message("robot_face")
|
|
|
|
if 'furry' in reactions_needed:
|
|
|
|
react_to_message("eggplant")
|
|
|
|
react_to_message("sweat_drops")
|
|
|
|
if 'flavortown' in reactions_needed:
|
|
|
|
react_to_message("dark_sunglasses")
|
|
|
|
react_to_message("guyfieri")
|
|
|
|
time.sleep(RTM_READ_DELAY)
|
|
|
|
logging.info("Client worked. No errors (we think lol)")
|
|
|
|
else:
|
|
|
|
print("Connection failed. Exception traceback printed above.")
|
|
|
|
logging.info('Check console for exception traceback.')
|
|
|
|
logging.info('Finished')
|