Search code examples
javascriptdiscord.jsline-breakschatgpt-api

How to properly make line breaks in a code block with dynamic input?


I have a problem. I have a Discord bot that allows users to communicate with GPT-4 using the chatgpt npm package. However, when the AI makes a line break, this is not properly reflected in the Discord message, and hence, the message is "smushed together". Like this: no line breaks

What can I do to actually have line breaks there? I tried telling GPT4 to use \n in the response, but when I did that, it was sent as "\n" in the code block and there were still no line breaks. Just \n between individual sentences. Here is a snipper of my code responsible for sending the message:

       response = await api.sendMessage("User has sent you a query to the roleplay. Respond without breaking character in terms of the roleplay as you were taught at the start. His query is: "+message.content, {
          parentMessageId: lastResponseId
        }).then(async (response) => {
          //add to user message history
          if (userMessageHistory.has(message.author.id)) {
            let userMessageHistoryArray = userMessageHistory.get(message.author.id);
            userMessageHistoryArray.push(response.id);
            userMessageHistory.set(message.author.id, userMessageHistoryArray);
          } else {
            let userMessageHistoryArray = [];
            userMessageHistoryArray.push(response.id);
            userMessageHistory.set(message.author.id, userMessageHistoryArray);
          }

          let responseFiltered = response.text.replace(/[^a-zA-ZěščřžýáíéďťňůúĚŠČŘŽÝÁÍÉĎŤŇŮÚ\?!,.0-9\\ -]/g, '');

          const responseChunks = responseFiltered.match(/.{1,1800}/g) || [responseFiltered]; // Handle case of no long responses
      
          for (const chunk of responseChunks) {
            // Use template literal for line breaks
            await message.channel.send({
              content: `<@${message.author.id}>\n\n\`\`\`\n${chunk}\n\`\`\``
            });
          }
      
          await message.reactions.removeAll();
          await message.react('<a:checkmark2:751058781156278382>')

Thank you.


Solution

  • Use trojan horse solution by replacing line breaks with a temporary delimiter. Then split the message to chunks and pass it to discord block and finally let the trojan jump out!

    const delimiter = '|||'; // Choose a delimiter that won't be present in the text
    
    const responseWithDelimiter = responseFiltered.replace(/\n/g, delimiter);
    
    const responseChunks = responseWithDelimiter.match(/.{1,1800}/g) || [responseWithDelimiter]; // Handle case of no long responses
    
    for (const chunk of responseChunks) {
        // Jumping out
        const formattedChunk = chunk.replace(new RegExp(delimiter, 'g'), '\n');
    
        await message.channel.send({
            content: `<@${message.author.id}>\n\n\`\`\`\n${formattedChunk}\n\`\`\``
        });
    }