diff --git a/app/javascript/dashboard/i18n/locale/en/integrations.json b/app/javascript/dashboard/i18n/locale/en/integrations.json index 50b2be3ec..ceeeabd56 100644 --- a/app/javascript/dashboard/i18n/locale/en/integrations.json +++ b/app/javascript/dashboard/i18n/locale/en/integrations.json @@ -38,6 +38,8 @@ "CONVERSATION_STATUS_CHANGED": "Conversation Status Changed", "CONVERSATION_UPDATED": "Conversation Updated", "MESSAGE_CREATED": "Message created", + "MESSAGE_INCOMING": "Incoming message", + "MESSAGE_OUTGOING": "Outgoing message", "MESSAGE_UPDATED": "Message updated", "WEBWIDGET_TRIGGERED": "Live chat widget opened by the user", "CONTACT_CREATED": "Contact created", diff --git a/app/javascript/dashboard/i18n/locale/pt_BR/integrations.json b/app/javascript/dashboard/i18n/locale/pt_BR/integrations.json index 478192a31..e18b15148 100644 --- a/app/javascript/dashboard/i18n/locale/pt_BR/integrations.json +++ b/app/javascript/dashboard/i18n/locale/pt_BR/integrations.json @@ -38,6 +38,8 @@ "CONVERSATION_STATUS_CHANGED": "Status de conversa alterado", "CONVERSATION_UPDATED": "Conversa Atualizada", "MESSAGE_CREATED": "Mensagem criada", + "MESSAGE_INCOMING": "Mensagem recebida", + "MESSAGE_OUTGOING": "Mensagem enviada", "MESSAGE_UPDATED": "Mensagem atualizada", "WEBWIDGET_TRIGGERED": "Widget de chat aberto pelo usuário", "CONTACT_CREATED": "Contato criado", diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/WebhookForm.vue b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/WebhookForm.vue index bb50aa879..1225c76a7 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/WebhookForm.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/WebhookForm.vue @@ -14,6 +14,8 @@ const SUPPORTED_WEBHOOK_EVENTS = [ 'conversation_status_changed', 'conversation_updated', 'message_created', + 'message_incoming', + 'message_outgoing', 'message_updated', 'webwidget_triggered', 'contact_created', diff --git a/app/listeners/webhook_listener.rb b/app/listeners/webhook_listener.rb index 1da036d85..3b2f2d2d5 100644 --- a/app/listeners/webhook_listener.rb +++ b/app/listeners/webhook_listener.rb @@ -30,6 +30,29 @@ class WebhookListener < BaseListener payload = message.webhook_data.merge(event: __method__.to_s) deliver_webhook_payloads(payload, inbox) + + message_incoming(event) + message_outgoing(event) + end + + def message_incoming(event) + message = extract_message_and_account(event)[0] + + return unless message.webhook_sendable? + return unless message.incoming? + + payload = message.webhook_data.merge(event: __method__.to_s) + deliver_account_webhooks(payload, message.account) + end + + def message_outgoing(event) + message = extract_message_and_account(event)[0] + + return unless message.webhook_sendable? + return unless message.outgoing? + + payload = message.webhook_data.merge(event: __method__.to_s) + deliver_account_webhooks(payload, message.account) end def message_updated(event) diff --git a/app/models/webhook.rb b/app/models/webhook.rb index a0c302dfd..af5a3c5f5 100644 --- a/app/models/webhook.rb +++ b/app/models/webhook.rb @@ -27,8 +27,8 @@ class Webhook < ApplicationRecord enum webhook_type: { account_type: 0, inbox_type: 1 } ALLOWED_WEBHOOK_EVENTS = %w[conversation_status_changed conversation_updated conversation_created contact_created contact_updated - message_created message_updated webwidget_triggered inbox_created inbox_updated - conversation_typing_on conversation_typing_off provider_event_received].freeze + message_created message_incoming message_outgoing message_updated webwidget_triggered + inbox_created inbox_updated conversation_typing_on conversation_typing_off provider_event_received].freeze private diff --git a/lib/webhooks/error_handler.rb b/lib/webhooks/error_handler.rb index cfcb03cfb..6aff0935d 100644 --- a/lib/webhooks/error_handler.rb +++ b/lib/webhooks/error_handler.rb @@ -1,5 +1,5 @@ class Webhooks::ErrorHandler - SUPPORTED_EVENTS = %w[message_created message_updated].freeze + SUPPORTED_EVENTS = %w[message_created message_incoming message_outgoing message_updated].freeze def initialize(payload, webhook_type, error) @payload = payload diff --git a/spec/listeners/webhook_listener_spec.rb b/spec/listeners/webhook_listener_spec.rb index 867dc5f1f..8bb899534 100644 --- a/spec/listeners/webhook_listener_spec.rb +++ b/spec/listeners/webhook_listener_spec.rb @@ -101,6 +101,86 @@ describe WebhookListener do end end + describe '#message_incoming' do + let(:event_name) { :'message.created' } + let!(:incoming_message) do + create(:message, message_type: 'incoming', + account: account, inbox: inbox, conversation: conversation) + end + let!(:incoming_message_event) { Events::Base.new(event_name, Time.zone.now, message: incoming_message) } + + context 'when webhook is not configured' do + it 'does not trigger webhook' do + expect(WebhookJob).to receive(:perform_later).exactly(0).times + listener.message_incoming(incoming_message_event) + end + end + + context 'when webhook is configured and message is incoming' do + it 'triggers the webhook event' do + webhook = create(:webhook, inbox: inbox, account: account, subscriptions: ['message_incoming']) + expect(WebhookJob).to receive(:perform_later).with(webhook.url, incoming_message.webhook_data.merge(event: 'message_incoming')).once + listener.message_incoming(incoming_message_event) + end + end + + context 'when webhook is configured and message is outgoing' do + it 'does not trigger the webhook event' do + create(:webhook, inbox: inbox, account: account, subscriptions: ['message_incoming']) + expect(WebhookJob).not_to receive(:perform_later) + listener.message_incoming(message_created_event) + end + end + + context 'when webhook is configured but event is not subscribed' do + it 'does not trigger the webhook event' do + create(:webhook, subscriptions: ['conversation_created'], inbox: inbox, account: account) + expect(WebhookJob).not_to receive(:perform_later) + listener.message_incoming(incoming_message_event) + end + end + end + + describe '#message_outgoing' do + let(:event_name) { :'message.created' } + let!(:incoming_message) do + create(:message, message_type: 'incoming', + account: account, inbox: inbox, conversation: conversation) + end + let!(:incoming_message_event) { Events::Base.new(event_name, Time.zone.now, message: incoming_message) } + + context 'when webhook is not configured' do + it 'does not trigger webhook' do + expect(WebhookJob).to receive(:perform_later).exactly(0).times + listener.message_outgoing(message_created_event) + end + end + + context 'when webhook is configured and message is outgoing' do + it 'triggers the webhook event' do + webhook = create(:webhook, inbox: inbox, account: account, subscriptions: ['message_outgoing']) + expect(WebhookJob).to receive(:perform_later).with(webhook.url, message.webhook_data.merge(event: 'message_outgoing')).once + listener.message_outgoing(message_created_event) + end + end + + context 'when webhook is configured and message is incoming' do + it 'does not trigger the webhook event' do + create(:webhook, inbox: inbox, account: account, subscriptions: ['message_outgoing']) + expect(WebhookJob).not_to receive(:perform_later) + listener.message_outgoing(incoming_message_event) + end + end + + context 'when webhook is configured but event is not subscribed' do + it 'does not trigger the webhook event' do + create(:webhook, subscriptions: ['conversation_created'], inbox: inbox, account: account) + expect(WebhookJob).not_to receive(:perform_later) + listener.message_outgoing(message_created_event) + end + end + end + describe '#conversation_created' do let(:event_name) { :'conversation.created' }