utility-bot

command module
v0.0.0-...-965f207 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 29, 2024 License: MIT Imports: 3 Imported by: 0

README

Utility Bot

build-and-test CodeFactor Go Report Card

A Discord bot designed to streamline the support process on the official NestJS Discord server.

We've developed this bot to improve your interaction with other users. With pre-written, perfectly formatted Markdown content delivered through slick slash commands, you can respond to everyday situations quickly. No more tedious explanations, no more typing out the same thing over and over again.

Commands

Command Description Who can execute it?
/solved To close and mark the forum posts as solved with a tag Mods, Forum post owner
/archive To close and lock the forum posts Mods
/dont-ping-mods Tell someone to stop pinging mods for help Mods
/mods cross-post Warn users not to cross-post, ask in relevant channels, and be patient Mods
/mods spam A friendly warning to prevent spamming in the chat Mods
/mods elaborate Please provide more context so we can better assist you with your inquiry Everyone
/community awesome A curated list of awesome things related to NestJS (awesome-nestjs) Everyone
/community testing Show off to the community methods of testing NestJS (jmcdo29/testing-nestjs) Everyone
/docs behind-proxy How to enable the trust proxy option behind a reverse proxy Everyone
/docs circular-dependency Circular dependencies in NestJS and how to avoid them Everyone
/docs file-change-detected How to fix when TypeScript 4.9+ on infinite loop in watch mode Everyone
/docs nest-debug Debug NestJS dependencies with environment variable Everyone
/docs providers-vs-imports Ensure accurate service/module listings Everyone
/docs request-lifecycle Get a grip on NestJS' request lifecycle for smooth coding Everyone
/docs resolve-dependencies Nest not being able to resolve dependencies of something Everyone
/rules codeblocks Letting people know how to share their code in a Markdown code block Everyone
/rules dm Use server to get help on NestJS; don't DM other members Everyone
/rules dont-ask-to-ask Telling people to just ask their question with a link explaining why Everyone
/rules no-hello Telling people not to say just 'hello' in the chat Everyone
/rules reproduction Request for a minimum reproduction of the issue Everyone
/rules screenshot When someone posts a screenshot instead of sharing their code Everyone
/javascript floating-promise Introduction to floating Promises in JavaScript Everyone
/request-info Ask people to run @nestjs/cli info and provide the output. Everyone
/show-the-error Telling people to be specific when seeking help. Everyone

Configuration

cp .env.example .env

The following environment variables are required, and the rest of the configuration is located in config.yml.

  • DISCORD_APP_ID
  • DISCORD_BOT_TOKEN
  • DISCORD_GUILD_ID

How we handle incoming Discord updates

The utility bot application listens for incoming Discord updates, such as message creations, interactions, and bot events. It then processes these updates accordingly, performing actions such as setting bot status, handling slash commands, moderating messages, and more.

flowchart TD
%% classes
    classDef orange stroke: #f96
    classDef green stroke: #0f0
    classDef cyan stroke: #0ff
%% start point
    discordUpdate["Discord Update"]:::cyan
    discordUpdate -->|" Event "| utilityBotApp("Utility-Bot Application")
    utilityBotApp --> eventType{"What's the event type?"}
    eventType -->|" Ready "| setStatus["Set Bot status to:\n\nListening to slash-commands!"]
    setStatus --> finish["Finish"]
    eventType -->|" Interaction Create "| eventInteractionCreate{"What is the type of interaction?"}
    eventInteractionCreate -->|" Application Command Autocomplete "| applicationCommandAutoComplete["Slash command autocomplete flow"]:::orange
    eventInteractionCreate -->|" Application Command "| checkRateLimit("Check ratelimit policy")
    checkRateLimit --> isStaticCommand{"Is static command?"}
    isStaticCommand -->|" Yes "| handleStaticCommand{"Handle static command\n(hardcoded)"}
    handleStaticCommand -->|" /solved "| solvedCommandFlow["Solved cmd flow"]:::orange
    handleStaticCommand -->|" /archive "| archiveCommandFlow["Archive cmd flow"]:::orange
    handleStaticCommand -->|" /dont-ping-mods "| dontPingModsFlow["Don't ping mods cmd flow"]:::orange
    handleStaticCommand -->|" /google-it "| googleItFlow["Google it cmd flow"]:::orange
    handleStaticCommand -->|" /reference "| referenceFlow["Reference cmd flow"]:::orange
    isStaticCommand -->|" No "| handleDynamicCommand("Handle dynamic command\n(config.yml)"):::green
    eventType -->|Message Create| isBotMessage{"Is the message from a bot?"}
    isBotMessage -->|" No "| AutoModFlow["Auto-moderation feature flow"]:::orange
    isBotMessage -->|" Yes "| Finish["Finish"]
Auto-moderation feature flow

We have noticed that a small number of members in our community have had their Discord accounts taken over due to clicking on harmful links. Attackers who gain access to these accounts often use them to send harmful links to multiple channels. To prevent this, we have added an auto-moderation feature to our utility bot. This feature will detect and instantly ban any accounts that are sending harmful links, protecting our community members from clicking on them. Even though the bot's primary function is to send pre-written responses through slash-commands, we believe this additional feature will be invaluable in keeping our community safe.

flowchart TD
%% classes
    classDef orange stroke: #f96
    classDef green stroke: #0f0
    classDef startPoint stroke: #0ff, font-size: 20pt
    classDef red stroke: #f00
%% start point
    start["Start point"]:::startPoint
    start ===> shouldTrackChannelID{"Should moderate the current\nchannel ID?\n(we only track text channels)"}
%% channels to track
    shouldTrackChannelID <-.-> channelsToTrack
    shouldTrackChannelID -->|" No "| finish-2["Finish"]
    shouldTrackChannelID -->|" Yes "| isUserModerator{"Is message author\na moderator?"}
%% is moderator?
    isUserModerator <-.-> moderators
    isUserModerator -->|" Yes "| finish-1["Finish"]
    isUserModerator -->|" No "| isUserInDeniedList
%% denied list
    deniedList <-.-> isUserInDeniedList{"Is message author\nin the denied list?"}
    isUserInDeniedList -->|" No "| storeTheirMessage("Store their message")
    isUserInDeniedList -->|" Yes "| take-action-secondary
    addUserToDeniedList("Add message author to the denied list") --> deniedList
%% Messages
    storeTheirMessage <-.-> messages
    storeTheirMessage -->|"Once the message\nis stored"| hasExceededMessageLimits
    hasExceededMessageLimits{"Has the message author\nexceeded the channel limit\nwithin the\nspecified time frame?"}
    hasExceededMessageLimits -->|" Yes "| take-action-primary-hub
    hasExceededMessageLimits -->|" No "| finish-4["Finish"]
%% take action hub
    take-action-primary-hub(("."))
    take-action-primary-hub --> getUserPreviousMessage("Get message author previous messages")
    take-action-primary-hub --> addUserToDeniedList
    getUserPreviousMessage <-.-> messages
    getUserPreviousMessage --> deleteTheirMessages
%% data stores
    moderators[("\nModerator IDs")]
    channelsToTrack[("\nChannel IDs\nto moderate")]
    messages[("\nDiscord messages (temporary)\n\nmap[UserID]map[ChannelID]Message")]
    deniedList[("\nDenied users IDs\n\n(temporary)")]

    subgraph take-action-primary["Take action - primary"]
        deleteTheirMessages("Delete their message(s)"):::red
        banThem("Ban their account"):::red
        alertModerators("Alert moderators"):::red
        deleteTheirMessages --> banThem
        banThem --> alertModerators
        alertModerators --> finish-5["Finish"]
    end

    subgraph take-action-secondary["Take action - secondary (in case the primary fails)"]
        deleteTheirMessage("Delete their current message"):::orange
        banThemAgain("Ban their account"):::orange
        deleteTheirMessage --> banThemAgain
        banThemAgain --> finish-3["Finish"]
    end
Solved command flow
flowchart TD
%% classes
    classDef startPoint stroke: #0ff, font-size: 15pt
    classDef red stroke: #f00
%% start point
    start["Start point"]:::startPoint
    start --> validateChannelType{"Is the channel \na forum post?"}
    validateChannelType -->|" No "| finish-1["Respond with an error"]:::red
    validateChannelType -->|" Yes "| isTheChannelLocked{"Is the current forum\npost locked?"}
    isTheChannelLocked -->|" No "| hasPermissionToExecute{"Is the person who\nexecuted the command\nOP or a Mod?"}
    isTheChannelLocked -->|" Yes "| finish-2["Respond with an error"]:::red
    hasPermissionToExecute -->|" No "| finish-3["Respond with an error"]:::red
    hasPermissionToExecute -->|" Yes "| findTheSolvedTag("Find the 'solved' tag metadata\nin the current forum post")
    findTheSolvedTag --> isSolvedTagApplied{"Is solved tag\nalready assigned\nto this forum post?"}
    isSolvedTagApplied -->|" No "| appendTheSolvedTag("Append the solved tag\nto the forum post tags\n(in memory only!)")
    isSolvedTagApplied -->|" Yes "| sendCannedResponse("Send the canned response")
    appendTheSolvedTag --> validateTagsLength{"Is the length of tags\nlower than six?\n(Discord only allows\nfive tags per post)"}
    validateTagsLength -->|" No "| finish-4["Respond with an error"]:::red
    validateTagsLength -->|" Yes "| editThePost("Edit the forum post and assign the tags")
    editThePost --> sendCannedResponse
    sendCannedResponse --> editThePostAgain("Edit the forum post (again?) to\napply the 'auto archive duration'")
    editThePostAgain --> finish-5["Finish"]
Archive command flow

Placeholder.

Don't ping moderators command flow

Placeholder.

flowchart TD
%% classes
    classDef startPoint stroke: #0ff, font-size: 15pt
    classDef red stroke: #f00
%% start point
    start["Start point"]:::startPoint
    start --> sendTheCannedResponse("Send the canned response")
    sendTheCannedResponse --> isChannelForumPost{"Is the current channel\na forum post?"}
    isChannelForumPost -->|" No "| finish["Finish"]

    moderators[("\nModerator IDs")]

    removeMods <-.-> moderators
    
    isChannelForumPost -->|" Yes "| removeMods("Remove the moderators from the forum post,\nexcept the person who executed this command")
    removeMods --> finish
Google it command flow

Placeholder.

Reference command flow

Placeholder.

Slash command autocomplete flow

Placeholder.

Docker usage

# brings down the previous container
# builds and starts a new container
# prints the container logs
make docker-redeploy

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cmd
internal
pkg
algolia
Package algolia provides utilities related to the Algolia search service.
Package algolia provides utilities related to the Algolia search service.
ratelimit
Package ratelimit provides a map-based implementation of a TTL (Time to Live) rate limiter.
Package ratelimit provides a map-based implementation of a TTL (Time to Live) rate limiter.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL