diff --git a/.gitignore b/.gitignore index 808f83e..928630b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ local mojojojo.log mojojojo/ .vscode/ +/.DS_Store diff --git a/Pipfile b/mojo-rtm/Pipfile similarity index 100% rename from Pipfile rename to mojo-rtm/Pipfile diff --git a/Pipfile.lock b/mojo-rtm/Pipfile.lock similarity index 100% rename from Pipfile.lock rename to mojo-rtm/Pipfile.lock diff --git a/docker/dockerfile b/mojo-rtm/dockerfile similarity index 72% rename from docker/dockerfile rename to mojo-rtm/dockerfile index 8d93656..900b42e 100644 --- a/docker/dockerfile +++ b/mojo-rtm/dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.9 +FROM python:3.7-alpine LABEL maintainer "me@jowj.net" RUN apk update @@ -14,8 +14,8 @@ RUN pip3 install --upgrade pip RUN pip3 install --upgrade setuptools -RUN pip3 install slackclient==1.3.1 +COPY ./ ./mojo/ -COPY ./ ./ +RUN pip3 install requests slackclient -CMD python3 ./mojojojo-bot.py +CMD python3 /mojo/mojo-web.py diff --git a/mojo-bot-v2.py b/mojo-rtm/mojo-rtm.py similarity index 92% rename from mojo-bot-v2.py rename to mojo-rtm/mojo-rtm.py index 183b5af..e87e616 100644 --- a/mojo-bot-v2.py +++ b/mojo-rtm/mojo-rtm.py @@ -1,8 +1,12 @@ import os +import time import slack import pdb +import json import re +from pathlib import Path + EXAMPLE_COMMAND = "do" MENTION_REGEX = "^<@(|[WU].+)>(.*)" bot_channel = "bots-like-gaston" @@ -31,7 +35,8 @@ def reactable_string(text): # no processing needed because: honestly its funnier even if it gets the word boundary wrong. reactable_array.append('flavortown') return reactable_array - + + @slack.RTMClient.run_on(event='message') def handle_messages(**payload): @@ -44,7 +49,7 @@ def handle_messages(**payload): channel_id = data['channel'] thread_ts = data['ts'] - pdb.set_trace() + if reactable_string(data['text']): reactions_needed = reactable_string(data['text']) @@ -88,7 +93,11 @@ def handle_messages(**payload): timestamp=thread_ts ) +if __name__ == '__main__': + slack_token = os.environ["SLACK_API_TOKEN"] + client = slack.WebClient(token=os.environ['SLACK_API_TOKEN']) + rtm_client = slack.RTMClient(token=slack_token) + rtm_client.start() + + -slack_token = os.environ["SLACK_API_TOKEN"] -rtm_client = slack.RTMClient(token=slack_token) -rtm_client.start() diff --git a/mojo-web/Pipfile b/mojo-web/Pipfile new file mode 100644 index 0000000..35df1a2 --- /dev/null +++ b/mojo-web/Pipfile @@ -0,0 +1,12 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] + +[packages] +slackclient = "*" + +[requires] +python_version = "3.7" diff --git a/mojo-web/Pipfile.lock b/mojo-web/Pipfile.lock new file mode 100644 index 0000000..05b90ac --- /dev/null +++ b/mojo-web/Pipfile.lock @@ -0,0 +1,134 @@ +{ + "_meta": { + "hash": { + "sha256": "7cbe5be898916ef05dcff196ada03f05a4876ea4138e116d9fddd22ebfb7053c" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "aiohttp": { + "hashes": [ + "sha256:00d198585474299c9c3b4f1d5de1a576cc230d562abc5e4a0e81d71a20a6ca55", + "sha256:0155af66de8c21b8dba4992aaeeabf55503caefae00067a3b1139f86d0ec50ed", + "sha256:09654a9eca62d1bd6d64aa44db2498f60a5c1e0ac4750953fdd79d5c88955e10", + "sha256:199f1d106e2b44b6dacdf6f9245493c7d716b01d0b7fbe1959318ba4dc64d1f5", + "sha256:296f30dedc9f4b9e7a301e5cc963012264112d78a1d3094cd83ef148fdf33ca1", + "sha256:368ed312550bd663ce84dc4b032a962fcb3c7cae099dbbd48663afc305e3b939", + "sha256:40d7ea570b88db017c51392349cf99b7aefaaddd19d2c78368aeb0bddde9d390", + "sha256:629102a193162e37102c50713e2e31dc9a2fe7ac5e481da83e5bb3c0cee700aa", + "sha256:6d5ec9b8948c3d957e75ea14d41e9330e1ac3fed24ec53766c780f82805140dc", + "sha256:87331d1d6810214085a50749160196391a712a13336cd02ce1c3ea3d05bcf8d5", + "sha256:9a02a04bbe581c8605ac423ba3a74999ec9d8bce7ae37977a3d38680f5780b6d", + "sha256:9c4c83f4fa1938377da32bc2d59379025ceeee8e24b89f72fcbccd8ca22dc9bf", + "sha256:9cddaff94c0135ee627213ac6ca6d05724bfe6e7a356e5e09ec57bd3249510f6", + "sha256:a25237abf327530d9561ef751eef9511ab56fd9431023ca6f4803f1994104d72", + "sha256:a5cbd7157b0e383738b8e29d6e556fde8726823dae0e348952a61742b21aeb12", + "sha256:a97a516e02b726e089cffcde2eea0d3258450389bbac48cbe89e0f0b6e7b0366", + "sha256:acc89b29b5f4e2332d65cd1b7d10c609a75b88ef8925d487a611ca788432dfa4", + "sha256:b05bd85cc99b06740aad3629c2585bda7b83bd86e080b44ba47faf905fdf1300", + "sha256:c2bec436a2b5dafe5eaeb297c03711074d46b6eb236d002c13c42f25c4a8ce9d", + "sha256:cc619d974c8c11fe84527e4b5e1c07238799a8c29ea1c1285149170524ba9303", + "sha256:d4392defd4648badaa42b3e101080ae3313e8f4787cb517efd3f5b8157eaefd6", + "sha256:e1c3c582ee11af7f63a34a46f0448fca58e59889396ffdae1f482085061a2889" + ], + "version": "==3.5.4" + }, + "async-timeout": { + "hashes": [ + "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", + "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" + ], + "version": "==3.0.1" + }, + "attrs": { + "hashes": [ + "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", + "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" + ], + "version": "==19.1.0" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, + "multidict": { + "hashes": [ + "sha256:024b8129695a952ebd93373e45b5d341dbb87c17ce49637b34000093f243dd4f", + "sha256:041e9442b11409be5e4fc8b6a97e4bcead758ab1e11768d1e69160bdde18acc3", + "sha256:045b4dd0e5f6121e6f314d81759abd2c257db4634260abcfe0d3f7083c4908ef", + "sha256:047c0a04e382ef8bd74b0de01407e8d8632d7d1b4db6f2561106af812a68741b", + "sha256:068167c2d7bbeebd359665ac4fff756be5ffac9cda02375b5c5a7c4777038e73", + "sha256:148ff60e0fffa2f5fad2eb25aae7bef23d8f3b8bdaf947a65cdbe84a978092bc", + "sha256:1d1c77013a259971a72ddaa83b9f42c80a93ff12df6a4723be99d858fa30bee3", + "sha256:1d48bc124a6b7a55006d97917f695effa9725d05abe8ee78fd60d6588b8344cd", + "sha256:31dfa2fc323097f8ad7acd41aa38d7c614dd1960ac6681745b6da124093dc351", + "sha256:34f82db7f80c49f38b032c5abb605c458bac997a6c3142e0d6c130be6fb2b941", + "sha256:3d5dd8e5998fb4ace04789d1d008e2bb532de501218519d70bb672c4c5a2fc5d", + "sha256:4a6ae52bd3ee41ee0f3acf4c60ceb3f44e0e3bc52ab7da1c2b2aa6703363a3d1", + "sha256:4b02a3b2a2f01d0490dd39321c74273fed0568568ea0e7ea23e02bd1fb10a10b", + "sha256:4b843f8e1dd6a3195679d9838eb4670222e8b8d01bc36c9894d6c3538316fa0a", + "sha256:5de53a28f40ef3c4fd57aeab6b590c2c663de87a5af76136ced519923d3efbb3", + "sha256:61b2b33ede821b94fa99ce0b09c9ece049c7067a33b279f343adfe35108a4ea7", + "sha256:6a3a9b0f45fd75dc05d8e93dc21b18fc1670135ec9544d1ad4acbcf6b86781d0", + "sha256:76ad8e4c69dadbb31bad17c16baee61c0d1a4a73bed2590b741b2e1a46d3edd0", + "sha256:7ba19b777dc00194d1b473180d4ca89a054dd18de27d0ee2e42a103ec9b7d014", + "sha256:7c1b7eab7a49aa96f3db1f716f0113a8a2e93c7375dd3d5d21c4941f1405c9c5", + "sha256:7fc0eee3046041387cbace9314926aa48b681202f8897f8bff3809967a049036", + "sha256:8ccd1c5fff1aa1427100ce188557fc31f1e0a383ad8ec42c559aabd4ff08802d", + "sha256:8e08dd76de80539d613654915a2f5196dbccc67448df291e69a88712ea21e24a", + "sha256:c18498c50c59263841862ea0501da9f2b3659c00db54abfbf823a80787fde8ce", + "sha256:c49db89d602c24928e68c0d510f4fcf8989d77defd01c973d6cbe27e684833b1", + "sha256:ce20044d0317649ddbb4e54dab3c1bcc7483c78c27d3f58ab3d0c7e6bc60d26a", + "sha256:d1071414dd06ca2eafa90c85a079169bfeb0e5f57fd0b45d44c092546fcd6fd9", + "sha256:d3be11ac43ab1a3e979dac80843b42226d5d3cccd3986f2e03152720a4297cd7", + "sha256:db603a1c235d110c860d5f39988ebc8218ee028f07a7cbc056ba6424372ca31b" + ], + "version": "==4.5.2" + }, + "slackclient": { + "hashes": [ + "sha256:ed0f60dd5a646b4ccd31ec1f11503b8689850894681e6baae2bc06b941fc1c58", + "sha256:eeb0dad774f6661f7504d80d8a22deadadb941b840e7a0719b5b92d4d84f9015" + ], + "index": "pypi", + "version": "==2.1.0" + }, + "yarl": { + "hashes": [ + "sha256:024ecdc12bc02b321bc66b41327f930d1c2c543fa9a561b39861da9388ba7aa9", + "sha256:2f3010703295fbe1aec51023740871e64bb9664c789cba5a6bdf404e93f7568f", + "sha256:3890ab952d508523ef4881457c4099056546593fa05e93da84c7250516e632eb", + "sha256:3e2724eb9af5dc41648e5bb304fcf4891adc33258c6e14e2a7414ea32541e320", + "sha256:5badb97dd0abf26623a9982cd448ff12cb39b8e4c94032ccdedf22ce01a64842", + "sha256:73f447d11b530d860ca1e6b582f947688286ad16ca42256413083d13f260b7a0", + "sha256:7ab825726f2940c16d92aaec7d204cfc34ac26c0040da727cf8ba87255a33829", + "sha256:b25de84a8c20540531526dfbb0e2d2b648c13fd5dd126728c496d7c3fea33310", + "sha256:c6e341f5a6562af74ba55205dbd56d248daf1b5748ec48a0200ba227bb9e33f4", + "sha256:c9bb7c249c4432cd47e75af3864bc02d26c9594f49c82e2a28624417f0ae63b8", + "sha256:e060906c0c585565c718d1c3841747b61c5439af2211e185f6739a9412dfbde1" + ], + "version": "==1.3.0" + } + }, + "develop": {} +} diff --git a/mojo-web/dockerfile b/mojo-web/dockerfile new file mode 100644 index 0000000..900b42e --- /dev/null +++ b/mojo-web/dockerfile @@ -0,0 +1,21 @@ +FROM python:3.7-alpine +LABEL maintainer "me@jowj.net" + +RUN apk update + +RUN apk add \ + python3 \ + python3-dev \ + libffi-dev + +RUN apk add --no-cache curl python pkgconfig python-dev openssl-dev libffi-dev musl-dev make gcc + +RUN pip3 install --upgrade pip + +RUN pip3 install --upgrade setuptools + +COPY ./ ./mojo/ + +RUN pip3 install requests slackclient + +CMD python3 /mojo/mojo-web.py diff --git a/mojo-arke.py b/mojo-web/mojo-web.py similarity index 100% rename from mojo-arke.py rename to mojo-web/mojo-web.py diff --git a/mojojojo-bot.py b/mojojojo-bot.py deleted file mode 100644 index 1906346..0000000 --- a/mojojojo-bot.py +++ /dev/null @@ -1,195 +0,0 @@ -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.lower(): - 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')