fix(whatsapp): prevent invalid automation sends outside reply window (#15113)
WhatsApp automations now fail locally when they attempt to send a free-form message after the 24-hour customer service window has closed. This avoids sending an invalid template request to Meta and gives users a clear, actionable error instead of “Template not found or invalid template name.” Template messages continue to be sent whenever template parameters are present. Free-form messages continue to be sent normally while the conversation is replyable. Fixes https://linear.app/chatwoot/issue/PLA-183/prevent-whatsapp-automations-outside-the-24-hour-window-from-producing ### How to reproduce 1. Create a WhatsApp automation that sends a message without template parameters. 2. Trigger it on a conversation whose 24-hour customer service window is closed. 3. Observe that the message previously reached the template send path and failed with a misleading provider error. ### How to test 1. Trigger an automation with template parameters and confirm it sends as a template message. 2. Trigger an automation without template parameters inside the 24-hour window and confirm it sends as a free-form message. 3. Trigger an automation without template parameters outside the 24-hour window and confirm it fails locally with a clear error and makes no request to Meta. ### Things to know This changes only the invalid closed-window, no-template path. Existing template and in-window message behavior remains unchanged. --------- Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com>
This commit is contained in:
@@ -6,12 +6,10 @@ class Whatsapp::SendOnWhatsappService < Base::SendOnChannelService
|
||||
end
|
||||
|
||||
def perform_reply
|
||||
should_send_template_message = template_params.present? || !message.conversation.can_reply?
|
||||
if should_send_template_message
|
||||
send_template_message
|
||||
else
|
||||
send_session_message
|
||||
end
|
||||
return send_template_message if template_params.present?
|
||||
return send_session_message if message.conversation.can_reply?
|
||||
|
||||
message.update!(status: :failed, external_error: I18n.t('errors.whatsapp.message_outside_messaging_window'))
|
||||
end
|
||||
|
||||
def send_template_message
|
||||
|
||||
@@ -154,6 +154,7 @@ en:
|
||||
invalid_token_permissions: 'The access token does not have the required permissions for WhatsApp.'
|
||||
phone_info_fetch_failed: 'Failed to fetch phone number information. Please try again.'
|
||||
phone_number_already_exists: 'Channel already exists for this phone number: %{phone_number}, please contact support if the error persists'
|
||||
message_outside_messaging_window: 'Message not sent because the WhatsApp 24-hour customer service window is closed and no template parameters were provided. Send an approved template message instead.'
|
||||
reauthorization:
|
||||
generic: 'Failed to reauthorize WhatsApp. Please try again.'
|
||||
not_supported: 'Reauthorization is not supported for this type of WhatsApp channel.'
|
||||
|
||||
@@ -72,6 +72,21 @@ describe Whatsapp::SendOnWhatsappService do
|
||||
expect(message.reload.source_id).to eq('123456789')
|
||||
end
|
||||
|
||||
it 'fails a free-form message without contacting the provider when outside the 24 hour limit' do
|
||||
create(:message, message_type: :incoming, content: 'test', created_at: 25.hours.ago,
|
||||
conversation: conversation, account: conversation.account)
|
||||
message = create(:message, message_type: :outgoing, content: 'test',
|
||||
conversation: conversation, account: conversation.account)
|
||||
|
||||
expect(Whatsapp::TemplateProcessorService).not_to receive(:new)
|
||||
|
||||
described_class.new(message: message).perform
|
||||
|
||||
expect(message.reload.status).to eq('failed')
|
||||
expect(message.external_error).to eq(I18n.t('errors.whatsapp.message_outside_messaging_window'))
|
||||
expect(a_request(:post, 'https://waba.360dialog.io/v1/messages')).not_to have_been_made
|
||||
end
|
||||
|
||||
it 'marks message as failed when template name is blank' do
|
||||
processor = instance_double(Whatsapp::TemplateProcessorService)
|
||||
allow(Whatsapp::TemplateProcessorService).to receive(:new).and_return(processor)
|
||||
|
||||
Reference in New Issue
Block a user