diff --git a/database.py b/database.py new file mode 100644 index 0000000..87c0aa0 --- /dev/null +++ b/database.py @@ -0,0 +1,59 @@ +async def user_exists(conn, user_id, guild_id): + cur = conn.cursor() + + cur.execute("SELECT user_id FROM member WHERE user_id=%s AND guild_id=%s", (user_id, guild_id)) + result = cur.fetchone() + + cur.close() + + return result != None + + +async def guild_exists(conn, guild_id): + cur = conn.cursor() + + cur.execute("SELECT guild_id FROM guild WHERE guild_id=%s", (guild_id,)) + result = cur.fetchone() + + cur.close() + + return result != None + +async def insert_poll(conn, poll_id, guild_id, question): + cur = conn.cursor() + + cur.execute( + "INSERT INTO " + "poll (poll_id, guild_id, question, opened) " + "VALUES (%s, %s, %s, true)", + (poll_id, guild_id, question) + ) + + conn.commit() + cur.close() + +async def insert_guild(conn, guild_id): + cur = conn.cursor() + cur.execute( + "INSERT INTO " + "guild (guild_id) " + "VALUES (%s)", + (guild_id,) + ) + + conn.commit() + cur.close() + + +async def insert_user(conn, user_id, guild_id, global_name, avatar): + cur = conn.cursor() + + cur.execute( + "INSERT INTO " + "member (user_id, guild_id, global_name, avatar) " + "VALUES (%s, %s, %s, %s)", + (user_id, guild_id, global_name, avatar) + ) + + conn.commit() + cur.close() diff --git a/database.sql b/database.sql index cadf57b..34b5b0f 100644 --- a/database.sql +++ b/database.sql @@ -1,37 +1,50 @@ -DROP TABLE IF EXISTS vote_utilisateur; -DROP TABLE IF EXISTS utilisateur; +DROP TABLE IF EXISTS vote_member; +DROP TABLE IF EXISTS member; DROP TABLE IF EXISTS poll; DROP TABLE IF EXISTS vote; +DROP TABLE IF EXISTS guild; - -CREATE TABLE vote ( - vote_id UUID, - vote_option VARCHAR(255), - nbr_vote INT, - PRIMARY KEY (vote_id) +CREATE TABLE guild +( + guild_id VARCHAR(255), + PRIMARY KEY (guild_id) ); -CREATE TABLE poll ( - poll_id UUID, - vote_id UUID, - question VARCHAR(255), - opened BOOLEAN, - PRIMARY KEY (poll_id), - FOREIGN KEY (vote_id) REFERENCES vote(vote_id) +CREATE TABLE vote +( + vote_id UUID, + vote_option VARCHAR(255), + PRIMARY KEY (vote_id) ); -CREATE TABLE utilisateur ( - user_id BIGINT, - global_name VARCHAR(255), - avatar TEXT, - PRIMARY KEY (user_id) +CREATE TABLE poll +( + poll_id UUID, + guild_id VARCHAR(255), + question VARCHAR(255), + opened BOOLEAN, + PRIMARY KEY (poll_id), + FOREIGN KEY (guild_id) REFERENCES guild (guild_id) ); -CREATE TABLE vote_utilisateur ( - user_id BIGINT, - vote_id UUID, - poll_id UUID, - FOREIGN KEY (user_id) REFERENCES utilisateur(user_id), - FOREIGN KEY (vote_id) REFERENCES vote(vote_id), - FOREIGN KEY (poll_id) REFERENCES poll(poll_id) +CREATE TABLE member +( + user_id VARCHAR(255), + guild_id VARCHAR(255), + global_name VARCHAR(255), + avatar TEXT, + PRIMARY KEY (user_id), + FOREIGN KEY (guild_id) REFERENCES guild (guild_id) ); + +CREATE TABLE vote_member +( + user_id VARCHAR(255), + guild_id VARCHAR(255), + vote_id UUID, + poll_id UUID, + FOREIGN KEY (guild_id) REFERENCES guild (guild_id), + FOREIGN KEY (user_id) REFERENCES member (user_id), + FOREIGN KEY (vote_id) REFERENCES vote (vote_id), + FOREIGN KEY (poll_id) REFERENCES poll (poll_id) +); \ No newline at end of file diff --git a/main.py b/main.py index d4fe303..7f47724 100644 --- a/main.py +++ b/main.py @@ -1,12 +1,14 @@ import asyncio +import json from typing import Any +from uuid import uuid4 +import psycopg2 import requests import websockets -import json - from websockets import Response +from database import user_exists, insert_user, guild_exists, insert_guild from enums import OpCode, EventTitle, InteractionType with open('configuration.json', 'r') as file: @@ -17,31 +19,16 @@ GATEWAY_URL: str = "wss://gateway.discord.gg/?v=10&encoding=json" API_URL: str = "https://discord.com/api/v10" TOKEN: str = CONFIG["TOKEN"] - -async def create_button(): - body: dict = { - "content": "This is a message with components", - "components": [ - { - "type": 1, - "components": [ - { - "type": 2, - "label": "Click me!", - "style": 1, - "custom_id": "click_one" - } - ] - - } - ] - } - - res = requests.post(f"{API_URL}/channels/840107060901052426/messages", json=body, - headers={"Authorization": f"Bot {TOKEN}"}) - - if res.status_code != 201: - print(res.json()) +try: + conn = psycopg2.connect( + database=CONFIG["DB_NAME"], + user=CONFIG["DB_USER"], + password=CONFIG["DB_PASSWORD"], + host=CONFIG["DB_ADDRESS"], + port=CONFIG["DB_PORT"] + ) +except Exception as e: + raise e async def create_command(): @@ -52,7 +39,6 @@ async def create_command(): } res: Response = requests.post(f"{API_URL}/applications/{APPLICATION_ID}/commands", json=body, headers={"Authorization": f"Bot {TOKEN}"}) - print(res) async def init_commands(): @@ -68,14 +54,12 @@ async def init_commands(): await create_command() -async def create_poll(interaction_id: int, interaction_token: str, components: list[dict]): +async def create_poll(interaction_id: str, interaction_token: str, components: list[dict]): question = next( (comp["components"][0]["value"] for comp in components if comp["components"][0]["custom_id"] == "label"), "Question du poll" ) - print(components) - vote_options = "" buttons = [] for index, comp in enumerate(components): @@ -142,18 +126,21 @@ async def identify(websocket): "since": 91879201, "afk": False }, - "intents": 50364416, + "intents": 36871, } } await websocket.send(json.dumps(payload)) -async def create_poll_form(interaction_id: int, interaction_token: str): +async def create_poll_form(interaction_id: str, interaction_token: str, guild_id: str): + poll_id = uuid4() + if not await guild_exists(conn=conn, guild_id=guild_id): + await insert_guild(conn=conn, guild_id=guild_id) body = { "type": 9, "data": { "title": "Créer un vote", - "custom_id": "poll_id_create", + "custom_id": poll_id, "components": [ { "type": 1, @@ -242,9 +229,13 @@ async def heartbeat(websocket, interval): await asyncio.sleep(interval / 1000) await websocket.send(json.dumps({"op": OpCode.HEARTBEAT, "d": None})) -async def send_private_response(interaction_id: int, interaction_token: str, custom_id: str, user_id: str): - # Récupérer le nom de l'option corespondant à l'id en BDD +async def vote_confirmation(interaction_id: str, interaction_token: str, custom_id: str, user_id: str, guild_id: str, + avatar: str, global_name: str): + if not await user_exists(conn=conn, user_id=user_id, guild_id=guild_id): + if not await guild_exists(conn=conn, guild_id=guild_id): + await insert_guild(conn=conn, guild_id=guild_id) + await insert_user(conn=conn, user_id=user_id, avatar=avatar, guild_id=guild_id, global_name=global_name) body = { "type": 4, "data": { @@ -263,6 +254,7 @@ async def send_private_response(interaction_id: int, interaction_token: str, cus else: print(res) + async def get_event(response: Any): match response["t"]: case EventTitle.MESSAGE_CREATE: @@ -270,16 +262,25 @@ async def get_event(response: Any): case EventTitle.INTERACTION_CREATE: if response["d"]["type"] == InteractionType.MODAL_SUBMIT: await create_poll( - int(response["d"]["id"]), + response["d"]["id"], response["d"]["token"], response["d"]["data"]["components"] - ) + ) elif response["d"]["type"] == InteractionType.MESSAGE_COMPONENT: custom_id = response["d"]["data"]["custom_id"] user_id = response["d"]["member"]["user"]["id"] - await send_private_response(int(response["d"]["id"]), response["d"]["token"], custom_id, user_id) + await vote_confirmation(interaction_id=response["d"]["id"], + interaction_token=response["d"]["token"], + custom_id=custom_id, + user_id=user_id, + guild_id=response["d"]["guild"]["id"], + avatar=response["d"]["member"]["user"]["avatar"], + global_name=response["d"]["member"]["user"]["global_name"]) elif response["d"]["type"] == InteractionType.APPLICATION_COMMAND: - await create_poll_form(int(response["d"]["id"]), response["d"]["token"]) + print(response["d"]) + await create_poll_form(interaction_id=response["d"]["id"], + interaction_token=response["d"]["token"], + guild_id=response["d"]["guild_id"]) case _: print(response) @@ -305,7 +306,9 @@ async def connect(): async def main(): gateway_connect = asyncio.create_task(connect()) # await init_commands() - # await create_button() + # guild_ids = await get_guilds_ids() + # for guild_id in guild_ids: + # await get_guild_members(guild_id) await gateway_connect