mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-03 04:27:53 +00:00
feat: Handle Line send message/attachments errors (#8200)
This commit is contained in:
@@ -205,6 +205,11 @@ export default {
|
||||
) {
|
||||
return this.sourceId && this.isSent;
|
||||
}
|
||||
// There is no source id for the line channel
|
||||
if (this.isALineChannel) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
showDeliveredIndicator() {
|
||||
@@ -223,6 +228,9 @@ export default {
|
||||
if (this.isAWebWidgetInbox || this.isAPIInbox) {
|
||||
return this.isSent;
|
||||
}
|
||||
if (this.isALineChannel) {
|
||||
return this.isDelivered;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
@@ -6,6 +6,30 @@ class Line::SendOnLineService < Base::SendOnChannelService
|
||||
end
|
||||
|
||||
def perform_reply
|
||||
channel.client.push_message(message.conversation.contact_inbox.source_id, [{ type: 'text', text: message.content }])
|
||||
response = channel.client.push_message(message.conversation.contact_inbox.source_id, [{ type: 'text', text: message.content }])
|
||||
return if response.blank?
|
||||
|
||||
parsed_json = JSON.parse(response.body)
|
||||
|
||||
if response.code == '200'
|
||||
# If the request is successful, update the message status to delivered
|
||||
message.update!(status: :delivered)
|
||||
else
|
||||
# If the request is not successful, update the message status to failed and save the external error
|
||||
message.update!(status: :failed, external_error: external_error(parsed_json))
|
||||
end
|
||||
end
|
||||
|
||||
# https://developers.line.biz/en/reference/messaging-api/#error-responses
|
||||
def external_error(error)
|
||||
# Message containing information about the error. See https://developers.line.biz/en/reference/messaging-api/#error-messages
|
||||
message = error['message']
|
||||
# An array of error details. If the array is empty, this property will not be included in the response.
|
||||
details = error['details']
|
||||
|
||||
return message if details.blank?
|
||||
|
||||
detail_messages = details.map { |detail| "#{detail['property']}: #{detail['message']}" }
|
||||
[message, detail_messages].join(', ')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,17 +2,95 @@ require 'rails_helper'
|
||||
|
||||
describe Line::SendOnLineService do
|
||||
describe '#perform' do
|
||||
context 'when a valid message' do
|
||||
let(:line_client) { double }
|
||||
let(:line_channel) { create(:channel_line) }
|
||||
let(:message) do
|
||||
create(:message, message_type: :outgoing, content: 'test',
|
||||
conversation: create(:conversation, inbox: line_channel.inbox))
|
||||
end
|
||||
|
||||
before do
|
||||
allow(Line::Bot::Client).to receive(:new).and_return(line_client)
|
||||
end
|
||||
|
||||
context 'when message send' do
|
||||
it 'calls @channel.client.push_message' do
|
||||
line_client = double
|
||||
line_channel = create(:channel_line)
|
||||
message = create(:message, message_type: :outgoing, content: 'test',
|
||||
conversation: create(:conversation, inbox: line_channel.inbox))
|
||||
allow(line_client).to receive(:push_message)
|
||||
allow(Line::Bot::Client).to receive(:new).and_return(line_client)
|
||||
expect(line_client).to receive(:push_message)
|
||||
described_class.new(message: message).perform
|
||||
end
|
||||
end
|
||||
|
||||
context 'when message send fails without details' do
|
||||
let(:error_response) do
|
||||
{
|
||||
'message' => 'The request was invalid'
|
||||
}.to_json
|
||||
end
|
||||
|
||||
before do
|
||||
allow(line_client).to receive(:push_message).and_return(OpenStruct.new(code: '400', body: error_response))
|
||||
end
|
||||
|
||||
it 'updates the message status to failed' do
|
||||
described_class.new(message: message).perform
|
||||
message.reload
|
||||
expect(message.status).to eq('failed')
|
||||
end
|
||||
|
||||
it 'updates the external error without details' do
|
||||
described_class.new(message: message).perform
|
||||
message.reload
|
||||
expect(message.external_error).to eq('The request was invalid')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when message send fails with details' do
|
||||
let(:error_response) do
|
||||
{
|
||||
'message' => 'The request was invalid',
|
||||
'details' => [
|
||||
{
|
||||
'property' => 'messages[0].text',
|
||||
'message' => 'May not be empty'
|
||||
}
|
||||
]
|
||||
}.to_json
|
||||
end
|
||||
|
||||
before do
|
||||
allow(line_client).to receive(:push_message).and_return(OpenStruct.new(code: '400', body: error_response))
|
||||
end
|
||||
|
||||
it 'updates the message status to failed' do
|
||||
described_class.new(message: message).perform
|
||||
message.reload
|
||||
expect(message.status).to eq('failed')
|
||||
end
|
||||
|
||||
it 'updates the external error with details' do
|
||||
described_class.new(message: message).perform
|
||||
message.reload
|
||||
expect(message.external_error).to eq('The request was invalid, messages[0].text: May not be empty')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when message send succeeds' do
|
||||
let(:success_response) do
|
||||
{
|
||||
'message' => 'ok'
|
||||
}.to_json
|
||||
end
|
||||
|
||||
before do
|
||||
allow(line_client).to receive(:push_message).and_return(OpenStruct.new(code: '200', body: success_response))
|
||||
end
|
||||
|
||||
it 'updates the message status to delivered' do
|
||||
described_class.new(message: message).perform
|
||||
message.reload
|
||||
expect(message.status).to eq('delivered')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user