Skip to content

Conversation

@achyu-dev
Copy link
Contributor

@achyu-dev achyu-dev commented Mar 25, 2025

📌 Description

This PR adds a new feature, where in, if any command is found within either a triple or single code block, it's ignored and the bot does not trigger the message that is instead triggered if its not within codeblocks

ℹ️ **Fixes **
Fixes: #412


🧱 Type of Change

  • 🐛 Bug fix – Non-breaking fix for a functional/logic error
  • ✨ New feature – Adds functionality without breaking existing commands or APIs
  • ⚠️ Breaking change – Backward-incompatible change (commands, bot behavior, etc.)
  • 🧪 Test suite change – Adds/updates unit, integration, or manual tests

🧪 How Has This Been Tested?

  • Unit Tests (test/commands.test.ts)
  • Manual testing in Discord

Test Environment:

  • OS: Windows 11

✅ Checklist

  • My code follows repo CONTRIBUTING.md guidelines
  • Self-review completed
  • Added/updated comments and docstrings
  • Updated relevant docs (README, help text, etc.)
  • No new warnings or errors introduced
  • Added/updated tests
  • All tests pass locally
  • Ran prettier (npm run prettier)
  • Docker image builds and runs
  • Changes are backwards compatible (if applicable)

🛠️ Affected Bot Areas

  • Commands (e.g., !su, !docs)

📸 Screenshots / Demos (if applicable)

image

🧠 Additional Notes

@what-the-diff
Copy link

what-the-diff bot commented Mar 25, 2025

PR Summary

  • Enhanced "dev" script
    The "dev" script in package.json is now designed to run specific development tasks (dev:bot and dev:test) rather than run everything, which improves the efficiency when working on these jobs.

  • Dependency Version Adjustments
    The versions of several dependencies (discord.js, fastify, tsx, and vitest) in package.json are amended to ensure the stability and performance of the project.

  • Removed unnecessary dependency
    The @total-typescript/shoehorn dependency from devDependencies in package.json has been eliminated, simplifying the development environment.

  • Exported commandsList
    commandsList from src/features/commands.ts has been exported for increased accessibility from other modules, which will enhance the ability to extend functionality moving forward.

  • Added !crosspost command
    Introduced the !crosspost command to commandsList in src/features/commands.ts, which sends a notification about cross posting in channels, improving chat management by reducing redundant posts.

  • Implemented escapeRegex function
    Introduced the ability to escape special characters in strings with the escapeRegex function within src/features/commands.ts

  • Introduced shouldTriggerCommand function
    Added a new function shouldTriggerCommand that checks if a command word exists in a message, while ignoring content in code blocks in src/features/commands.ts. This facilitates eased command triggering and handling.

  • Updated command handling logic
    Command handling logic is updated to use shouldTriggerCommand for checking if a command should be triggered. This ensures commands are only activated when needed, preventing unnecessary operations and enhancing efficiency.

  • Improved Reactions and Error Handling
    The handling of reactions and error management in emojiMod.ts has been simplified while also boosting correct logging of errors. This makes the error handling process more streamlined and reduces the chance of missing critical errors during development and operation.

Copy link
Member

@vcarl vcarl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, a couple of required changes before I can approve this — let's keep the PR narrowly focused on just the specific issue of command triggers in code blocks

@achyu-dev achyu-dev marked this pull request as ready for review March 28, 2025 17:03
@DanielFGray
Copy link
Contributor

Seems like this could be made a lot simpler utilizing a slightly more complex regex:

/!\w+(?=[^`]*(?:`[^`]*`[^`]*)*$)/

this should match !words not inside code blocks
in action: https://regex101.com/r/pm4kqS/1

@achyu-dev
Copy link
Contributor Author

Can someone help me on why these 8 test cases fail?

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 8 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 FAIL  test/commands.test.ts > Discord Bot Commands > should ignore command inside deeply nested triple backticks
AssertionError: expected true to be false // Object.is equality

- Expected
+ Received

- false
+ true

 ❯ test/commands.test.ts:129:63
    127|       "```\nSome random text\n```js\nconsole.log('!mdn Array.prototype.map');\n```\nMore text outside";
    128|
    129|     expect(shouldProcessCommand(mockMessage.content, "!mdn")).toBe(false);
       |                                                               ^
    130|   });
    131|

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/8]⎯

 FAIL  test/commands.test.ts > Discord Bot Commands > should ignore command inside a long deeply nested code block
AssertionError: expected true to be false // Object.is equality

- Expected
+ Received

- false
+ true

 ❯ test/commands.test.ts:145:63


⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/8]⎯

 FAIL  test/commands.test.ts > Discord Bot Commands > should process command outside deeply nested backticks but ignore the inside one
AssertionError: expected false to be true // Object.is equality

- Expected
+ Received

- true
+ false

 ❯ test/commands.test.ts:177:63
    175|       "Hey everyone, I need help with JavaScript! ```js\nfunction test() {\n  console.log('!mdn Array.prototype.map');\n}\n``` But I still need info on !m…
    176|
    177|     expect(shouldProcessCommand(mockMessage.content, "!mdn")).toBe(true); // The one outside should be processed.
       |                                                               ^
    178|     expect(
    179|       shouldProcessCommand(

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/8]⎯

 FAIL  test/commands.test.ts > Discord Bot Commands > should ignore command inside multi-level text and markdown blocks
AssertionError: expected true to be false // Object.is equality

- Expected
+ Received

- false
+ true

 ❯ test/commands.test.ts:193:63
    191|       "```\nAnother block\n```js\nconsole.log('!mdn Array.prototype.map');\n```";
    192|
    193|     expect(shouldProcessCommand(mockMessage.content, "!mdn")).toBe(false);
       |                                                               ^
    194|   });
    195|

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/8]⎯

 FAIL  test/commands.test.ts > Discord Bot Commands > should ignore command if inside an embedded link
AssertionError: expected true to be false // Object.is equality

- Expected
+ Received

- false
+ true

 ❯ test/commands.test.ts:247:63
    245|     mockMessage.content =
    246|       "[Click here for !mdn Array.prototype.map](https://example.com)";
    247|     expect(shouldProcessCommand(mockMessage.content, "!mdn")).toBe(false);
       |                                                               ^
    248|   });
    249|

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/8]⎯

 FAIL  test/commands.test.ts > Discord Bot Commands > should ignore command inside nested code blocks
AssertionError: expected true to be false // Object.is equality

- Expected
+ Received

- false
+ true

 ❯ test/commands.test.ts:261:63
    259|     mockMessage.content =
    260|       "```\nHere is some code:\n```js\nconsole.log('!mdn Array.prototype.map');\n```";
    261|     expect(shouldProcessCommand(mockMessage.content, "!mdn")).toBe(false);
       |                                                               ^
    262|   });
    263|

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/8]⎯

 FAIL  test/commands.test.ts > Discord Bot Commands > should ignore command if it's part of a quoted message
AssertionError: expected true to be false // Object.is equality

- Expected
+ Received

- false
+ true

 ❯ test/commands.test.ts:273:63
    271|   it("should ignore command if it's part of a quoted message", () => {
    272|     mockMessage.content = `> Someone said: "!mdn Array.prototype.map is useful"`;
    273|     expect(shouldProcessCommand(mockMessage.content, "!mdn")).toBe(false);
       |                                                               ^
    274|   });
    275|

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/8]⎯

 FAIL  test/commands.test.ts > Discord Bot Commands > should ignore command if part is inside a code block
AssertionError: expected false to be true // Object.is equality

- Expected
+ Received

- true
+ false

 ❯ test/commands.test.ts:323:63
    321|     mockMessage.content =
    322|       "```js\nconsole.log('!mdn Array.prototype.map');\n``` !mdn Array.prototype.map";
    323|     expect(shouldProcessCommand(mockMessage.content, "!mdn")).toBe(true); // Only process the second one
       |                                                               ^
    324|   });
    325| });

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[8/8]⎯

 Test Files  1 failed | 5 passed (6)
      Tests  8 failed | 48 passed | 1 skipped (57)
   Start at  12:21:41
   Duration  1.40s (transform 378ms, setup 1ms, collect 1.57s, tests 504ms, environment 1ms, prepare 936ms)

@achyu-dev
Copy link
Contributor Author

Seems like this could be made a lot simpler utilizing a slightly more complex regex:

/!\w+(?=[^`]*(?:`[^`]*`[^`]*)*$)/

this should match !words not inside code blocks in action: https://regex101.com/r/pm4kqS/1

okay I added this regex

@achyu-dev achyu-dev requested a review from vcarl September 16, 2025 16:50
@achyu-dev achyu-dev changed the title Text block comments Commands inside Code Blocks - #412 Sep 17, 2025
@achyu-dev achyu-dev force-pushed the text-block-comments branch from 12b8c36 to 36bb00e Compare October 1, 2025 17:22
@achyu-dev achyu-dev closed this Oct 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

text in code blocks is treated as commands

4 participants