diff --git a/orderbot/__main__.py b/orderbot/__main__.py index df3215c..4a645d2 100644 --- a/orderbot/__main__.py +++ b/orderbot/__main__.py @@ -1,13 +1,15 @@ -from .src import github_bot -from .src import discord_bot +import logging import os + from dotenv import load_dotenv -import logging + +from .src import discord_bot, github_bot # write to file with time and level logging.basicConfig( - filename='orderbot.log', - filemode='w', + handlers=[ + logging.FileHandler("orderbot.log", mode="w"), + ], format='[%(asctime)s][%(levelname)s][%(message)s]', datefmt='%d-%b-%y %H:%M:%S', level=logging.DEBUG diff --git a/orderbot/src/discord_bot.py b/orderbot/src/discord_bot.py index d47e753..ebaca15 100644 --- a/orderbot/src/discord_bot.py +++ b/orderbot/src/discord_bot.py @@ -17,22 +17,25 @@ def __init__(self, token, github_bot: GithubBot): self.token = token self.github_bot = github_bot - def repr_message(self, message): - return f"Message: {message.content} from {message.author} in {message.channel} at {message.created_at} with {message.reactions} reactions" - def run(self): super().run(self.token) + def repr_message(self, message): + return f"Message: {message.content} from {message.author} in {message.channel} at {message.created_at} with {message.reactions} reactions" + async def create_thread_issue(self, message): # create a new issue on github - await self.github_bot.create_issue(f"{message.channel.name} - {message.author.display_name}", f"[{message.author}]" + message.content, os.getenv("GITHUB_PROJECT_NUMBER")) + issue = await self.github_bot.create_issue(f"{message.channel.name} - {message.author.display_name}", f"[{message.author}]" + message.content, os.getenv("GITHUB_PROJECT_NUMBER")) # create thread - thread = await message.create_thread(name=message.author.display_name) - await thread.send("Issue created, please wait for a staff member to respond") + issue_number = issue["createIssue"]["issue"]["number"] + thread = await message.create_thread(name=f"{message.author.display_name} #{issue.number}") + # await thread.send("Issue created, please wait for a staff member to respond") + + logging.info(f"Created issue #{issue_number} for {message.author} in {message.channel.name}") async def on_ready(self, *args, **kwargs): - logging.debug(f"We have logged in as {self.user}") + logging.info(f"We have logged in as {self.user}") async def on_message(self, message: discord.Message): logging.debug(self.repr_message(message)) @@ -41,6 +44,10 @@ async def on_message(self, message: discord.Message): if message.author == self.user: return + # only reply to authorized users (to be defined later) + if "Bureau" not in [r.name for r in message.author.roles]: + return + # check if the message is a command if message.content.startswith("!"): # split the message into command and arguments @@ -57,20 +64,21 @@ async def on_message(self, message: discord.Message): # send an error message await message.channel.send("Invalid command") + channel = message.channel.name + if "#" in channel: + issue_number = int(channel.split("#")[-1]) + await self.github_bot.add_issue_comment(issue_number, f"[{message.author}] - {message.content}") + # on reaction async def on_message_edit(self, before, after): logging.debug(f"Message edited: {before} -> {after}") await self.on_message(after) async def on_raw_reaction_add(self, payload): - logging.debug(f"Raw reaction added: {payload}") - reaction = payload.emoji channel = self.get_channel(payload.channel_id) message = await channel.fetch_message(payload.message_id) user = self.get_user(payload.user_id) - print(f"Reaction: {reaction} from {user} in {channel} at {message.created_at} with {message.reactions} reactions") - if payload.emoji.name == "🧵": await self.create_thread_issue(message) diff --git a/orderbot/src/github_bot.py b/orderbot/src/github_bot.py index 60eed5c..eb9eeb1 100644 --- a/orderbot/src/github_bot.py +++ b/orderbot/src/github_bot.py @@ -4,6 +4,8 @@ from gql import Client, gql from gql.transport.aiohttp import AIOHTTPTransport +logging.getLogger("gql").setLevel(logging.WARNING) + class GithubBot(): def __init__(self, org, repo, token): @@ -98,7 +100,7 @@ async def fetch_repo(self, name): ) return response - async def fetch_issue(self, repo_name, title): + async def fetch_issue_by_name(self, repo_name, title): # fetch the issue in the repository query = gql( """ @@ -124,6 +126,32 @@ async def fetch_issue(self, repo_name, title): ) return response + async def fetch_issue_by_number(self, repo_name, number): + # fetch the issue in the repository + query = gql( + """ + query ($login: String!, $name: String!, $number: Int!) { + organization(login: $login) { + repository(name: $name) { + issue(number: $number) { + id + } + } + } + } + """ + ) + + response = await self.client.execute_async( + query, + variable_values={ + "login": self.org, + "name": repo_name, + "number": int(number), + }, + ) + return response + async def create_issue(self, title, body, project_number): project = await self.fetch_projectv2_fields(project_number) repo = await self.fetch_repo(self.repo) @@ -172,16 +200,19 @@ async def create_issue(self, title, body, project_number): } ) + logging.info(f"Created issue {issue['createIssue']['issue']['number']}") + return issue - async def add_issue_comment(self): - # TODO test this + async def add_issue_comment(self, number, body): try: - issue_id = self.fetch_issue(self.repo, self.title)["organization"]["repository"]["issue"]["id"] + issue = await self.fetch_issue_by_number(self.repo, number) + issue_id = issue["organization"]["repository"]["issue"]["id"] except KeyError: logging.error("Issue not found") return + # add the comment to the issue query = gql( """ mutation ($body: String!, $subjectId: ID!) { @@ -192,12 +223,13 @@ async def add_issue_comment(self): """ ) - response = await self.client.execute_async( + comment = await self.client.execute_async( query, variable_values={ - "body": self.body, + "body": body, "subjectId": issue_id, - }, + } ) - return response \ No newline at end of file + logging.info(f"Added Github comment: {body} in issue {number}") + return comment \ No newline at end of file