mirror of
https://github.com/lingble/chatwoot.git
synced 2025-10-29 18:22:53 +00:00
fix: Handle emoji and special characters in mention notifications (#11857)
Fixes notification display issues when user or team names contain emojis
and special characters. Previously, mention notifications would show
URL-encoded characters instead of properly formatted names with emojis.
**Before:**
Notification: "John Doe: Hey @%F0%9F%91%8D%20customer%20support please
check this"
**After:**
Notification: "John Doe: Hey @👍 customer support please check this"
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
module MessageFormatHelper
|
||||
include RegexHelper
|
||||
|
||||
def transform_user_mention_content(message_content)
|
||||
# attachment message without content, message_content is nil
|
||||
message_content.presence ? message_content.gsub(MENTION_REGEX, '\1') : ''
|
||||
return '' unless message_content.presence
|
||||
|
||||
# Use CommonMarker to convert markdown to plain text for notifications
|
||||
# This handles all markdown formatting (links, bold, italic, etc.) not just mentions
|
||||
# Converts: [@👍 customer support](mention://team/1/%F0%9F%91%8D%20customer%20support)
|
||||
# To: @👍 customer support
|
||||
CommonMarker.render_doc(message_content).to_plaintext.strip
|
||||
end
|
||||
|
||||
def render_message_content(message_content)
|
||||
|
||||
@@ -5,7 +5,13 @@ module RegexHelper
|
||||
# valid unicode letter, unicode number, underscore, hyphen
|
||||
# shouldn't start with a underscore or hyphen
|
||||
UNICODE_CHARACTER_NUMBER_HYPHEN_UNDERSCORE = Regexp.new('\A[\p{L}\p{N}]+[\p{L}\p{N}_-]+\Z')
|
||||
MENTION_REGEX = Regexp.new('\[(@[\w_. ]+)\]\(mention://(?:user|team)/\d+/(.*?)+\)')
|
||||
# Regex to match mention markdown links and extract display names
|
||||
# Matches: [@display name](mention://user|team/id/url_encoded_name)
|
||||
# Captures: 1) @display name (including emojis), 2) url_encoded_name
|
||||
# Uses [^]]+ to match any characters except ] in display name to support emojis
|
||||
# NOTE: Still used by Slack integration (lib/integrations/slack/send_on_slack_service.rb)
|
||||
# while notifications use CommonMarker for better markdown processing
|
||||
MENTION_REGEX = Regexp.new('\[(@[^]]+)\]\(mention://(?:user|team)/\d+/([^)]+)\)')
|
||||
|
||||
TWILIO_CHANNEL_SMS_REGEX = Regexp.new('^\+\d{1,15}\z')
|
||||
TWILIO_CHANNEL_WHATSAPP_REGEX = Regexp.new('^whatsapp:\+\d{1,15}\z')
|
||||
|
||||
@@ -3,9 +3,37 @@ require 'rails_helper'
|
||||
describe MessageFormatHelper do
|
||||
describe '#transform_user_mention_content' do
|
||||
context 'when transform_user_mention_content called' do
|
||||
it 'return transormed text correctly' do
|
||||
it 'return transformed text correctly' do
|
||||
expect(helper.transform_user_mention_content('[@john](mention://user/1/John%20K), check this ticket')).to eq '@john, check this ticket'
|
||||
end
|
||||
|
||||
it 'handles emoji in display names correctly' do
|
||||
content = '[@👍 customer support](mention://team/1/%F0%9F%91%8D%20customer%20support), please help'
|
||||
expected = '@👍 customer support, please help'
|
||||
expect(helper.transform_user_mention_content(content)).to eq expected
|
||||
end
|
||||
|
||||
it 'handles multiple mentions with emojis and spaces' do
|
||||
content = 'Hey [@John Doe](mention://user/1/John%20Doe) and [@🚀 Dev Team](mention://team/2/%F0%9F%9A%80%20Dev%20Team)'
|
||||
expected = 'Hey @John Doe and @🚀 Dev Team'
|
||||
expect(helper.transform_user_mention_content(content)).to eq expected
|
||||
end
|
||||
|
||||
it 'handles emoji-only team names' do
|
||||
expect(helper.transform_user_mention_content('[@🔥](mention://team/3/%F0%9F%94%A5) urgent')).to eq '@🔥 urgent'
|
||||
end
|
||||
|
||||
it 'handles special characters in names' do
|
||||
expect(helper.transform_user_mention_content('[@user@domain.com](mention://user/4/user%40domain.com) check')).to eq '@user@domain.com check'
|
||||
end
|
||||
|
||||
it 'returns empty string for nil content' do
|
||||
expect(helper.transform_user_mention_content(nil)).to eq ''
|
||||
end
|
||||
|
||||
it 'returns empty string for empty content' do
|
||||
expect(helper.transform_user_mention_content('')).to eq ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -128,6 +128,39 @@ has been assigned to you"
|
||||
expect(notification.push_message_body).to eq "#{message.sender.name}: Hey @John Peter please check this?"
|
||||
end
|
||||
|
||||
it 'returns appropriate body suited for the notification type conversation_mention if username contains emoji' do
|
||||
conversation = create(:conversation)
|
||||
content = 'Hey [@👍 customer support](mention://team/1/%F0%9F%91%8D%20customer%20support) please check this?'
|
||||
message = create(:message, sender: create(:user), content: content, conversation: conversation)
|
||||
notification = create(:notification, notification_type: 'conversation_mention', primary_actor: conversation, secondary_actor: message)
|
||||
expect(notification.push_message_body).to eq "#{message.sender.name}: Hey @👍 customer support please check this?"
|
||||
end
|
||||
|
||||
it 'returns appropriate body suited for the notification type conversation_mention if team name contains emoji and spaces' do
|
||||
conversation = create(:conversation)
|
||||
content = 'Please check [@🚀 Development Team](mention://team/2/%F0%9F%9A%80%20Development%20Team)'
|
||||
message = create(:message, sender: create(:user), content: content, conversation: conversation)
|
||||
notification = create(:notification, notification_type: 'conversation_mention', primary_actor: conversation, secondary_actor: message)
|
||||
expect(notification.push_message_body).to eq "#{message.sender.name}: Please check @🚀 Development Team"
|
||||
end
|
||||
|
||||
it 'returns appropriate body suited for the notification type conversation_mention with mixed emoji and regular mentions' do
|
||||
conversation = create(:conversation)
|
||||
content = 'Hey [@John Doe](mention://user/1/John%20Doe) and ' \
|
||||
'[@👍 customer support](mention://team/1/%F0%9F%91%8D%20customer%20support) please review'
|
||||
message = create(:message, sender: create(:user), content: content, conversation: conversation)
|
||||
notification = create(:notification, notification_type: 'conversation_mention', primary_actor: conversation, secondary_actor: message)
|
||||
expect(notification.push_message_body).to eq "#{message.sender.name}: Hey @John Doe and @👍 customer support please review"
|
||||
end
|
||||
|
||||
it 'returns appropriate body suited for the notification type conversation_mention with special characters in names' do
|
||||
conversation = create(:conversation)
|
||||
content = 'Please review [@user@domain.com](mention://user/4/user%40domain.com)'
|
||||
message = create(:message, sender: create(:user), content: content, conversation: conversation)
|
||||
notification = create(:notification, notification_type: 'conversation_mention', primary_actor: conversation, secondary_actor: message)
|
||||
expect(notification.push_message_body).to eq "#{message.sender.name}: Please review @user@domain.com"
|
||||
end
|
||||
|
||||
it 'calls remove duplicate notification job' do
|
||||
allow(Notification::RemoveDuplicateNotificationJob).to receive(:perform_later)
|
||||
notification = create(:notification, notification_type: 'conversation_mention')
|
||||
|
||||
Reference in New Issue
Block a user