GithubHelp home page GithubHelp logo

en3sis / hans Goto Github PK

View Code? Open in Web Editor NEW
16.0 2.0 4.0 759 KB

An open-source, modular Discord bot template. Built with Discord.JS & TypeScript

Home Page: https://hans.app

License: MIT License

Shell 0.43% Dockerfile 0.77% TypeScript 92.87% JavaScript 3.17% PLpgSQL 2.75%
discord-bot discordjs open-source typescript discord-template

hans's Introduction

Docker Pulls Docker Image Version (tag latest semver) Discord

๐Ÿค– Hans - Discord Bot

Hans is built with a modular architecture that makes it easy to add and remove functionality on the fly, empowering you to create a bot tailored to your community's needs.

Built with Discord.JS, TypeScript, and lots of โค๏ธ

Invite to server

Bring Hans to your Discord server and start using his available features immediately here ๐Ÿ”—. It uses the latest hans:nightly image with the latest features.

The list of commands & plugins can be found here ๐Ÿ”—

Developing Hans

๐Ÿชฌ NOTE: Please consider opening an issue and PR for bugs, suggestions, or new features.


๐Ÿ”… Prepare environment

Before running any command, run npm install && cp .env.template .env, and fill in all the env variables needed. To create your application, visit Discord's Developer Portal

๐Ÿชฌ IMPORTANT: A Supabase instance is needed for the bot to work. A free cluster should be more than enough (even for small bots & communities) for development.

Supabase Local Development.

Supabase is used for storing the bot's configs, guilds, and users.

You can work with supabase local, follow the instructions here ๐Ÿ”—. Once you run supabase start the local Supabase will be populated with the latest schema (have a look at the supabase/seed.template.sql file for more configuration)

More information related to working with Supabase local development can be found ๐Ÿ“น here ๐Ÿ”—

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Development

Once the Prepare environment section is done, you can follow along with the development.

npm run dev

It will start a development server with ts-node and nodemon for live-reload. A bot Invite link will be displayed in the console.

Slash commands

All commands (under src/commands) are built with the Slash Command interaction.

๐Ÿชฌ IMPORTANT: before developing commands, make sure you invite the bot to your server and the entry in Supabase configs -> bot_guild_id is your guild_id.

All commands under the main folder are available globally (it will take a second to have them available) while the ones under bots-playground/ are guild-specific and are instantly deployed, use this folder for debugging & development purposes.

To deploy the commands: npm run slashDev or npm run slash in production.


๐Ÿงช Unit Tests

For testing, we use Mocha with TS.

All the tests are under the /tests directory. Right now they're none or a few, we should add more test coverage for command controllers.

npm run test

Will run all the tests.


๐Ÿ— Production

We have multiple environments for deploying your bot.

With Docker

You can either use the pre-built Docker image from DockerHub at en3sis/hans:latest or build your own locally using the command docker build -t en3sis/hans .

To run the container, use the command docker run --env-file .env --name hans -d --restart=always en3sis/hans:latest while making sure that the .env file is in the same directory as the command and contains all the necessary environment variables for the bot to function properly. You can also run it with docker-compose using the command docker-compose up -d --build bot.

Note: for M1 Macs, you'll need to use docker-compose build --build-arg M1=true before running the docker-compose up -d.

Locally

You can also run the bot locally using the following commands:

๐Ÿชฌ IMPORTANT: Follow the Prepare environment section.

npm run build

To generate the application's build.

npm start

It will run the bot with the production environment.

With Kubernetes (WIP)

๐Ÿ’ข NOTE: This is a WIP, it's not fully tested yet, things are missing. Please feel free to contribute.

It's also possible to deploy the bot to a Kubernetes cluster, the necessary files are in the k8s folder.

Steps:

  1. You'll need your K8S cluster, ofc ;P
  2. Create the namespace kubectl apply -f k8s/namespace.yaml
  3. Run cp k8s/secrets.template.yaml k8s/secrets.yaml, fill it up and apply the secrets kubectl apply -f k8s/secrets.yaml
  4. Deploy the workload kubectl apply -f k8s/deployment.yaml

hans's People

Contributors

dependabot[bot] avatar en3sis avatar

Stargazers

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

Watchers

 avatar  avatar

hans's Issues

[FEATURE] using winston.js as loger

๐Ÿ“ Is your feature request related to a problem? Please describe.

A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
NA

๐Ÿงฌ Describe the solution you'd like

A clear and concise description of what you want to happen.

Right now we have some console.log to catch HTTP requests errors and so.
We want a better way to handle those errors, one idea would be using having a look at Winston (or some other alternatives)

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Additional context

Add any other context or screenshots about the feature request here.

It would be also nice to have some wrapper for debugging, for example, having logs that will only show on ISDEV=true

[BUG] messageUpdated event

๐Ÿ“ Describe the bug

A clear and concise description of what the bug is.
Not sure if there was a change in the API, but the messageUpdate:oldMessage response seems to always be undefined

๐Ÿงฌ To Reproduce

Steps to reproduce the behavior:

  1. Start your bot.
  2. Make sure your development guild has the MongoDB document for messageUpdate: true & messagesAlterations: { logChannelId: 'YOUR_CHANNEL' } set.
  3. Send a message in any chat
  4. Edit the message
  5. If you console.log the oldMessage (src/events/messageUpdate.ts) it the content is undefined

๐Ÿ”… Expected behavior

A clear and concise description of what you expected to happen.

It should show the old message content & author should be present, but they're null.

๐ŸŒ  Screenshots

If applicable, add screenshots to help explain your problem.

image

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Additional context

Add any other context about the problem here.

Not sure if there was a change in the bot permissions level.

[FEATURE] Disallow commands globally

๐Ÿ“ Is your feature request related to a problem? Please describe.

If we deploy a command with some bugs, we need to redeploy the bot in order to fix it.

๐Ÿงฌ Describe the solution you'd like

Add an array with disabled commands so we can do it from Hans configuration. In this case if something goes wrong, we have the force stop.

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Additional context

Reduce time for `/events`

After adding the new plugin for /events, I notice that in servers with many events & users, the command is slow.

Possibles causes:

Since the participants are not part of the GuildScheduledEvent and we need to fetch them for each event, that seems to be a heavy computation, we might be able to improve this by further checks and exceptions.

[FEATURE] `sentimentAnalysis` plugin

๐Ÿ“ Is your feature request related to a problem? Please describe.

We have the functionality, we just need to move it to the new plugin architecture.

๐Ÿงฌ Describe the solution you'd like

  • It should trigger on messageCreate
  • It should be part of the moderation category
  • It should allow setting a channel where to send the analysis and inform of negative/positive messages

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Additional context

[FEATURE ]Generic /config command for guild configuration

๐Ÿงฌ Details

Right now a user cannot enable plugins without editing the DB directly. This will be a multiple steps tasks.

Step 1 :
We need to create a slash command called /moderation.
Requirements:

  • It should only be allowed to be used by the guild owner
  • It should provide multiple options, preferably plugin specific (check /src/controllers/plugins)

Moderation plugins:

  • sentimentAnalysis
  • messagesAlterations

[FEATURE] Standup Plugin improvements

๐Ÿ“ Is your feature request related to a problem? Please describe.

I'm currently implementing a new plugin for Standups with limited functionality (Monday - Friday at a given hour, single channel)
This Issue is to have a follow-up and improve it.

๐Ÿงฌ Describe the solution you'd like

  • Allow creating multiple standups per guild (metadata[{standups}])
  • Command that shows all standups and an option to stop/remove a given standup.
  • Move everything to it's command (/standup)? This might require thinking, maybe we can rework the plugins/commands functionality.

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Additional context

[FEATURE] free use of `chatGpt` limits per server

๐Ÿ“ Is your feature request related to a problem? Please describe.

Right now only guilds labeled at premium can run the /ask command and without limit. Server admins can add their own api key.

๐Ÿงฌ Describe the solution you'd like

Besides the current functionality, we want to allow a ~50 commands per guild per day for free, above those usages, they'll have to add their own API key if more requests are needed.

  • Show remaining usages on the response.
  • Maybe we want an rpc that will reset the remaining commands every night at 00:00

[BUG] ThreadChannel

๐Ÿ“ Describe the bug

Adding a new channel object to the the threadChannels document doesn't seem to work

๐Ÿงฌ To Reproduce
Having multiple elements in the array's documents won't make all of them work, only the first one

๐Ÿ”… Expected behavior
It should create a new thread in threadChannels[1].threadChannelId

๐ŸŒ  Screenshots

image

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Additional context

[FEATURE] Self role

๐Ÿ“ Is your feature request related to a problem? Please describe.

๐Ÿงฌ Describe the solution you'd like

  1. Have a subcommand for /moderation related to user self role where an Admin can select multiple roles from server roles.
  2. It should take @roles, channel, description where channel = channel for the message to be posted and description as message.content
  3. Create a new message, having each role as a button.
  4. This should be a new plugin called selfRoles

Notes: We need to figure out how and when we edit the message with the roles when we add/remove roles from the list.

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Additional context

[FEATURE] `giveaway` plugin

๐Ÿ“ Is your feature request related to a problem? Please describe.
We want a solid giveaway system

๐Ÿงฌ Describe the solution you'd like

  • new table for guilds-giveaways
  • a new plugin and the command for it
  • we should be able to specify title, description, ending date, allowed roles(?), active
  • a button to join the giveaway
  • functionality to randomly choose a participant when the event ends (this will require to get the cronjob on the bot or supabase side)
  • when it finishes, maybe we can create a thread to the giveaway message where the winner is announced

Note: We add before a full-automated delivery system where we could set the reward (cd key for example) and it would be sent as DM to the winner. We could make use of the encrypt/decrypt functionality to store sensitive data if auto-delivery is enabled

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Additional context

image

[FEATURE] introduce Mongoose / To be filled

๐Ÿ“ Is your feature request related to a problem? Please describe.

๐Ÿงฌ Describe the solution you'd like

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Additional context

[FEATURE] Sharding

๐Ÿ“ Is your feature request related to a problem? Please describe.

Currently, Hans does not need sharding since it's way below the minimum requirement (guild presence) but if a forked bot requires it, Shading has to be implemented.

๐Ÿงฌ Describe the solution you'd like
Implement Shading: https://discordjs.guide/sharding/#sharding-file

[FEATURE] MongoDB -> Supabase

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Additional context

While MongoDB works well, I want a more robust solution.
I was playing around with Supabase for a few days now and seems to fit perfectly.
I'll gradually move the core functionality then the Plugins section

[FEATURE] Reddit new messages notifications

๐Ÿ“ Is your feature request related to a problem? Please describe.
NA

๐Ÿงฌ Describe the solution you'd like

They're many cool subreddits whit excellent content, one of them being https://www.reddit.com/r/FreeGameFindings where people post free games.

New functionality scans the subreddit every n minutes and, If a new post makes it to new sections, notify it to a given channel.

AC:

Plugin part
As part of #15

  • Should fetch the latest post
  • A new database called Plugins with a collection reddit and the document with the data structure.
  • Should check in the collection to see if it was already notified (in the document)
  • Allow multiples guilds to subscribe to the same document
  • Iterate over the list of subscribed guilds and send it to the channel

Command part
As part of #20
To enable it:

  • Add a command to subscribe to a subreddit, it will create a new document in the collection (/reddit -> Subredit* -> ChannelId?* = required | ? = optional)
  • It will create a new channel in the discord with some {title} where it will initialize the notifications
  • It will re-post the latest post in the channel.

Document Template

{
  subReddit: 'javascript',
  description: 'The programming language of the web',
  latestPostId: 'foo_bar',
  subscribedGuilds: [
    {
      guildId: '123456789',
      channelId: '123456789',
    }
  ]
}

๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป Additional context

[FEATURE] Plugins structure

๐Ÿ“ Is your feature request related to a problem? Please describe.

Right now the Plugin configuration works well but it can be improved.

๐Ÿงฌ Describe the solution you'd like

  • Replicate the slashCommand folder structure and dynamic loading
  • Stores plugins in their own table in Supabase, depending on #37

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.