fix(app-store): reuse existing response message

This commit is contained in:
Muhsin
2026-06-03 15:45:55 +04:00
parent 2fadbf81bc
commit 65ef019248
2 changed files with 57 additions and 6 deletions
@@ -9,8 +9,7 @@ class AppStore::SendOnAppStoreService < Base::SendOnChannelService
validate_feature_enabled!
validate_message_support!
source_id = channel.reply_to_review(review_id, reply_content)
message.update!(source_id: source_id) if source_id.present?
Messages::StatusUpdateService.new(message, 'delivered').perform
sync_response_message(source_id)
rescue StandardError => e
ChatwootExceptionTracker.new(e, account: message.account).capture_exception
Messages::StatusUpdateService.new(message, 'failed', e.message).perform
@@ -33,4 +32,34 @@ class AppStore::SendOnAppStoreService < Base::SendOnChannelService
def reply_content
message.outgoing_content.presence || message.content
end
def existing_response_message(source_id)
return if source_id.blank?
message.conversation.messages.where.not(id: message.id).find_by(source_id: source_id)
end
def sync_response_message(source_id)
response_message = existing_response_message(source_id)
if response_message.present?
update_existing_response_message(response_message, source_id)
message.destroy!
Messages::StatusUpdateService.new(response_message, 'delivered').perform
else
message.update!(source_id: source_id) if source_id.present?
Messages::StatusUpdateService.new(message, 'delivered').perform
end
end
def update_existing_response_message(response_message, source_id)
content_attributes = (response_message.content_attributes || {}).deep_merge(
'external_echo' => true,
'app_store' => {
'response_id' => source_id
}
)
response_message.update!(content: reply_content, content_attributes: content_attributes)
end
end
@@ -32,16 +32,38 @@ RSpec.describe AppStore::SendOnAppStoreService do
end
it 'updates the existing App Store response when the conversation already has one' do
create(:message, message_type: :outgoing, inbox: inbox, conversation: conversation, account: inbox.account, content: 'Old reply',
source_id: 'response-1')
existing_response = create(
:message,
message_type: :outgoing,
inbox: inbox,
conversation: conversation,
account: inbox.account,
content: 'Old reply',
source_id: 'response-1',
content_attributes: {
external_echo: true,
app_store: {
response_id: 'response-1',
response_state: 'PUBLISHED'
}
}
)
message = create(:message, message_type: :outgoing, inbox: inbox, conversation: conversation, account: inbox.account, content: 'Updated reply')
allow(channel).to receive(:reply_to_review).and_return('response-1')
described_class.new(message: message).perform
expect { described_class.new(message: message).perform }
.to change { conversation.messages.reload.count }.by(-1)
expect(channel).to have_received(:reply_to_review).with('review-1', 'Updated reply')
expect(Messages::StatusUpdateService).to have_received(:new).with(message, 'delivered')
expect { message.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect(existing_response.reload.content).to eq('Updated reply')
expect(existing_response.content_attributes['external_echo']).to be true
expect(existing_response.content_attributes['app_store']).to include(
'response_id' => 'response-1',
'response_state' => 'PUBLISHED'
)
expect(Messages::StatusUpdateService).to have_received(:new).with(existing_response, 'delivered')
end
it 'marks the message as failed when attachments are present' do