From 4efb02784c81bdcc3cbda16a3d8f0e5e722fb33b Mon Sep 17 00:00:00 2001 From: Benjamyn Love Date: Sun, 15 Oct 2023 18:54:25 +1100 Subject: [PATCH 1/6] Added redis cache and user registration system --- Pipfile | 1 + Pipfile.lock | 11 +++++++- libs/http/__init__.py | 1 + libs/http/users.py | 31 +++++++++++++++++++++ slackbot.py | 63 ++++++++++++++++++++++++++++++++++++++----- testing_libs.py | 36 +++++++++++++++++++++++++ 6 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 libs/http/__init__.py create mode 100644 libs/http/users.py create mode 100644 testing_libs.py diff --git a/Pipfile b/Pipfile index da71969..a620189 100644 --- a/Pipfile +++ b/Pipfile @@ -10,6 +10,7 @@ aiomysql = "*" uvicorn = "*" gunicorn = "*" flask = "*" +redis = "*" [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index 4e6ac4a..ee6c2dc 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c15a725d7a97c336acc3f1198bfbdd80a2360883990bd018c6482960d2606860" + "sha256": "c5a98719dfb37b2da391fbbb06f7dce1c8be9b79d9b4be7b4b365ac786e53ecb" }, "pipfile-spec": 6, "requires": { @@ -534,6 +534,15 @@ "markers": "python_version >= '3.7'", "version": "==1.1.0" }, + "redis": { + "hashes": [ + "sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f", + "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==5.0.1" + }, "slack-bolt": { "hashes": [ "sha256:43b121acf78440303ce5129e53be36bdfe5d926a193daef7daf2860688e65dd3", diff --git a/libs/http/__init__.py b/libs/http/__init__.py new file mode 100644 index 0000000..b942ebb --- /dev/null +++ b/libs/http/__init__.py @@ -0,0 +1 @@ +from . import users diff --git a/libs/http/users.py b/libs/http/users.py new file mode 100644 index 0000000..3f3ff5b --- /dev/null +++ b/libs/http/users.py @@ -0,0 +1,31 @@ +import aiohttp + + +class UserRequests: + def __init__(self, API_URL, BOT_TOKEN): + self.API_URL = API_URL + self.headers = {"Content-Type": "application/json", "X-BOTAUTH": BOT_TOKEN} + + async def getUser(self, user_id): + async with aiohttp.ClientSession(self.API_URL, headers=self.headers) as session: + # Make sure we have a good connection + async with session.head("/") as alive: + if alive.status != 200: + return None + + async with session.get(f"/api/user/{user_id}") as data: + response = await data.json() + return response + + async def registerUser(self, user_data: dict): + async with aiohttp.ClientSession(self.API_URL, headers=self.headers) as session: + # Make sure we have a good connection + async with session.head("/") as alive: + if alive.status != 200: + return None + + async with session.post("/api/user/register", json=user_data) as data: + if data.status != 200: + return False + response = await data.json() + return response diff --git a/slackbot.py b/slackbot.py index fa36008..0890fca 100644 --- a/slackbot.py +++ b/slackbot.py @@ -8,11 +8,16 @@ from slack_bolt.async_app import AsyncApp from slack_bolt.adapter.asgi.async_handler import AsyncSlackRequestHandler import libs.block_utils as block_utils import libs.benv +from libs import http +import redis.asyncio as redis libs.benv.load_env() logging.basicConfig(level=logging.DEBUG) +redis_client = redis.Redis() + +user_manager = http.users.UserRequests(environ["API_URL"], environ["API_BOT_TOKEN"]) # Dataset for automatic reactions, the lower the chance the more often it triggers auto_react_lookup = { @@ -20,18 +25,56 @@ auto_react_lookup = { "U05ES1730UE": {"text": "clown_face", "chance": 3}, # mprice "U05FN1F9ZCG": {"text": "frannodders", "chance": 4}, # blove "U05EY6DQR9R": {"text": "kekw", "chance": 4}, # jfox - "U05ERL26A3G": {"text": "jacoborg", "chance": 3},# jborg - "U05F0NWDH9S": {"text": "usb-c", "chance": 3}, #jjennings + "U05ERL26A3G": {"text": "jacoborg", "chance": 3}, # jborg + "U05F0NWDH9S": {"text": "usb-c", "chance": 3}, # jjennings } -app = AsyncApp(token=environ.get("SLACK_BOT_TOKEN"), signing_secret=environ.get('SLACK_SIGNING_SECRET')) +app = AsyncApp( + token=environ.get("SLACK_BOT_TOKEN"), + signing_secret=environ.get("SLACK_SIGNING_SECRET"), +) api = AsyncSlackRequestHandler(app) - messages_already_reacted = {} +async def check_user_registration(user_id: str, client) -> bool: + r = await redis.from_url("redis://localhost") + async with r.pipeline(transaction=True) as pipe: + user_exists = await pipe.get(user_id).execute() + if user_exists[0] is None: + if check_user_exists() is True: + await pipe.set(user_id, 1) + return True + else: + user_created = await register_user(user_id, client) + if user_created is True: + await pipe.set(user_id, 1) + return user_created + else: + return True + + +async def check_user_exists(user_id: str): + response = await user_manager.getUser(user_id) + return response["status"] + + +async def register_user(user_id: str, client): + # lookup the user_id to get account info + user_info = await client.users_info(user=user_id) + new_user_data = { + "firstname": user_info["user"]["real_name"].split()[0], + "lastname": user_info["user"]["real_name"].split()[1], + "email": user_info["user"]["profile"]["email"], + "uuid": user_info["user"]["id"], + "profile": user_info["user"]["profile"]["image_512"], + } + response = await user_manager.registerUser(new_user_data) + return response["status"] + + @app.event("reaction_added") async def reaction_add(body, logger, ack, say, client): await ack() @@ -45,6 +88,8 @@ async def reaction_add(body, logger, ack, say, client): reactions = await client.reactions_get( channel=event["item"]["channel"], timestamp=event["item"]["ts"] ) + + # for reaction in reactions.data["message"]["reactions"]: # if reaction["name"] == "clown_face": # if ( @@ -63,14 +108,17 @@ async def reaction_del(body, logger, ack): await ack() - @app.event(event="message") async def handle_message_events(body, say, ack, logger, client, message, response): # logger.info(body) + pprint(body) event = body.get("event", {}) channel_id = event.get("channel") user_id = event.get("user") + await ack() + await check_user_registration(user_id, client) + # Check user is the milk man and then add a milk react if user_id in auto_react_lookup.keys(): rand_num = random.randrange(0, 6) @@ -87,6 +135,7 @@ async def handle_message_events(body, say, ack, logger, client, message, respons await say("hi") pprint(environ) + # if text == "!milk": # await ack() # members = await client.conversations_members(channel=channel_id) @@ -95,8 +144,8 @@ async def handle_message_events(body, say, ack, logger, client, message, respons # await client.reactions_add( # channel=channel_id, name="glass_of_milk", timestamp=message["ts"] # ) - # pprint(member_data.data) - # await say("test") +# pprint(member_data.data) +# await say("test") # if text == "vader": # await ack() # blocks = await block_utils.image_block( diff --git a/testing_libs.py b/testing_libs.py new file mode 100644 index 0000000..ac627be --- /dev/null +++ b/testing_libs.py @@ -0,0 +1,36 @@ +from libs import http +import asyncio + + +user_requester = http.users.UserRequests( + "https://priceybot.au", "jkcGd6r6zJrd05RnKnU3pWm7xlo6enBj" +) + + +async def getUser(user_id): + data = await user_requester.getUser(user_id) + print(data) + + +async def registerUser(user_data): + response = await user_requester.registerUser(user_data) + print(response) + + +loop = asyncio.get_event_loop() + +data = { + "firstname": "Test2", + "lastname": "User2", + "email": "test@benjamyn.love2", + "uuid": "U1111112", + "profile": "https://benjamyn.love/PriceyBot.png", +} + +tasks = [ + loop.create_task(getUser("U05FN1F9ZCG")), + loop.create_task(registerUser(data)), +] + +loop.run_until_complete(asyncio.wait(tasks)) +loop.close() From 09611fa95a6743ee98e91175250e864b673f283a Mon Sep 17 00:00:00 2001 From: Benjamyn Love Date: Sun, 15 Oct 2023 18:58:02 +1100 Subject: [PATCH 2/6] No look --- testing_libs.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/testing_libs.py b/testing_libs.py index ac627be..e4a6360 100644 --- a/testing_libs.py +++ b/testing_libs.py @@ -2,9 +2,7 @@ from libs import http import asyncio -user_requester = http.users.UserRequests( - "https://priceybot.au", "jkcGd6r6zJrd05RnKnU3pWm7xlo6enBj" -) +user_requester = http.users.UserRequests("https://priceybot.au", "API_KEY") async def getUser(user_id): From a85da28dddaa623fe0d588b5b24e58047b51e754 Mon Sep 17 00:00:00 2001 From: Benjamyn Love Date: Sun, 15 Oct 2023 19:31:01 +1100 Subject: [PATCH 3/6] Actually send the user id moron --- slackbot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slackbot.py b/slackbot.py index 0890fca..ae96cae 100644 --- a/slackbot.py +++ b/slackbot.py @@ -44,7 +44,7 @@ async def check_user_registration(user_id: str, client) -> bool: async with r.pipeline(transaction=True) as pipe: user_exists = await pipe.get(user_id).execute() if user_exists[0] is None: - if check_user_exists() is True: + if check_user_exists(user_id) is True: await pipe.set(user_id, 1) return True else: From 99d3764932a886dd7ff4536858e2c5abd3d12cb3 Mon Sep 17 00:00:00 2001 From: Benjamyn Love Date: Sun, 15 Oct 2023 19:39:20 +1100 Subject: [PATCH 4/6] Fix registration --- slackbot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slackbot.py b/slackbot.py index ae96cae..c2b6a17 100644 --- a/slackbot.py +++ b/slackbot.py @@ -65,9 +65,9 @@ async def register_user(user_id: str, client): # lookup the user_id to get account info user_info = await client.users_info(user=user_id) new_user_data = { - "firstname": user_info["user"]["real_name"].split()[0], - "lastname": user_info["user"]["real_name"].split()[1], - "email": user_info["user"]["profile"]["email"], + "firstname": user_info["user"]["profile"]["first_name"], + "lastname": user_info["user"]["profile"]["last_name"], + "email": f"{user_info['user']['profile']['display_name_normalized']}@nexigen.digital", "uuid": user_info["user"]["id"], "profile": user_info["user"]["profile"]["image_512"], } From fbe54b416245007297e16e0037149e55fef17824 Mon Sep 17 00:00:00 2001 From: Benjamyn Love Date: Sun, 15 Oct 2023 19:41:10 +1100 Subject: [PATCH 5/6] Consistency is key --- libs/http/users.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/http/users.py b/libs/http/users.py index 3f3ff5b..5f99460 100644 --- a/libs/http/users.py +++ b/libs/http/users.py @@ -26,6 +26,6 @@ class UserRequests: async with session.post("/api/user/register", json=user_data) as data: if data.status != 200: - return False + return {"status": False} response = await data.json() return response From 92e339aae4ed4afe5d950facb0acee23547936d8 Mon Sep 17 00:00:00 2001 From: Benjamyn Love Date: Sun, 15 Oct 2023 19:45:09 +1100 Subject: [PATCH 6/6] Log less --- slackbot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slackbot.py b/slackbot.py index c2b6a17..cf3dfe3 100644 --- a/slackbot.py +++ b/slackbot.py @@ -13,7 +13,7 @@ import redis.asyncio as redis libs.benv.load_env() -logging.basicConfig(level=logging.DEBUG) +logging.basicConfig(level=logging.INFO) redis_client = redis.Redis()