Giter Club home page Giter Club logo

pax-academia's Introduction

Pax Academia

General purpose utility bot for the Homework Help Discord server

How to Contribute

To contribute to this project, please read the Contributing Guidelines.

Running bot

To run the bot, navigate to the root directory and run the following command:

python main.py

You should see the the following text in your terminal:

<botname> has connected to Discord!

where <botname> is the name of your bot.

pax-academia's People

Contributors

danparizher avatar dddictionary avatar dependabot[bot] avatar gabemillikan avatar justsharan avatar mountainaero avatar pharmony01 avatar sebastiaan-daniels avatar woseek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

pax-academia's Issues

Type Refactoring

A lot of functions, methods, and variables are typed incorrectly throughout the project. This issue serves as a tracker for correcting those types.

The incorrect types can cause a number of problems, including:

  • Errors when the code is run.
  • Difficulties in debugging the code.
  • Difficulties in understanding the code.

This issue should be fixed to improve the quality of the code and to make it more maintainable.

Add code block detection using lexers

If a user pastes their code without it being formatted in a code block, Pax should detect it and respond with the following: /tip Format Your Code

image

/see-apps improvements

  • Change /see-apps subcommand:spam to match all other subcommands in appearance (when empty).
  • Remove introductory embed (before clicking ➡️ after using see-apps) instead introduce dummy command with example applications.
    • Dummy command should mirror real command, only differentiated by prefix dummy- and manipulating test-data
    • Dummy command should have at least one application in every possible state
    • Dummy command should reset to original test data with subcommand
    • [Optional] Dummy entries should detail what to be done with them i.e. by putting "Mark me as Spam" in the name field.
    • [Optional] Dummy entries should include instructions / what is expected to happen, or how to undo an action

Renaming:

  • Rename Applicant nameApplicant Name
  • Rename first nameFirst Name
  • Rename Second Opinion requiredSecond Opinion Required
  • Rename Time zoneTime Zone
  • Rename Hours available per weekHours Available per Week
  • Rename Why staff?Why do you want to become a staff member?
  • Rename Why do you want to become a staff memberWhy do you want to become a staff member?
  • Rename Contribute reasonHow will you contribute if you become a staff member?
  • Rename How can you contribute if you are given staffHow will you contribute if you become a staff member?
  • Rename Submission timeSubmission Time
  • Rename Like / DislikesLikes / Dislikes

If introductory embed is not removed generally:

  • Remove introductory embed when using /see-apps specific_id

Consider:

  • Renaming /see-apps into /see-applications OR /see-sapps (see staff apps)
  • Introducing subcommand list in command to group options all, spam accepted denied

Might have some more when the dummy command is here, since we now only have a real application now and I can't test anymore...

Implement `/view-logs`

Implement a /view-logs command that retrieves a user-specified number of logs from the log.txt file, so that developers can actively test and debug on production code that is difficult to replicate in testing environments.

Self-inflicted Pax alert

Not sure if this has been talked about, but I would think you shouldn't be able to get an alert from your own message. I already know that I said it, so it doesn't benefit me to get a ping for it.

Bug: Staff application error in DM's

/apply-for-staff raises an error when used in direct messages due to the bot trying to access the joined_at attribute, which is not present in DM's.

A check should be added to prevent users from being able to use the command in DM's

Create `AutoDeletionDetection.py`

Required by staff team: Create a system that detects user messages being deleted in quick succession.

  • Should generate a report showing messages deleted in the last hour, every hour, in increments of ten minutes.
  • Determine control limits for anomaly criteria
  • When the algorithm detects that a user surpasses the control limit, their roles will be cached, and the user will be muted
  • Create a button that allows staff to unmute the individual in cases of false positives

Enhancement: Assert whether environment variables are loaded correctly

Some env variables are crucial for the bot to function correctly. (bot token, deepl token, etc...)
When loading the tokens through os, an assert statement should follow to verify whether or not a correct variable is loaded.

(a check can be by length, it must be an int, etc...)

Slowmode Management (for #sensitive-topics)

Pax should monitor activity in a channel and should be able to change slowmode based on activity, number of users, or a schedule.

  • Monitor #sensitive-topics activity (perhaps in DB)

  • -->(Query) How many messages have been sent in the past 20 minutes.

  • -->(Query) How many messages have been sent in the past 20 minutes.

  • -->(Query) Any other metric that might be useful

  • Command to set slowmode lower and upper range /slowmode range <range-min> <range-max> (max range would be OFF to 6h)

  • Command to schedule slowmode: /slowmode schedule <slowmode-mode [OFF-6h]> <duration active>* <start-delay>
    *should return to default after duration. <start-delay> is an optional parameter everything else should be required.

  • Command to set default slow mode: /slowmode default <mode>*
    * Modes: OFF (no slowmode), no-interact (Pax does nothing), auto (Pax does stuff).

  • Command to set current slow mode: /slowmode mode <mode> (modes described above)

Optional:

  • Command to set criteria for "Auto" mode to increase slowmode
  • Command to set criteria for "Auto" mode to decrease slowmode

Make any and all embedded error messages ephemeral

Error messages are currently displayed as embedded messages within the user interface. This can be confusing for users, as they may not immediately understand that the message is an error and how to address it. In addition, these error messages can be visually cluttered and disruptive to the user experience.

Make all error messages in the Discord bot ephemeral. This will help to ensure that users are not confused by the messages and can focus on the main content of the bot.

[Alerts] Further customisation of Alerts.

  • Ability to set list of ignored channel (categories)
  • Ability to set list of ignored roles
  • Ability to set list of ignored users (at least ignore self as an option)
  • Ability to pause/suspend alerts for a period of time

Questionable if we should implement or not:

  • Above abilities, but whitelist instead of blacklist (setting target channels, target roles, target users)

Embed Title overflow in `/define`

Ignoring exception in command define:
Traceback (most recent call last):
  File "C:\Production code\Pax-Academia\venv\Lib\site-packages\discord\commands\core.py", line 124, in wrapped
    ret = await coro(arg)
          ^^^^^^^^^^^^^^^
  File "C:\Production code\Pax-Academia\venv\Lib\site-packages\discord\commands\core.py", line 978, in _invoke
    await self.callback(self.cog, ctx, **kwargs)
  File "C:\Production code\Pax-Academia\util\Logging.py", line 65, in wrapper
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Production code\Pax-Academia\cogs\Dictionary.py", line 522, in define
    await ctx.respond(embed=embed)
  File "C:\Production code\Pax-Academia\venv\Lib\site-packages\discord\commands\context.py", line 286, in respond
    return await self.followup.send(*args, **kwargs)  # self.send_followup
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Production code\Pax-Academia\venv\Lib\site-packages\discord\webhook\async_.py", line 1745, in send
    data = await adapter.execute_webhook(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Production code\Pax-Academia\venv\Lib\site-packages\discord\webhook\async_.py", line 221, in request
    raise HTTPException(response, data)
discord.errors.HTTPException: 400 Bad Request (error code: 50035): Invalid Form Body
In embeds.0.title: Must be 256 or fewer in length.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Production code\Pax-Academia\venv\Lib\site-packages\discord\bot.py", line 1114, in invoke_application_command
    await ctx.command.invoke(ctx)
  File "C:\Production code\Pax-Academia\venv\Lib\site-packages\discord\commands\core.py", line 375, in invoke
    await injected(ctx)
  File "C:\Production code\Pax-Academia\venv\Lib\site-packages\discord\commands\core.py", line 132, in wrapped
    raise ApplicationCommandInvokeError(exc) from exc
discord.errors.ApplicationCommandInvokeError: Application Command raised an exception: HTTPException: 400 Bad Request (error code: 50035): Invalid Form Body
In embeds.0.title: Must be 256 or fewer in length.

Error when DMing user with DM's off

An error occurs when trying to send a direct message to someone who has their DM's turned off

Ignoring exception in on_message
Traceback (most recent call last):
  File "C:\Production code\Pax-Academia\venv\lib\site-packages\discord\client.py", line 377, in _run_event
    await coro(*args, **kwargs)
  File "C:\Production code\Pax-Academia\cogs\Alerts.py", line 211, in on_message
    await user_alerts()
  File "C:\Production code\Pax-Academia\cogs\Alerts.py", line 171, in user_alerts
    await user.send(embed=embed)
  File "C:\Production code\Pax-Academia\venv\lib\site-packages\discord\abc.py", line 1580, in send
    data = await state.http.send_message(
  File "C:\Production code\Pax-Academia\venv\lib\site-packages\discord\http.py", line 353, in request
    raise Forbidden(response, data)
discord.errors.Forbidden: 403 Forbidden (error code: 50007): Cannot send messages to this user

Add ability to give feedback on experimental commands

As Pax commands start becoming more experimental, and a little more invasive with on_message events, Some commands that are in early production might give false positives/be sent incorrectly.

An easy way to decorate a command as experimental should be created to ask active, verified members of the community to share their feedback with experimental commands. This feedback will be stored in the database and will be used by developers to evaluate their code before making it invasive/forced

Check Requirements Command for Valued Contributors/Helper roles

Builds on #45: User requires the following aspects for helper roles. [Staff-only command]

  • Time in server

    • (alternative condition if user left and rejoined the server)
  • #164

  • Certain amount of messages in any channel in a certain time frame.

  • Account age

The exact requirements for Valued Contributors must not be publicised!
The information in question can be found in #vc-protocols and should also not show up in source-code.

Role requirements may be subject to debate or change.

Multipost Utility Rework

"The chief utility of the feature is that it alerts helpers as to when (and where) a question has been posted elsewhere, so they’re put on notice and don’t unwittingly waste their time working on a question that already may have been answered (this is also why I don’t think auto-deletion is necessary, in addition to the issue with false-positive deletions, which may prove especially problematic when people delete and repost a question in the correct channel). But it is true that Pax’s warnings can add up and become an eyesore. So what if we take a middle-ground approach? Just as people have been doing for a while now, multiposted questions can be flagged with a reaction by the bot indicating so; this would put the helpers on notice. And the warnings can be deleted after some time has passed. Additionally, perhaps some threshold—such as the same content being posted in more than two channels—can be put in place wherein all multiposted messages are deleted except for the most recent one.

The "3+and-delete" rule would add an extra layer of protection against the automated deletion of nonoffending messages and, combined with the timed auto-deletion of warnings, would work to suppress extraneous messages all around." -@woseek

Example:

#math-a: Original Message - Flagged (Upon first multipost)
#math-b: First multipost - Flagged and Warned
#math-c: Second multipost - Deleted
#math-d: Third multipost - Deleted
-@arborym

Staff application command [SAC] stage 2

Builds on #41 : Additionally SAC should check if the user has

  • At least 500 messages in any channel.

Also optionally:

  • Send ?modlogs log of user in #google-form-submissions channel automatically upon (valid*) received application.
    • Wouldn't work if someone submitted a troll application.
    • Shouldn't work with staff account names.

Message count in help channels.

Count Messages in channels, which are in Channel Categories that end in "Help" (or idk you could do smth more clever than that).

PII in bandwith database

Detail saves the entire link when downloading an attachment

image
This can be used directly to identify persons or download content. EVEN if it was posted in a channel you do not have access to.

We should consider masking this one way or another, so that the full link isn't saved. I recommend keeping the HTTP POST/ GET but instead of the full link, only saving the filetype extension.

https://github.com/Arborym/Pax-Academia/blob/8290648b0cdf200c9af1a881a1f693715e8fbd5f/util/bandwidth.py#L25

Basic staff application command

User command which gives user link to the staff application form, if they meet the following criteria:

  • Discord account age minimum 1 year.
  • Server member for at least 30 days.

Edit:

  • There should be a log of who requested the staff application form.

Rename /ask and make it anonymous

There are two issues with our current /ask command:

  1. Sometimes, users think that that is the command to ask a question. So they do /ask What's 2+2?, then never get a response.
  2. It isn't anonymous, so whoever uses the command will almost assuredly be pinged once the user finally does ask their question. Just because I want the user to ask their question, doesn't mean I want to commit to answering it.

Me: /ask
Bot: @gabe used the /ask command: ask your question
Them: Okay what is 2 + 2?
Them: @gabe why aren't you answering my question?

Related to this thread in Discord

Surveys log on every message

Every message that is sent triggers the Surveys log.
f"$ sent a survey in {message.channel.name}, bot responded".

This clutters the logs immensely as there is a message sent every two seconds.

Bot has no write permissions in certain channels

The bot isn't allowed to send messages in some channels, which results in the following error:

Ignoring exception in on_message
Traceback (most recent call last):
  File "C:\Production code\Pax-Academia\venv\lib\site-packages\discord\client.py", line 377, in _run_event
    await coro(*args, **kwargs)
  File "C:\Production code\Pax-Academia\cogs\Surveys.py", line 34, in on_message
    await message.channel.send(
  File "C:\Production code\Pax-Academia\venv\lib\site-packages\discord\abc.py", line 1580, in send
    data = await state.http.send_message(
  File "C:\Production code\Pax-Academia\venv\lib\site-packages\discord\http.py", line 353, in request
    raise Forbidden(response, data)
discord.errors.Forbidden: 403 Forbidden (error code: 50013): Missing Permissions

Database should be reworked

The current database.sqlite should be reworked to be a proper, relationship based db.
(Which is what I'm working on)

Multipost warning twice in a row

When a user sends two separate multiposts (with differing fingerprints) in the same channel, we can delete the original multipost message such that only the most recent one remains.

Relevant discord thread here.

Set a limit on message content when receiving user alerts

Traceback (most recent call last):
  File "C:\Production code\Pax-Academia\venv\lib\site-packages\discord\client.py", line 377, in _run_event
    await coro(*args, **kwargs)
  File "C:\Production code\Pax-Academia\cogs\Alerts.py", line 258, in on_message
    await user_alerts()
  File "C:\Production code\Pax-Academia\cogs\Alerts.py", line 204, in user_alerts
    await user.send(embed=embed)
  File "C:\Production code\Pax-Academia\venv\lib\site-packages\discord\abc.py", line 1580, in send
    data = await state.http.send_message(
  File "C:\Production code\Pax-Academia\venv\lib\site-packages\discord\http.py", line 359, in request
    raise HTTPException(response, data)
discord.errors.HTTPException: 400 Bad Request (error code: 50035): Invalid Form Body
In embeds.0.fields.0.value: Must be 1024 or fewer in length.

Make sure that the value of this field does not exceed 1024 characters in length.

Allow mass-muting and -kicking of users

Especially in raid situations outright banning all accounts which joined during a certain time will inevitably lead to a small number of false positives. Having available a possibility to mass-mute and mass-kick suspected accounts allows legit users to come back and ask to be unmuted.

In order to streamline this process, both a command /mmute for mass-muting and /mkick for mass-kicking as well as a combination of both, /mmutekick that first mutes and then kicks all users could be implemented. The syntax of the command should be compatible with the one used for Aperture at the moment.

Bug: Message count error in DMs

Every time a user sends a direct message to the bot (not a command), the bot raises an error in messagecounter.py

Traceback (most recent call last):
  File "xxx\client.py", line 378, in _run_event
    await coro(*args, **kwargs)
  File "xxx\MessageCounter.py", line 31, in on_message
    category_name = message.channel.category.name.lower()
                    ^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'DMChannel' object has no attribute 'category'

Fix: exit (return) event (on_message) if message is a direct message

/translate command is not asynchronous

Problem

The deepl.translate function is synchronous. This means that when someone uses the command, the entire bot halts all other activities (i.e. other commands and background tasks like moderation) and waits for the DeepL API to return the result. This may take a while (especially with rate limiting!), so we would really like this to be asynchronous.

Potential Solutions

  1. pass the call off into another thread and asynchronously busy-wait for it to be completed. For example:

    import threading
    import asyncio
    
    # this is psuedocode (don't want to make this issue comment too long)
    # - the arguments to deepl.translate are more nuanced than this
    # - thread.result() is not a real function, we would need to use a mutable container
    # - it would be nice to raise exceptions from the thread
    async def translate(text, src, dst):
        thread = threading.Thread(deepl.translate, args=(text, src, dst))
        thread.start()
        while thread.is_running():
            await asyncio.sleep(0.1)
        return thread.result()
  2. Use a different library that supports async calls,. I found deepl-tr-async, but it's an extremely heavyweight library and I don't really think it makes sense to add all of those dependencies.

  3. A better solution that would take a lot more time would be to reimplement the deepl api (or fork it) using aiohttp to make the call itself asynchronous.

Update check-requirements command/form

  • When user submits an application on google form run /check-requirements and return result in column as yes/no
  • When user submits an application check if user ran /check-requirements previously and return result in column as yes/no.

Additional (Optional Tasks

  • When user submits an application on the google form check if user is (still) valid applicant.
    • User is in server.
    • User ID is not already a Staff member.
    • User doesn't currently have the Muted role.

Questions for staff form in Discord.

Enhancement: Adapt to new discord usernames

With the new discord username system going into place, the code should be adapted to incorporate these new names and slowly remove the discriminators.

At the moment, there are no errors raised by the program, but that could change in the near future.
Most affected are logging and staffapps which should be looked at.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.