fix(slack): Show correct sender name and avatar for Slack replies (#13624)

This commit is contained in:
Muhsin Keloth
2026-02-26 14:45:15 +04:00
committed by GitHub
parent 109b43aadb
commit 6b3f1114fd
4 changed files with 151 additions and 20 deletions

View File

@@ -69,7 +69,7 @@ describe Integrations::Slack::IncomingMessageBuilder do
expect(hook).not_to be_nil
messages_count = conversation.messages.count
builder = described_class.new(message_params)
allow(builder).to receive(:sender).and_return(nil)
allow(builder).to receive(:resolve_slack_sender).and_return([nil, nil, nil])
2.times.each { builder.perform }
expect(conversation.messages.count).to eql(messages_count + 1)
expect(conversation.messages.last.content).to eql('this is test https://chatwoot.com Hey @Sojan Test again')
@@ -79,7 +79,7 @@ describe Integrations::Slack::IncomingMessageBuilder do
expect(hook).not_to be_nil
messages_count = conversation.messages.count
builder = described_class.new(message_params)
allow(builder).to receive(:sender).and_return(nil)
allow(builder).to receive(:resolve_slack_sender).and_return([nil, nil, nil])
builder.perform
expect(conversation.messages.count).to eql(messages_count + 1)
expect(conversation.messages.last.content).to eql('this is test https://chatwoot.com Hey @Sojan Test again')
@@ -89,7 +89,7 @@ describe Integrations::Slack::IncomingMessageBuilder do
expect(hook).not_to be_nil
messages_count = conversation.messages.count
builder = described_class.new(private_message_params)
allow(builder).to receive(:sender).and_return(nil)
allow(builder).to receive(:resolve_slack_sender).and_return([nil, nil, nil])
builder.perform
expect(conversation.messages.count).to eql(messages_count + 1)
expect(conversation.messages.last.content).to eql('pRivate: A private note message')
@@ -130,7 +130,7 @@ describe Integrations::Slack::IncomingMessageBuilder do
messages_count = conversation.messages.count
message_with_attachments[:event][:files] = nil
builder = described_class.new(message_with_attachments)
allow(builder).to receive(:sender).and_return(nil)
allow(builder).to receive(:resolve_slack_sender).and_return([nil, nil, nil])
builder.perform
expect(conversation.messages.count).to eql(messages_count)
end
@@ -139,7 +139,7 @@ describe Integrations::Slack::IncomingMessageBuilder do
expect(hook).not_to be_nil
messages_count = conversation.messages.count
builder = described_class.new(message_with_attachments)
allow(builder).to receive(:sender).and_return(nil)
allow(builder).to receive(:resolve_slack_sender).and_return([nil, nil, nil])
builder.perform
expect(conversation.messages.count).to eql(messages_count + 1)
expect(conversation.messages.last.content).to eql('this is test https://chatwoot.com Hey @Sojan Test again')
@@ -152,7 +152,7 @@ describe Integrations::Slack::IncomingMessageBuilder do
message_with_attachments[:event][:text] = 'Attached File!'
builder = described_class.new(message_with_attachments)
allow(builder).to receive(:sender).and_return(nil)
allow(builder).to receive(:resolve_slack_sender).and_return([nil, nil, nil])
builder.perform
expect(conversation.messages.count).to eql(messages_count)
@@ -165,13 +165,113 @@ describe Integrations::Slack::IncomingMessageBuilder do
video_attachment_params[:event][:files][0][:mimetype] = 'video/mp4'
builder = described_class.new(video_attachment_params)
allow(builder).to receive(:sender).and_return(nil)
allow(builder).to receive(:resolve_slack_sender).and_return([nil, nil, nil])
expect { builder.perform }.not_to raise_error
expect(conversation.messages.last.attachments).to be_any
end
end
context 'when resolving slack sender' do
let(:builder) { described_class.new(message_params) }
before do
allow(builder).to receive(:slack_client).and_return(slack_client)
end
context 'when slack user email matches a chatwoot agent' do
before do
create(:user, account: conversation.account, email: 'agent@example.com')
slack_response = {
user: {
profile: { email: 'agent@example.com', display_name: 'Muhsin K', image_192: 'https://avatars.slack-edge.com/avatar.png' },
real_name: 'Muhsin K',
name: 'muhsink'
}
}
allow(slack_client).to receive(:users_info)
.with(user: message_params[:event][:user])
.and_return(slack_response)
end
it 'sets the matched agent as message sender' do
builder.perform
expect(conversation.messages.last.sender).to eq(conversation.account.users.from_email('agent@example.com'))
end
it 'does not store sender_name in additional_attributes' do
builder.perform
expect(conversation.messages.last.additional_attributes).not_to have_key('sender_name')
end
end
context 'when slack user email does not match any chatwoot agent' do
before do
slack_response = {
user: {
profile: { email: 'unknown@example.com', display_name: 'Muhsin K', image_192: 'https://avatars.slack-edge.com/avatar.png' },
real_name: 'Muhsin K',
name: 'muhsink'
}
}
allow(slack_client).to receive(:users_info)
.with(user: message_params[:event][:user])
.and_return(slack_response)
end
it 'saves sender_name from slack display_name in additional_attributes' do
builder.perform
expect(conversation.messages.last.sender).to be_nil
expect(conversation.messages.last.additional_attributes['sender_name']).to eq('Muhsin K')
end
it 'saves sender_avatar_url from slack profile image in additional_attributes' do
builder.perform
expect(conversation.messages.last.additional_attributes['sender_avatar_url'])
.to eq('https://avatars.slack-edge.com/avatar.png')
end
it 'falls back to real_name when display_name is blank' do
allow(slack_client).to receive(:users_info).and_return({
user: {
profile: { email: 'unknown@example.com', display_name: '',
image_192: nil }, real_name: 'Muhsin K', name: 'muhsink'
}
})
builder.perform
expect(conversation.messages.last.additional_attributes['sender_name']).to eq('Muhsin K')
end
it 'falls back to slack username when display_name and real_name are both blank' do
allow(slack_client).to receive(:users_info).and_return({
user: {
profile: { email: 'unknown@example.com', display_name: '',
image_192: nil }, real_name: '', name: 'muhsink'
}
})
builder.perform
expect(conversation.messages.last.additional_attributes['sender_name']).to eq('muhsink')
end
end
context 'when the slack API call raises an error' do
before do
allow(slack_client).to receive(:users_info).and_raise(StandardError, 'API error')
end
it 'creates the message with nil sender' do
expect { builder.perform }.not_to raise_error
expect(conversation.messages.last.sender).to be_nil
end
it 'does not store sender info in additional_attributes' do
builder.perform
expect(conversation.messages.last.additional_attributes).not_to have_key('sender_name')
expect(conversation.messages.last.additional_attributes).not_to have_key('sender_avatar_url')
end
end
end
context 'when link shared' do
let(:link_shared) do
{