Coder Social home page Coder Social logo

kittybot's Introduction

KittiBot - a sentient Discord bot!

Current Functionality

  • Automatically assigns the #NotALurker role to members who qualify for it (previously mods had to manually assign it).
  • Answers questions targeted to her with a magic 8 ball response.
  • Detects reposted images (especially useful for meme repost detection).
  • /advice command: Returns a piece of life advice :)
  • /deletesinquiry command: Returns a list of the users which have the most amount of deleted messages.
  • /emojicloud command: Returns a 'wordcloud' of all emojis (unicode and custom emojis -- animated included!) used to-date by a specified user.
  • /emojilovers command: For a specified emoji in the server, returns the top 5 users of it in order.
  • /emojistats command: Returns information regarding how often a specified user has used a specific emoji.
  • /emojiusage command: For a specified emoji for a specified user, returns the amount of times the user has used said emoji.
  • /fact command: Returns a random fact // common misconception.
  • /fortune command: Returns a random fortune. Beware!
  • /messageboard command: Returns a bar graph of the top 10 users in terms of all-time total messages sent. There's a type option field which has 3 graph representation types to choose from:
    1. lightmode: Returns the graph (matlibplot image) in a light-mode colour scheme.
    2. darkmode: Returns the graph (matlibplot image) in a dark-mode colour scheme.
    3. native: Returns of a horizontal block bar chart in native Discord message format.
    • If no option is specified the lightmode graph is returned by default.
  • /messagecount command: Returns the total server message count alongside the requester's total message count.
  • /pickupline command: Returns a pickup line. Use at your own risk.
  • +ping command: Kitti returns to you a heartbeat latency message.
  • /say command: Writes a custom text message encapsulated in something rather interesting...
  • /translate command: Translates text to and from English. There's 2 option fields. The first is the text, and the second is the language you want to translate into (you write the language code; e.g. fr for french). If you don't specify the language code (i.e. leaving this option field blank), then it assumes you want to translate the text you write into English.
  • /userinfo command: This command returns interesting information about a specified user (specified through the target option field). If no member is specified, the command returns info of whoever issued the command. There's also a type option field which has 2 choices:
    1. general: Returns an embed containing general information such as account creation date, server join date etc.
    2. emoji: Returns an embed of the top 5 used emojis of the user, their total messages, and what 'rank' they are in terms of total messages sent.
    • If no option is specified, the emoji type is chosen by default.
  • /wordcloud command: Returns a 'wordcloud' of all unicode emojis used to-date by a specified user.
  • /setprompt command: Set prompt for Gemini LLM queries
  • All commands have a 10-second cooldown period (per user), and are generally called in using command form.
  • There are several other Easter Eggs in Kitti easily discovered through usage ;)

Key Notes & Repository Information

  • Kitti is an open-source, community-powered bot for the CS@unimelb Discord server.
  • This bot is made using Hikari & Lightbulb. These are two nice & simple Python libraries.
  • Note: Python version 3.10 is required.
  • The docs for these two libraries are https://www.hikari-py.dev/hikari/ & https://hikari-lightbulb.readthedocs.io/en/latest/.
  • The following get-started guide is very nice if you want to quickly understand how these libraries work: https://novanai.readthedocs.io/en/latest/lightbulb/index.html
  • Pull requests are very much accepted (and encouraged!) if you want to add features to the bot & server :)
  • If you want to play around with it, you will need to use your own bot token. You could then invite your own bot (with the token you got) to your own personal server and play around with it there for testing (this is all in the above guide) :)
  • After cloning the repo, you can install the required dependencies (listed in requirements.txt) using the command pip install -r requirements.txt.
  • The bot is then made alive by simply running: python bot.py
  • For readability purposes, if you want to add a function/command, please write it in a new python file placed in the extensions folder -- just like the userinfo and fortune commands are.
  • Important: If you want to develop/contribute/test/play-around, you will need to create a .env file and inside it add your bot token (as explained in the guide), and the 'default guild' IDs. It will need to be like: BOT_TOKEN = 123456 and DEFAULT_GUILDS = 123456,56789 (comma-seperated list). Specifying guild IDs in .env is not neccessary, and actually the act of specifying certain IDs to it (can be many guilds) means that slash commands will only be available in those guilds. The benefit of specifying default guilds is that the slash commands become available instantly in those servers, which is good for testing purposes. Note: 'guild' means Discord server.
  • So, to be clear, your .env file should be located in the top layer of the repository (same level as bot.py and requirements.txt) and could look like this:
BOT_TOKEN = 123456 # Your bot’s token from the Discord Developer Portal.
DEFAULT_GUILDS = 123456,56789 # The 'default guilds' -- these instantly load slash comamands. Can be empty.
FORTUNE_DIRECTORY=/usr/share/games/fortunes # Location of where fortunes is installed on your machine.
NOTALURKER_ROLE=11111111111111111 # The role ID for the notAlurker role.
ORIGINALITY_CHANNEL_ID=11111111111111111 # The channel you want the originality feature to operate in.
DEBUG=True
PHASH_TH=40 # Perceptual hash threshold for meme repost
CHASH_TH=40 # Color hash threshold for meme repost
RANK_CHANGE_FLOOR=30 # Only users above this rank will be announced when they overtake someone
GEMINI_API_KEY=abcd # Access to google gemini LLM
BOT_ADMIN_ROLE=11111111111111111 # Role has access to some commands
  • The /fortune command requires the fortunes package to be installed and pointed to by the FORTUNE_DIRECTORY variable in .env.
    • If you're on Linux you can install fortunes with sudo apt-get install -y fortune and in .env set FORTUNE_DIRECTORY=/usr/share/games/fortunes
    • If you're on macOS you can install fortunes with brew install fortune and in .env set FORTUNE_DIRECTORY=/usr/local/Cellar/fortune/9708/share/games/fortunes
    • I don't have Windows so if you develop on Windows you'll have to find how to download the fortunes package yourself. If you can't find it it's fine, it just means the +fortune command won't work during testing (but everything else should).
    • You may optionally white-list and black-list database files by setting FORTUNE_WHITELIST and/or FORTUNE_BLACKLIST to a space-separated list of database file names.
  • The bot can grant a role to members when they first send a text message. Conventionally, this role is called #NotALurker. To enable this feature the NOTALURKER_ROLE parameter in .env must be set to the role ID to grant. The bot's role must be higher than this role to have permission to grant it.
  • The bot is easily deployed on a cloud server (e.g. droplet on Digital Ocean which runs Ubuntu 20.04).

Docker deployment

For the docker deployment, just create the .env file as above but do not add the FORTUNE_DIRECTORY, and then execute the following commands:

docker compose build
docker compose up -d

Further Ideas // Ways to Contribute

  • Resolve outstanding issues noted in Issues.
  • Perhaps a unimelb-handbook webscraping related command? The repo already uses a webscraper (BeautifulSoup) you could use!
  • Greeting new people when they join the server in #general.
  • Getting Kitti to reply to someone if they thank Kitti (e.g.: Thanks @Kitti! ... You're welcome @____ 🐱).
  • Add programming/CS related facts to the fact 'database'. The database is currently a list of strings whereby each string is a fact/common-misconception scraped from a Wikipedia page.
  • Implement some sort of natural language processing thing (neural network?) that does something to do with text analysis (e.g. off a message that someone sends). This is some next level stuff, but hey, if there's an interest then why not? πŸ˜ƒ
  • Implement a creative command you have of your own!

Legal

This software distributes the Noto Emoji font, under the terms of the SIL Open Font License. See fonts/OFL.txt for details.

kittybot's People

Contributors

olliequ avatar flukiluke avatar dakshag avatar walter-bd avatar jimbxb avatar peppermintsodaa avatar

Stargazers

Sebastian Tobin-Couzens avatar  avatar Anjaney C Mahajan avatar Hoang Giap Vu avatar  avatar  avatar Adam Nicholas Werbik avatar caesiumCode avatar  avatar  avatar  avatar

Watchers

Kostas Georgiou avatar  avatar

kittybot's Issues

The tragedy of Darth Plagueis "the wise"

Did you ever πŸ§ƒπŸ§ƒπŸ§ƒ hear the tragedy of Darth Plagueis The Wise? πŸ”ƒ I thought πŸ’­πŸ’­ not. πŸ’΅πŸ’΅πŸ’΅ It’s not πŸ’΅πŸ’΅ a 🏧🏧 story the Jedi would tell πŸ›°πŸ›°πŸ›° you. 🀟🀟 It’s a 🏧 Sith legend. 🦡🦡🦡 Darth Plagueis was a 🏧 Dark Lord of the Sith, so powerful and so wise πŸ”ƒπŸ”ƒ he could ☁ use 🎠🎠🎠 the Force to influence the midichlorians to create 🐈 life… He had such a 🏧🏧 knowledge πŸ¦‰ of the dark side πŸ™ƒπŸ™ƒπŸ™ƒ that he could ☁☁☁ even πŸ•¦πŸ•¦ keep the ones he cared about from 😀😀 dying. The dark side πŸ™ƒπŸ™ƒ of the Force is a 🏧🏧🏧 pathway to many abilities some πŸ•‰ consider to be unnatural. He became so powerful… the only thing he was afraid of was losing πŸ“•πŸ“•πŸ“• his power, which eventually, of course, he did. Unfortunately, he taught his apprentice everything he knew, then β›Ί his apprentice killed πŸ’ŠπŸ’Š him in his sleep. 😴 Ironic. He could ☁☁ save 🍢🍢🍢 others 🦦 from 😀😀 death, but not πŸ’΅ himself. 🧝

message edit/deletion counts

i.e. so we can rank people based on how many messages they sneakily delete, possibly with deleterious social results.

would be nice! Possible?

Changing of image repost detection algo means 'history' of known duplicates was reset

However, the previous image hashes are <message_id, image hash> in the table, so they are saved. The thing is their hashes are the hashes from the old algo. This means that the new algorithm won't detect a reposted image of this old set from here on out as the new hashing algo is different to the old one -- so the same image would have 2 different hashes.

So a script is needed to go to each old message, get the new hash (using the new hash algo) and insert it into the table. Shouldn't be too bad! I believe there's around 40 images which need a hash update.

Ugly use of `time(s)`

Currently the emojilovers command will inform that a person has used an emoji n time(s). This parenthesised construction is unsightly and displeasing to the eye.

snark is not subject to duplicate message policing

When a duplicate message triggers snark by replying to the bot, the message is snarked then deleted. This results in a bot reply to a deleted message.

Expected behaviour: unoriginal messages are not deemed worthy for snarking.

Mentions.user_ids is deprecated

Sep 06 21:58:18 plum kitti[297250]: W 2022-09-06 11:58:18,970 py.warnings: /home/extensions/snark.py:25: DeprecationWarning: 'Mentions.user_ids' is deprecated and will be removed in a following version. You can use 'user_mentions_ids in the base message object' instead.

Presumably this is due to a recent hikari upgrade

Fortune won't print when asked to if the fortune retrieved is over 2,000 characters long.

Currently just gives a generic error handling message:

hikari.errors.BadRequestError: Bad Request 400: (50035) 'Invalid Form Body' for https://discord.com/api/v8/channels/813266892818219038/messages
{
  "content": {
    "_errors": [
      {
        "code": "BASE_TYPE_MAX_LENGTH",
        "message": "Must be 2000 or fewer in length."

Possible routes to resolve:

  • Write specific error handling message
  • Instead try retrieve a different fortune
  • Remove fortunes over 2k chars from database

Pillow deprecation warning

kitti[297]: W 2022-10-30 15:36:41,211 py.warnings: /usr/local/lib/python3.10/site-packages/wordcloud/wordcloud.py:499: DeprecationWarning: ROTATE_90 is deprecated and will be removed in Pillow 10 (2023-07-01). Use Transpose.ROTATE_90 instead.
kitti[297]:   orientation = Image.ROTATE_90

Matlibplot doesn't render user emojis in the display name on the x-axis

Here's an example:

k

A potential solution is to change the font used for the plot. The code for the matlib plot is super simple, it's only 10 lines of code, and can be found here:

fig, ax = plt.subplots(figsize=(11,5))
bars = ax.bar(users, counts, color=['#C9B037', '#D7D7D7', '#6A3805', '#9fdbed', '#9fdbed', '#9fdbed', '#9fdbed', '#9fdbed', '#9fdbed', '#9fdbed'], edgecolor='black')
ax.bar_label(bars)
# ax.set_xlabel('Members', labelpad=10, color='#333333', fontsize='12')
ax.set_ylabel('Total Messages', labelpad=15, color='#333333', fontsize='12')
ax.set_title('Messages Tally! from {} to {}'.format(set_num*10 + 1, set_num*10 + 10), pad=15, color='#333333', weight='bold', fontsize='15')
ax.set_facecolor('#f5f5f5')
plt.yticks(fontsize=8)
plt.xticks(fontsize=(95/max_name_length))

For the unique message feature, Kitti says some messages were first sent 52 years ago.

This is for messages that don't have timestamps for when they were first sent (this is because the timestamp first-sent addition was made at a later date). For null values the default time assigned is the UNIX timestamp epoch (January, 1970).

One potential fix is a manual fix: every message in the db has a message ID that can be looked up to manually retrieve what date it was originally sent, and insert this into the db. You might be able to automate this manual process by iterating through the db checking for emojis with this 1970 timestamp?

Here's an example:

image

Message Count isn't incremented when a user sends a message with no text content

An important example is the posting of just an image in #memes. This should increment the count. Perhaps a sticker sending, too.

The reason is because, as we can see below in

if event.is_bot or not event.content:
return

The sending of just an image will result in event.content being None -- this is because the content variable of the event object is just for text. And because it's None, the function will immediately return and so no increment will occur.

I believe the attachments variable contains info about any attached images, so maybe this variable can be scanned to solve this issue.

None in snark module

Mar 27 17:47:32 plum priceless_spence[1008]: E 2024-03-27 06:47:32,976 hikari.event_manager: an exception occurred handling an event (GuildMessageCreateEvent)
Mar 27 17:47:32 plum priceless_spence[1008]: Traceback (most recent call last):
Mar 27 17:47:32 plum priceless_spence[1008]:   File "/home/extensions/snark.py", line 115, in main
Mar 27 17:47:32 plum priceless_spence[1008]:     if plugin.bot.application.id not in mentioned_ids:
Mar 27 17:47:32 plum priceless_spence[1008]: AttributeError: 'NoneType' object has no attribute 'id'

On every message after a system restart

Fortune sometimes prints with incorrect line breaks.

What it should print like:

"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."

What it currently sometimes prints like:

"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat."

Here is an actual example of the error from the server: https://imgur.com/a/yJ2YbgO

Edit: Fortunes also sometimes print with 2 spaces between sentences. Obviously, there should only be 1 whitespace. Here's an example: https://imgur.com/a/yoO9FW1

For the unique message feature, Kitti doesn't allow the sending of custom emojis (when she should)

This is because custom emojis are interpreted as a string encapsulated with <:>. A check could be made for these chars to allow the sending of emojis. Remember, any message with length <= 2 should be allowed, and a custom emoji should be treated as length 1.

Unicode emojis don't have this issue as for some reason they aren't translated to this <:> structure. In the command line with bot.py running, if you print(message) where message is sending of a unicode emoji, it will actually print the singular emoji. Where if it's custom it'll be something like <:catswag:989147563854823444> which obviously has length greater than 2.

Example:

image

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.