[core] ChatWoot - markdown fix for symbols in the middle of text

fix #1643
This commit is contained in:
devlikepro committed 2025-12-05 00:13:14 -08:00
1 parent 18d8330ab3
commit 0f5fcf60f6
3 files changed
+65 -16

No files matched your search

@@ -108,15 +108,15 @@ describe('PixMessage - pt-BR', () => {
const result = converter.convert(payload, protoMessage);
// Assert
const expected = `💳 ****PIX - Copia e Cola****
const expected = `💳 **PIX - Copia e Cola**
****Merchant Name Here****
**Merchant Name Here**
****Chave PIX:**** +5000000000000
****Tipo:**** PHONE
****Referência:**** 4TB11111111
**Chave PIX:** +5000000000000
**Tipo:** PHONE
**Referência:** 4TB11111111
💳 ****PIX Copia e Cola enviado****`;
💳 **PIX Copia e Cola enviado**`;
expect(protoMessage).not.toBeNull();
expect(result).not.toBeNull();
@@ -227,16 +227,16 @@ describe('PixMessage - pt-BR', () => {
const result = converter.convert(payload, protoMessage);
// Assert
const expected = `💳 ****PIX - Copia e Cola****
const expected = `💳 **PIX - Copia e Cola**
****Merchant Name Here****
**Merchant Name Here**
****Chave PIX:**** +5000000000000
****Tipo:**** PHONE
****Valor:**** R$\u00A025,12
****Referência:**** 4TB11111111
**Chave PIX:** +5000000000000
**Tipo:** PHONE
**Valor:** R$\u00A025,12
**Referência:** 4TB11111111
💳 ****PIX Copia e Cola enviado****`;
💳 **PIX Copia e Cola enviado**`;
expect(protoMessage).not.toBeNull();
expect(result).not.toBeNull();
@@ -53,4 +53,40 @@ describe('WhatsappToMarkdown', () => {
const expected = 'URL: https://example.com/test_page e texto *em itálico*';
expect(WhatsappToMarkdown(input)).toBe(expected);
});
it('keeps already bold markdown intact', () => {
const input = '**PIX - Copia e Cola**';
expect(WhatsappToMarkdown(input)).toBe(input);
});
it('keeps already strikethrough markdown intact', () => {
const input = '~~removed~~';
expect(WhatsappToMarkdown(input)).toBe(input);
});
it('keeps underscores inside identifiers intact', () => {
const input = 'api key: abc_test_key';
expect(WhatsappToMarkdown(input)).toBe(input);
});
it('does not convert underscores inside words', () => {
const input = 'Instance name: customer_prod_instance';
expect(WhatsappToMarkdown(input)).toBe(input);
});
it('does not convert when markers are stuck to word characters', () => {
const input = 'My name is*Rafael* and email is test_user@example.com';
expect(WhatsappToMarkdown(input)).toBe(input);
});
it('keeps formatting when markers touch punctuation boundaries', () => {
const input = 'Hello *Rafael*, welcome to _WAHA_!';
const expected = 'Hello **Rafael**, welcome to *WAHA*!';
expect(WhatsappToMarkdown(input)).toBe(expected);
});
it('ignores markers with inner spaces next to the marker', () => {
const input = '* text* and _ text_ should stay the same';
expect(WhatsappToMarkdown(input)).toBe(input);
});
});
@@ -1,5 +1,18 @@
import { UrlProtection } from '@waha/apps/chatwoot/messages/to/markdown';
const boldPattern = new RegExp(
`(?<![\\p{L}\\p{N}_*])\\*(?!\\*)(?=\\S)(.+?)(?<=\\S)\\*(?![\\p{L}\\p{N}_*])`,
'gu',
);
const italicPattern = new RegExp(
`(?<![\\p{L}\\p{N}_])_(?!_)(?=\\S)(.+?)(?<=\\S)_(?![\\p{L}\\p{N}_])`,
'gu',
);
const strikePattern = new RegExp(
`(?<![\\p{L}\\p{N}_~])~(?!~)(?=\\S)(.+?)(?<=\\S)~(?![\\p{L}\\p{N}_~])`,
'gu',
);
export function WhatsappToMarkdown(text: string): string {
if (!text) {
return text;
@@ -16,11 +29,11 @@ export function WhatsappToMarkdown(text: string): string {
// Apply markdown transformations to "clean" text
let result = text
// Bold: *bold* → **bold**
.replace(/\*(.*?)\*/g, '**$1**')
.replace(boldPattern, '**$1**')
// Strikethrough: ~strike~ → ~~strike~~
.replace(/~(.*?)~/g, '~~$1~~')
.replace(strikePattern, '~~$1~~')
// Italic: _italic_ → *italic*
.replace(/_(.*?)_/g, '*$1*');
.replace(italicPattern, '*$1*');
// Restore original URLs after all transformations
result = urls.restore(result);