import logging import asyncio import aiomysql import random from os import environ from pprint import pprint 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.INFO) 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 = { "U02GTCPB2CB": {"text": "glass_of_milk", "chance": -1}, # agoodlet "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 "U05ERL0PSBY": {"text": "gif", "chance": 3} # mginger } 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 await check_user_exists(user_id) 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).execute() 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"]["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"], } 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() event = body.get("event") user = event.get("item_user") channel_id = event.get("channel") reaction = event.get("reaction") if ( user == "U05ES1730UE" and event["reaction"] == "clown_face" ): # If pricey gets clown reacted 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 ( # int(reaction["count"]) >= 3 # and messages_already_reacted.get(event["item"]["ts"], False) # is False # ): # messages_already_reacted[event["item"]["ts"]] = True # await say( # f"Pricey has been clown reacted {reaction['count']} times on a recent post" # ) @app.event("reaction_removed") 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) print(rand_num) if rand_num > auto_react_lookup[user_id]["chance"]: await client.reactions_add( channel=channel_id, name=auto_react_lookup[user_id]["text"], timestamp=message["ts"], ) text = event.get("text") if text == "x": await say("hi") pprint(environ) # if text == "!milk": # await ack() # members = await client.conversations_members(channel=channel_id) # members = members["members"] # member_data = await client.users_info(user=members[0]) # await client.reactions_add( # channel=channel_id, name="glass_of_milk", timestamp=message["ts"] # ) # pprint(member_data.data) # await say("test") # if text == "vader": # await ack() # blocks = await block_utils.image_block( # "https://benjamyn.love/vader.gif", "I fixed it mother bitch" # ) # await say(blocks=blocks) # if text == "test image action": # await ack() # blocks = await block_utils.image_block( # "https://benjamyn.love/topright.png", "Top right buddy" # ) # await say(blocks=blocks) # if text == "gimmie": # pool = await aiomysql.create_pool( # host=environ.get("MYSQL_HOST"), # port=int(environ.get("MYSQL_PORT")), # user=environ.get("MYSQL_USER"), # password=environ.get("MYSQL_PASS"), # db=environ.get("MYSQL_DB"), # loop=asyncio.get_event_loop(), # ) # async with pool.acquire() as conn: # async with conn.cursor() as cur: # await cur.execute( # "select quote from tblQuotes order by rand() limit 1;" # ) # (r,) = await cur.fetchone() # await say(text=r.decode()) # pool.close() # await pool.wait_closed() # await ack() @app.command(command="/socialcredit") async def handle_social_credit(body, client, say, logger, ack): await ack() user_id = body.get("user_id") await say(f"This feature is under development") @app.command(command="/test") async def handle_test_command(body, say, ack, respond, context, logger): logger.info(body) await ack() await say("Responding to slash commands") if __name__ == "__main__": app.start(5000)