GithubHelp home page GithubHelp logo

insprill / robot-insprill Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 3.0 11.19 MB

Self-hostable general-purpose Discord bot

Home Page: https://robot-insprill.rtfd.io/

License: GNU Affero General Public License v3.0

Kotlin 98.97% Dockerfile 1.03%
discord-bot bot discord kord kotlin

robot-insprill's People

Contributors

andynoob avatar chaoticwagon avatar foxikle avatar insprill avatar

Watchers

 avatar  avatar

robot-insprill's Issues

Implement bot presence

Add a config section containing different presences to cycle through.

Example configuration:

presence:
  random: true
  interval: 3600
  presences:
    - type: PLAYING
      message: video games
      status: Online
    - type: WATCHING
      message: youtube
      status: dnd

Implementation notes:

  • If random is true, a random presence will be picked, but not the one that was previously used.
  • interval should be the time, in seconds, between presence updates.
  • presences should be a List of Presence.
  • Presence should be a new configuration section that holds an ActivityType, message, status, and optional URL.

Implement restricted channels

Restricted channels are channels that only allow certain types of media to be posted.

Example configuration:

restricted-channels:
  - channel-id: 0000000000000000
    types:
      - IMAGE
      - VIDEO
      - LINK
      - COMMAND
    response:
      text: "This channel is only for images, videos, links, and commands!"

Implementation notes

  • When a message is posted that doesn't include one of the provided types, the response message will be shown. This should either be only visible to the user or deleted after x seconds if that's not possible.
  • Response configs will be BotConfig$Messages.
  • types should be an enum. It could be implemented similarly to the Statistic enum, with each variant having a function that checks sent messages for the required media and returns whether it's valid.

Implement text scanning and responses

When a user sends a message, a link to a paste site, an image, or a file (under a certain size) it should be scanned and responded to if conditions are met.

Example configuration:

auto-actions:
    # A list of channel IDs to scan, or `*` for any channel.
  - channels:
      - 1027121783792480296
    # What forms of media should be scanned?
    methods:
      - TEXT
      - BIN
      - IMAGE
      - FILE
    # Whether bot messages should be scanned.
    bots: false
    # A list of actions.
    actions:
        # A regex pattern to match against.
      - pattern: ".*failed to find 'plugin.yml'.*"
        # This should be able to reuse the custom commands response format.
        response:
          embeds:
            - title: "Your plugin.yml couldn't be found"
              description: |-
                Make sure it's in the correct location. If you are using Gradle or Maven it should be in the `src/main/resources` folder. 
                If you're not using those, it should be in the `src` folder, *not* a package.

   # Example to respond 'NO BIG BOY' whenever someone mentions it.
  - channels: *
    methods:
      - TEXT
    bots: false
    actions:
      - pattern: "(?i).*big ?boy.*"
        response:
          text: "NO BIG BOY"

Implementation notes:

  • OCR can be done with JavaCPP Presets for Tesseract. Example project.
  • Bin fetching can be done using the existing BinService enum and a little regex magic.
  • Responses can use the MessageBehavior#reply function. This will make it clearer what the bot's responding to if an HTTP request or OCR scan takes a while.
  • Response configs will use BotConfig$Messages.
  • Files/bins over maybe a megabyte or two should be skipped since it would take ages to look through. Not sure of a good way to protect against images, maybe skip everything over x by y pixels?

Audit logging

The following should be logged:

  • Messages
    • Message edited
    • Message deleted
    • Invite posted
  • Members
    • Joined server
    • Left server
    • Banned
    • Unbanned
    • Joined voice
    • Left voice
    • Roles changed
    • Profile updated
      • Name
      • Nickname
      • Avatar
      • Member Avatar
      • Discriminator
      • Banner
      • Member Banner
      • About me
  • Roles
    • Role created
    • Role deleted
    • Role modified
      • Permissions
      • Name
      • Color
      • Icon
  • Channels
    • Channel created
    • Channel deleted
    • Channel modified
      • Name
      • Slowmode
      • NSFW status
      • Topic
      • Permissions

There should also be the following configuration options:

  • Log channels
  • Ignore bots
  • Ignore channels

Missing access error when audit logging system is given an inaccessible channel.

Problem

When implementing forms, this particular error was thrown when the audit system detects something to log and the channel specified in config does not exist/is not accessible:

Error

[15:02:16 ERROR]: catching
dev.kord.rest.request.KtorRequestException: REST request returned an error: 403 Forbidden  Missing Access null
	at dev.kord.rest.request.KtorRequestHandler.handle(KtorRequestHandler.kt:61)
	at dev.kord.rest.request.KtorRequestHandler$handle$1.invokeSuspend(KtorRequestHandler.kt)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
	Suppressed: dev.kord.rest.request.RecoveredStackTrace: This is the recovered stack trace:
		at dev.kord.rest.service.ChannelService.getChannel(ChannelService.kt:525)
		at dev.kord.core.supplier.RestEntitySupplier.getChannelOrNull(RestEntitySupplier.kt:86)
		at dev.kord.core.supplier.StoreEntitySupplier.getChannelOrNull(StoreEntitySupplier.kt:50)
		at dev.kord.core.supplier.FallbackEntitySupplier.getChannelOrNull(FallbackEntitySupplier.kt:38)
		at dev.kord.core.behavior.GuildBehavior$DefaultImpls.getChannel(GuildBehavior.kt:1109)
		at dev.kord.core.entity.Guild.getChannel(Guild.kt:34)
		at net.insprill.robotinsprill.audit.AuditManager.sendMessage(AuditManager.kt:49)
		at net.insprill.robotinsprill.audit.AuditManager.sendUserMessage(AuditManager.kt:34)
		at net.insprill.robotinsprill.audit.category.AuditCategory.send(AuditCategory.kt:19)
		at net.insprill.robotinsprill.audit.category.AuditMessages$registerEvents$2.invokeSuspend(AuditMessages.kt:32)
		at net.insprill.robotinsprill.audit.category.AuditMessages$registerEvents$2.invoke(AuditMessages.kt)
		at net.insprill.robotinsprill.audit.category.AuditMessages$registerEvents$2.invoke(AuditMessages.kt)
		at net.insprill.robotinsprill.audit.category.AuditMessages$registerEvents$$inlined$event$4$1.invokeSuspend(Kord.kt:636)
		... 6 common frames omitted

Why

This error occurs because AuditManager#sendMessage invokes #getChannel, which throws an error if the specified channel could not be retrieved.

Alternative

Use #getChannelOrNull and boxing it with try/catch.

Implement statistics channels

Statistics channels are channels that display a certain statistic in the name.
These can be statistics about the server, like member counts, or from a social media platform like YouTube subscribers.

Example configuration:

statistic-channels:
  - channel-id: 0000000000000000
    format: "CodedRed Subs: %s"
    statistic: YOUTUBE_SUBS
    data: UC_kPUW3XPrCCRT9a4Pnf1Tg
  - channel-id: 0000000000000000
    format: "CodedRed Views: %s"
    statistic: YOUTUBE_VIEWS
    data: UC_kPUW3XPrCCRT9a4Pnf1Tg

Implementation notes:

  • The channel must already exist. It will not be created by the bot to simplify the implementation.
  • The format field will define the channel name. It'll be formatted with a simple String#format, and %s being the value.
  • The data field is a String that some statistics may use, like YOUTUBE_SUBS for the channel to get the sub count.
  • The following statistics will exist:
    • YOUTUBE_SUBS - API key set via the YOUTUBE_API_KEY env var.
    • YOUTUBE_VIEWS - API key set via the YOUTUBE_API_KEY env var.

Implement a role selection command

The role selector command is a command that will respond with an embed and a dropdown allowing users to pick what roles they want.

Example configuration:

commands.slash.select-roles:
  - message:
      embed: ...
    roles:
      - id: 0000000000000000
        emoji: name:0000000000000000

This configuration may change based on the actual implementation. This should be taken more as a loose reference than a guide.

A similar example from the Modrinth Discord:
Image
The main difference between ours and theirs is that theirs is a static message where you click a button that gives you the prompt. Ours would be a command to give the message & the prompt.

Implementation notes:

  • The command name will be select-roles
  • The message field will use BotConfig$Message.
  • The response should be ephemeral.

Implement forms

Forms would be channels that you need to fill out a form in order to post to.

Example configuration:

forms:
  - channel: 000000000000000
    color: "#000000"
    completable: true
    fields:
      - name: Plugin Name
        type: TEXT
        min: 2
        max: 24
      - name: Plugin Description
        type: TEXT
      - name: Budget (USD)
        type: NUMBER
        min: 1
        max: 1000
      - name: Contact
        type: USER

Implementation notes:

  • Once the user submits all required information, the bot will post it as an embed.
  • There should be a button for OP to delete the post.
  • The embed should have OP's tag as the author name, and OP's pfp as the author image.
  • There should be a way to enter longer pieces of text than the user can post in one message.
  • There should be an option to mark a post as completed.
  • There should be the following types:
    • TEXT
      Takes a basic text input. Has two parameters, min and max defining the minimum and maximum length of the text.
    • NUMBER
      Takes a number as input. Has two parameters, min and max defining the minimum and maximum value of the number.
    • USER
      Takes a single mention of a user.

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.