Skip to content

Conversation

achyu-dev
Copy link
Contributor

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

Added a new logic to check the commands inside nested / normal codeblocks

export function removeCodeBlocksAndQuotes(text: string): string {
  if (!text) return "";
  let filtered = text.replace(/```[\s\S]*?```/g, "");
  filtered = filtered.replace(/`[^`]+`/g, "");
  filtered = filtered.replace(/^>.*$/gm, "");
  filtered = filtered.replace(/>>>[\s\S]*?(?=\n\n|$)/g, "");
  filtered = filtered.replace(/\n{3,}/g, "\n\n").trim();
  return filtered;
}

export function isInsideCodeBlock(text: string, position: number): boolean {
  let insideSingle = false;
  let insideTriple = false;
  let i = 0;
  
  while (i < position) {
    if (text.slice(i, i + 3) === "```") {
      insideTriple = !insideTriple;
      i += 3;
    } else if (text[i] === "`" && !insideTriple) {
      insideSingle = !insideSingle;
      i++;
    } else {
      i++;
    }
  }

  return insideSingle || insideTriple;
}

Copy link

what-the-diff bot commented Mar 25, 2025

PR Summary

  • Improved Development Script in package.json
    The development script inside the root package.json file has been updated. Now, it can run different types of development tasks (dev:bot and dev:test) at the same time. This change will allow developers to work more efficiently.

  • Enhanced Accessibility of commandsList in src/features/commands.ts
    The commandsList constant, which holds a list of all our bot's commands, is now accessible from other modules. This will allow other parts of the bot to utilize this list if needed, contributing to better modularity.

  • Added a New !crosspost Command to the Bot
    A new command !crosspost has been added to the bot. This command shares a message informing users about the importance of avoiding cross-posting in channels. It also includes embedded messages emphasizing the significance of focused communication.

  • Created shouldTriggerCommand Function for Command Validation
    A new function shouldTriggerCommand has been introduced. It uses regex (pattern matching) to decide whether commands are valid based on their placement in the message. It specifically ignores commands within code blocks to prevent undesired triggering.

  • Refined Command Handling Logic in Message Handling
    The command handling logic in message handling has been refined. It now utilizes shouldTriggerCommand function for a more accurate verification of commands rather than simple inclusion checks within msg.content. This will make our bot respond more accurately to user inputs.

  • Included Comprehensive Tests in test/commands.test.ts
    New tests have been added to verify the behavior of commands under various circumstances. It includes tests for edge cases like commands within different code block formats, handling of whitespace, handling of mixed messages, and handling of special characters. This will ensure that our bot behaves as expected under all these varied scenarios.

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

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.

4 participants