Giter Club home page Giter Club logo

pluralkit's Introduction

PluralKit

PluralKit is a Discord bot meant for plural communities. It has features like message proxying through webhooks, switch tracking, system and member profiles, and more.

Do you just want to add PluralKit to your server? If so, you don't need any of this. Use the bot's invite link: https://discord.com/oauth2/authorize?client_id=466378653216014359&scope=bot%20applications.commands&permissions=536995904

PluralKit has a Discord server for support, feedback, and discussion: https://discord.gg/PczBt78

Requirements

Running the bot requires .NET 5, a PostgreSQL database and a Redis database. It should function on any system where the prerequisites are set up (including Windows).

Optionally, it can integrate with Sentry for error reporting and InfluxDB for aggregate statistics.

Configuration

Configuring the bot is done through a JSON configuration file. An example of the configuration format can be seen in pluralkit.conf.example. The configuration file needs to be placed in the bot's working directory (usually the repository root) and must be called pluralkit.conf.

The configuration file is in JSON format (albeit with a .conf extension). The following keys are available (using . to indicate a nested object level), bolded key names are required:

  • PluralKit.Bot.Token: the Discord bot token to connect with
  • PluralKit.Database: the URI of the database to connect to (in ADO.NET Npgsql format)
  • PluralKit.RedisAddr: the host:port of a Redis database to connect to
  • PluralKit.Bot.Prefixes: an array of command prefixes to use (default ["pk;", "pk!"]).
  • PluralKit.Bot.ClientId: the ID of the bot's user account, used for calculating the bot's own permissions and for the link in pk;invite.
  • PluralKit.SentryUrl (optional): the Sentry client key/DSN to report runtime errors to. If absent, disables Sentry integration.
  • PluralKit.InfluxUrl (optional): the URL to an InfluxDB server to report aggregate statistics to. An example of these stats can be seen on the public stats page.
  • PluralKit.InfluxDb (optional): the name of an InfluxDB database to report statistics to. If either this field or PluralKit.InfluxUrl are absent, InfluxDB reporting will be disabled.
  • PluralKit.LogDir (optional): the directory to save information and error logs to. If left blank, will default to logs/ in the current working directory.

The bot can also take configuration from environment variables, which will override the values read from the file. Here, use : (colon) or __ (double underscore) as a level separator (eg. export PluralKit__Bot__Token=foobar123) as per ASP.NET config.

Running

Docker

The easiest way to get the bot running is with Docker. The repository contains a docker-compose.yml file ready to use.

  • Clone this repository: git clone https://github.com/PluralKit/PluralKit
  • Create a pluralkit.conf file in the same directory as docker-compose.yml containing at least PluralKit.Bot.Token and PluralKit.Bot.ClientId fields
    • (PluralKit.Database is overridden in docker-compose.yml to point to the Postgres container)
  • Build the bot: docker-compose build
  • Run the bot: docker-compose up

In other words:

$ git clone https://github.com/PluralKit/PluralKit
$ cd PluralKit
$ cp pluralkit.conf.example pluralkit.conf
$ nano pluralkit.conf  # (or vim, or whatever)
$ docker-compose up -d

Manually

  • Install the .NET 6 SDK (see https://dotnet.microsoft.com/download)
  • Clone this repository: git clone https://github.com/PluralKit/PluralKit
  • Create and fill in a pluralkit.conf file in the same directory as docker-compose.yml
  • Run the bot: dotnet run --project PluralKit.Bot
    • Alternatively, dotnet build -c Release -o build/, then dotnet build/PluralKit.Bot.dll

(tip: use scripts/run-test-db.sh to run a temporary PostgreSQL database on your local system. Requires Docker.)

Scheduled Tasks worker

There is a scheduled tasks worker that needs to be ran separately from the bot. This handles cleaning up the database, and updating statistics (system/member/etc counts, shown in the pk;stats embed).

Note: This worker is not required, and the bot will function correctly without it.

If you are running the bot via docker-compose, this is set up automatically.

If you run the bot manually you can run the worker as such:

  • dotnet run --project PluralKit.ScheduledTasks
  • or if you used dotnet build rather than dotnet run to run the bot: dotnet build/PluralKit.ScheduledTasks.dll

Upgrading database from legacy version

If you have an instance of the Python version of the bot (from the legacy branch), you may need to take extra database migration steps. For more information, see LEGACYMIGRATE.md.

User documentation

See the docs/ directory

License

This project is under the GNU Affero General Public License, Version 3. It is available at the following link: https://www.gnu.org/licenses/agpl-3.0.en.html

pluralkit's People

Contributors

5ht2 avatar ambdroid avatar ashen-dawn avatar bakakiller avatar beefox-sys avatar dependabot[bot] avatar draconizations avatar foundationkitty avatar greysdawn avatar iguessitsbray avatar katrix avatar multimasks avatar multiusersystem avatar nephanim avatar nim-ka avatar poggingfish avatar programing-monkey avatar repository avatar rladenson avatar ryonez avatar saizai avatar starshine-sys avatar subroutine7901 avatar thes1lv3r avatar u1f408 avatar ultragamer135 avatar vmorrisonwood avatar xbelladonna avatar xske avatar zoemartin01 avatar

Stargazers

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

Watchers

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

pluralkit's Issues

Add License

Is there a reason that pluralkit has no license openly displayed in the repo? The lack of a license discourages contribution from devs like me.

Add system member display names

Members should be able to set a "display name" or "nickname" that'll be used when proxying messages and possibly in various card embeds, but not when executing commands. This is for more advanced use cases than the system tag, and could for example be useful if your display name contains emojis, fancy punctuation or spaces.

Custom bot prefix per-server

custom stuff for servers

examples:

  • pk;prefix kek; changes commands to kek;command
  • pk;blacklist #channel adds channel to proxying blacklist (easier for mobile server owners who struggle w/ bot permissions and just give pk admin)

Add the ability to accept names with spaces in commands.

At the moment, commands use spaces as markers for the next segment of a command. If you use both a given name and a forename, a command will not take it in as a whole name. Even when using quotes, it will try to split it.

While there is an alternative method, using id's, it's more likely a member will remember the name at all times.

Could you please modify commands that use member names to be able to take names with spaces in quotes as well?
And while I have a system name that's just a single word, it would probably be if benefit from the same addition to the commands feature set.

Cheers.

hex codes and member working

so i added two tulpas to Pluralkit. only one of them, Pluralkit doesn't acknowledge. i keep trying to do stuff with it but it keeps saying that the tulpa doesn't exist. and the Coloring. i tried hex codes and it keeps saying that the hex codes aren't valid. even when i tried the hex code it used as an example. you people really need to make it more manageable to use.

Add better permission errors

Should dump an error in the chat if it's lacking manage webhook or manage messages permission instead of just silently failing and throwing to #error-log.

Add a confirmation dialog if there's a member name conflict

It should raise a confirmation dialog if you try to register a member with a name that already exists, or try to rename a member to a name that already exists. Duplicate names are supported, but should be discouraged and prevented from occurring by accident.

Allow less precise birthdate designation

Currently users can only assign birthdates as Year, Month, Day, but it would be preferable to allow Year, Month, No Day or simply Month or Year, Day on its own would make no sense though

Multi-line messaging

Posting a single message like this:

[foo]
{bar}

would match "foo" on [text] and "bar" on {text}

Possibly limit to 3 or 5 or so for abuse reasons

Key error database_uri in config file

When using the database_uri in config, pk will throw a key error.

Recreating annabelle-proxy_bot_1 ... done
Recreating annabelle-proxy_api_1 ... done
Attaching to annabelle-proxy_api_1, annabelle-proxy_bot_1
api_1  | Traceback (most recent call last):
api_1  |   File "api_main.py", line 202, in <module>
api_1  |     web.run_app(run())
api_1  |   File "/usr/local/lib/python3.6/site-packages/aiohttp/web.py", line 53, in run_app
api_1  |     app = loop.run_until_complete(app)
api_1  |   File "/usr/local/lib/python3.6/asyncio/base_events.py", line 473, in run_until_complete
api_1  |     return future.result()
api_1  |   File "api_main.py", line 197, in run
api_1  |     os.environ["DATABASE_URI"]
api_1  |   File "/usr/local/lib/python3.6/os.py", line 669, in __getitem__
api_1  |     raise KeyError(key) from None
api_1  | KeyError: 'DATABASE_URI'
bot_1  | [2019-03-07 17:26:50,556] [discord.client] [WARNING] PyNaCl is not installed, voice will NOT be supported
bot_1  | [2019-03-07 17:26:50,557] [discord.client] [INFO] logging in using static token
annabelle-proxy_api_1 exited with code 1
bot_1  | [2019-03-07 17:26:51,797] [discord.gateway] [INFO] Created websocket connected to wss://gateway.discord.gg?encoding=json&v=
bot_1  | [2019-03-07 17:26:51,799] [discord.gateway] [INFO] Shard ID None has sent the IDENTIFY payload.
api_1  | Traceback (most recent call last):
api_1  |   File "api_main.py", line 202, in <module>
api_1  |     web.run_app(run())
api_1  |   File "/usr/local/lib/python3.6/site-packages/aiohttp/web.py", line 53, in run_app
api_1  |     app = loop.run_until_complete(app)
api_1  |   File "/usr/local/lib/python3.6/asyncio/base_events.py", line 473, in run_until_complete
api_1  |     return future.result()
api_1  |   File "api_main.py", line 197, in run
api_1  |     os.environ["DATABASE_URI"]
api_1  |   File "/usr/local/lib/python3.6/os.py", line 669, in __getitem__
api_1  |     raise KeyError(key) from None
api_1  | KeyError: 'DATABASE_URI'
bot_1  | [2019-03-07 17:26:52,154] [discord.gateway] [INFO] Shard ID None has connected to Gateway: gateway-prd-main-wrhh, discord-s
api_1  | Traceback (most recent call last):
api_1  |   File "api_main.py", line 202, in <module>
api_1  |     web.run_app(run())
api_1  |   File "/usr/local/lib/python3.6/site-packages/aiohttp/web.py", line 53, in run_app
api_1  |     app = loop.run_until_complete(app)
api_1  |   File "/usr/local/lib/python3.6/asyncio/base_events.py", line 473, in run_until_complete
api_1  |     return future.result()
api_1  |   File "api_main.py", line 197, in run
api_1  |     os.environ["DATABASE_URI"]
api_1  |   File "/usr/local/lib/python3.6/os.py", line 669, in __getitem__
api_1  |     raise KeyError(key) from None
api_1  | KeyError: 'DATABASE_URI'
annabelle-proxy_api_1 exited with code 1
api_1  | Traceback (most recent call last):
api_1  |   File "api_main.py", line 202, in <module>
api_1  |     web.run_app(run())
api_1  |   File "/usr/local/lib/python3.6/site-packages/aiohttp/web.py", line 53, in run_app
api_1  |     app = loop.run_until_complete(app)
api_1  |   File "/usr/local/lib/python3.6/asyncio/base_events.py", line 473, in run_until_complete
api_1  |     return future.result()
api_1  |   File "api_main.py", line 197, in run
api_1  |     os.environ["DATABASE_URI"]
api_1  |   File "/usr/local/lib/python3.6/os.py", line 669, in __getitem__
api_1  |     raise KeyError(key) from None
api_1  | KeyError: 'DATABASE_URI'
annabelle-proxy_api_1 exited with code 1
^CGracefully stopping... (press Ctrl+C again to force)
Stopping annabelle-proxy_api_1   ... done
Stopping annabelle-proxy_bot_1   ... done

Using the same uri in docker-compose.yml functions correctly.

Member listing rework

Sub-features:

  • Truncate the member list in pk;system and add a form of ellipsis referring to the member list command (or perhaps don't show members at all?)
  • Add a command for showing a full member list
  • Add pagination to the member list
  • Make it show member details too

UX improvements

  • System/member edit command rework (see #6)
  • Better status information and prompting
    • Member name conflict prompt (see #10)
  • Better errors
    • Various hints
      • Hint "quoting names" on unresolved member name
      • More specific help pages on unknown subcommand (instead of just ignoring)
    • Avatar size/format check (see #5)

(do comment with more suggestions!)

Refactor command structure

Currently, the pk;member set command tree is kind of unintuitive, and a lot of users struggle with it. I'll probably be refactoring it to read pk;member avatar <name> <url> and similar, restructuring the parameter order.

Extend/correct "system set tag"'s error handling regarding the use of custom emoji's.

Currently if a user tries to set a custom emoji as their systems tag, PluralKit responds with:
Can't have system tag longer than 32 characters.

The real issue as discussed in the support server is that discord can't use custom emoji. I recommend adding a check to test if a user tried to pass a custom emoji, and then to return an error if they did. For example:
Sorry, but custom emojis are not supported due to a discord limitation, please use a standard emoji instead.

Docker-compose fails to build (pycares fails to download)

Just did a pull to update my bot, however docker-compose throws an error.

Collecting pytz (from -r requirements.txt (line 9))
  Downloading https://files.pythonhosted.org/packages/61/28/1d3920e4d1d50b19bc5d24398a7cd85cc7b9a75a490570d5a30c57622d34/pytz-2018.9-py2.py3-none-any.whl (510kB)
Collecting timezonefinder (from -r requirements.txt (line 10))
  Downloading https://files.pythonhosted.org/packages/38/2c/8fcd7bc6d6ecb4a1ae043c27488ede4aba5d48d5ec47e25ee8401d7c648b/timezonefinder-3.4.2-py2.py3-none-any.whl (37.2MB)
Collecting typing; python_version < "3.7" (from aiodns->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/4a/bd/eee1157fc2d8514970b345d69cb9975dcd1e42cd7e61146ed841f6e68309/typing-3.6.6-py3-none-any.whl
Collecting pycares>=3.0.0 (from aiodns->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/85/de/cd46a73e43e206a6ad1e9cf9cc893c3ed1b21caf57f1e0a8d9a119d290eb/pycares-3.0.0.tar.gz (211kB)
    Complete output from command python setup.py egg_info:
    Package libffi was not found in the pkg-config search path.
    Perhaps you should add the directory containing `libffi.pc'
    to the PKG_CONFIG_PATH environment variable
    Package 'libffi', required by 'virtual:world', not found
    Package libffi was not found in the pkg-config search path.
    Perhaps you should add the directory containing `libffi.pc'
    to the PKG_CONFIG_PATH environment variable
    Package 'libffi', required by 'virtual:world', not found
    Package libffi was not found in the pkg-config search path.
    Perhaps you should add the directory containing `libffi.pc'
    to the PKG_CONFIG_PATH environment variable
    Package 'libffi', required by 'virtual:world', not found
    Package libffi was not found in the pkg-config search path.
    Perhaps you should add the directory containing `libffi.pc'
    to the PKG_CONFIG_PATH environment variable
    Package 'libffi', required by 'virtual:world', not found
    Package libffi was not found in the pkg-config search path.
    Perhaps you should add the directory containing `libffi.pc'
    to the PKG_CONFIG_PATH environment variable
    Package 'libffi', required by 'virtual:world', not found
    c/_cffi_backend.c:15:17: fatal error: ffi.h: No such file or directory
     #include <ffi.h>
                     ^
    compilation terminated.
    Traceback (most recent call last):
      File "/usr/local/lib/python3.6/distutils/unixccompiler.py", line 118, in _compile
        extra_postargs)

Looks like an issue with pycares, which I'm hazarding a guess is a requirement for timezonefinder.

Git updated from commit 3c96852 to 8f2f8d7.

System time zones

Commands would use this time zone when outputting information and parsing time offsets.

Would probably be best implemented on a per-system basis, and if an account is linked to the system, will use said time zone for all output. Accounts with no system will use UTC as a default.

This would have a pk;system timezone <zone> command. It would attempt to parse the time zone, and ask for verification while displaying the current time in said time zone, so the user can verify it's correct.

Possible considerations:

  • Should the timezone be a proper Olson name, or just a UTC offset? The former would be slightly more difficult to implement, and also rely on an updated time zone database (through the pytz dependency, probably). The latter would be easier, but wouldn't update as DST changes, requiring a manual change that's likely to go unnoticed by the user.

Member groups

You should be able to categorize members in groups.

Sub-features:

  • Commands to add/remove groups
  • Commands to move a member to a group
  • Per-group system tags
  • Group headers in the member list (see #26)

Considerations:

  • Should you be able to select a "currently active group", similar to switch tracking, and have members for those take precedence re: querying/proxying?
  • When deleting a group, do the members in the group get deleted too? Do they get moved to another group? Are they placed in a "null group"?
  • Should it be possible for members to exist outside of a group, or would it implicitly create a default group for every non-grouped member?

Extract the database connection into its own class

I'd like to pull database methods into a DatabaseConnection class instead of having free functions being called with a "conn" object that gets passed around. This could possibly handle pooling automatically on a per-request basis, although that might conflict with transaction support.

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.