diff --git a/app/controllers/api/v1/accounts/webhooks_controller.rb b/app/controllers/api/v1/accounts/webhooks_controller.rb
index 0add18047..7ea257ed2 100644
--- a/app/controllers/api/v1/accounts/webhooks_controller.rb
+++ b/app/controllers/api/v1/accounts/webhooks_controller.rb
@@ -23,7 +23,7 @@ class Api::V1::Accounts::WebhooksController < Api::V1::Accounts::BaseController
private
def webhook_params
- params.require(:webhook).permit(:inbox_id, :url)
+ params.require(:webhook).permit(:inbox_id, :url, subscriptions: [])
end
def fetch_webhook
diff --git a/app/javascript/dashboard/assets/scss/_utility-helpers.scss b/app/javascript/dashboard/assets/scss/_utility-helpers.scss
index abea0e28c..71977cf2b 100644
--- a/app/javascript/dashboard/assets/scss/_utility-helpers.scss
+++ b/app/javascript/dashboard/assets/scss/_utility-helpers.scss
@@ -2,6 +2,10 @@
margin-right: var(--space-small);
}
+.margin-bottom-small {
+ margin-bottom: var(--space-small);
+}
+
.margin-right-smaller {
margin-right: var(--space-smaller);
}
diff --git a/app/javascript/dashboard/components/widgets/ShowMore.vue b/app/javascript/dashboard/components/widgets/ShowMore.vue
new file mode 100644
index 000000000..c4755aed9
--- /dev/null
+++ b/app/javascript/dashboard/components/widgets/ShowMore.vue
@@ -0,0 +1,50 @@
+
+
+ {{ textToBeDisplayed }}
+
+
+
+
+
diff --git a/app/javascript/dashboard/i18n/locale/en/integrations.json b/app/javascript/dashboard/i18n/locale/en/integrations.json
index 4562183c7..2094f269b 100644
--- a/app/javascript/dashboard/i18n/locale/en/integrations.json
+++ b/app/javascript/dashboard/i18n/locale/en/integrations.json
@@ -2,6 +2,29 @@
"INTEGRATION_SETTINGS": {
"HEADER": "Integrations",
"WEBHOOK": {
+ "SUBSCRIBED_EVENTS": "Subscribed Events",
+ "FORM": {
+ "CANCEL": "Cancel",
+ "DESC": "Webhook events provide you the realtime information about what's happening in your Chatwoot account. Please enter a valid URL to configure a callback.",
+ "SUBSCRIPTIONS": {
+ "LABEL": "Events",
+ "EVENTS": {
+ "CONVERSATION_CREATED": "Conversation Created",
+ "CONVERSATION_STATUS_CHANGED": "Conversation Status Changed",
+ "CONVERSATION_UPDATED": "Conversation Updated",
+ "MESSAGE_CREATED": "Message created",
+ "MESSAGE_UPDATED": "Message updated",
+ "WEBWIDGET_TRIGGERED": "Live chat widget opened by the user"
+ }
+ },
+ "END_POINT": {
+ "LABEL": "Webhook URL",
+ "PLACEHOLDER": "Example: https://example/api/webhook",
+ "ERROR": "Please enter a valid URL"
+ },
+ "EDIT_SUBMIT": "Update webhook",
+ "ADD_SUBMIT": "Create webhook"
+ },
"TITLE": "Webhook",
"CONFIGURE": "Configure",
"HEADER": "Webhook settings",
@@ -17,35 +40,16 @@
"EDIT": {
"BUTTON_TEXT": "Edit",
"TITLE": "Edit webhook",
- "CANCEL": "Cancel",
- "DESC": "Webhook events provide you the realtime information about what's happening in your Chatwoot account. Please enter a valid URL to configure a callback.",
- "FORM": {
- "END_POINT": {
- "LABEL": "Webhook URL",
- "PLACEHOLDER": "Example: https://example/api/webhook",
- "ERROR": "Please enter a valid URL"
- },
- "SUBMIT": "Edit webhook"
- },
"API": {
- "SUCCESS_MESSAGE": "Webhook URL updated successfully",
+ "SUCCESS_MESSAGE": "Webhook configuration updated successfully",
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
}
},
"ADD": {
"CANCEL": "Cancel",
"TITLE": "Add new webhook",
- "DESC": "Webhook events provide you the realtime information about what's happening in your Chatwoot account. Please enter a valid URL to configure a callback.",
- "FORM": {
- "END_POINT": {
- "LABEL": "Webhook URL",
- "PLACEHOLDER": "Example: https://example/api/webhook",
- "ERROR": "Please enter a valid URL"
- },
- "SUBMIT": "Create webhook"
- },
"API": {
- "SUCCESS_MESSAGE": "Webhook added successfully",
+ "SUCCESS_MESSAGE": "Webhook configuration added successfully",
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
}
},
@@ -57,16 +61,16 @@
},
"CONFIRM": {
"TITLE": "Confirm Deletion",
- "MESSAGE": "Are you sure to delete ",
+ "MESSAGE": "Are you sure to delete the webhook? (%{webhookURL})",
"YES": "Yes, Delete ",
"NO": "No, Keep it"
}
}
},
"SLACK": {
- "HELP_TEXT" : {
+ "HELP_TEXT" : {
"TITLE": "Using Slack Integration",
- "BODY": "
Chatwoot will now sync all the incoming conversations into the customer-conversations channel inside your slack workplace.
Replying to a conversation thread in customer-conversations slack channel will create a response back to the customer through chatwoot.
Start the replies with note: to create private notes instead of replies.
If the replier on slack has an agent profile in chatwoot under the same email, the replies will be associated accordingly.
When the replier doesn't have an associated agent profile, the replies will be made from the bot profile.
"
+ "BODY": "
Chatwoot will now sync all the incoming conversations into the customer-conversations channel inside your slack workplace.
Replying to a conversation thread in customer-conversations slack channel will create a response back to the customer through chatwoot.
Start the replies with note: to create private notes instead of replies.
If the replier on slack has an agent profile in chatwoot under the same email, the replies will be associated accordingly.
When the replier doesn't have an associated agent profile, the replies will be made from the bot profile.
"
}
},
"DELETE": {
diff --git a/app/javascript/dashboard/i18n/locale/en/settings.json b/app/javascript/dashboard/i18n/locale/en/settings.json
index 5727e09d0..63b070b0e 100644
--- a/app/javascript/dashboard/i18n/locale/en/settings.json
+++ b/app/javascript/dashboard/i18n/locale/en/settings.json
@@ -127,6 +127,10 @@
"BUTTON_TEXT": "Copy",
"COPY_SUCCESSFUL": "Code copied to clipboard successfully"
},
+ "SHOW_MORE_BLOCK": {
+ "SHOW_MORE": "Show More",
+ "SHOW_LESS": "Show Less"
+ },
"FILE_BUBBLE": {
"DOWNLOAD": "Download",
"UPLOADING": "Uploading..."
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/EditWebHook.vue b/app/javascript/dashboard/routes/dashboard/settings/integrations/EditWebHook.vue
deleted file mode 100644
index cdfa2998a..000000000
--- a/app/javascript/dashboard/routes/dashboard/settings/integrations/EditWebHook.vue
+++ /dev/null
@@ -1,108 +0,0 @@
-
-
-
-
-
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/NewWebHook.vue b/app/javascript/dashboard/routes/dashboard/settings/integrations/NewWebHook.vue
deleted file mode 100644
index 35e3df04d..000000000
--- a/app/javascript/dashboard/routes/dashboard/settings/integrations/NewWebHook.vue
+++ /dev/null
@@ -1,121 +0,0 @@
-
-
-
-
-
-
-
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/EditWebHook.vue b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/EditWebHook.vue
new file mode 100644
index 000000000..624a41d05
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/EditWebHook.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhook.vue b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/Index.vue
similarity index 73%
rename from app/javascript/dashboard/routes/dashboard/settings/integrations/Webhook.vue
rename to app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/Index.vue
index e5bb621f0..8bd36c0a8 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhook.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/Index.vue
@@ -4,7 +4,7 @@
color-scheme="success"
class-names="button--fixed-right-top"
icon="add-circle"
- @click="openAddPopup()"
+ @click="openAddPopup"
>
{{ $t('INTEGRATION_SETTINGS.WEBHOOK.HEADER_BTN_TXT') }}
@@ -37,35 +37,14 @@
-
- |
- {{ webHookItem.url }}
- |
-
-
-
-
-
- |
-
+
@@ -83,24 +62,27 @@
-
+
-
@@ -112,11 +94,13 @@ import NewWebhook from './NewWebHook';
import EditWebhook from './EditWebHook';
import alertMixin from 'shared/mixins/alertMixin';
import globalConfigMixin from 'shared/mixins/globalConfigMixin';
+import WebhookRow from './WebhookRow';
export default {
components: {
NewWebhook,
EditWebhook,
+ WebhookRow,
},
mixins: [alertMixin, globalConfigMixin],
data() {
@@ -179,11 +163,3 @@ export default {
},
};
-
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/NewWebHook.vue b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/NewWebHook.vue
new file mode 100644
index 000000000..7c90241c4
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/NewWebHook.vue
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/WebhookForm.vue b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/WebhookForm.vue
new file mode 100644
index 000000000..3d6be7ae0
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/WebhookForm.vue
@@ -0,0 +1,108 @@
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/WebhookRow.vue b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/WebhookRow.vue
new file mode 100644
index 000000000..0e754d93d
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/WebhookRow.vue
@@ -0,0 +1,83 @@
+
+
+ |
+ {{ webhook.url }}
+
+
+ {{ $t('INTEGRATION_SETTINGS.WEBHOOK.SUBSCRIBED_EVENTS') }}:
+
+
+
+ |
+
+
+
+
+
+ |
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/specs/webhookMixin.spec.js b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/specs/webhookMixin.spec.js
new file mode 100644
index 000000000..c617b64b0
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/specs/webhookMixin.spec.js
@@ -0,0 +1,26 @@
+import { createWrapper } from '@vue/test-utils';
+import webhookMixin from '../webhookMixin';
+import Vue from 'vue';
+
+describe('webhookMixin', () => {
+ describe('#getEventLabel', () => {
+ it('returns correct i18n translation:', () => {
+ const Component = {
+ render() {},
+ title: 'WebhookComponent',
+ mixins: [webhookMixin],
+ methods: {
+ $t(text) {
+ return text;
+ },
+ },
+ };
+ const Constructor = Vue.extend(Component);
+ const vm = new Constructor().$mount();
+ const wrapper = createWrapper(vm);
+ expect(wrapper.vm.getEventLabel('message_created')).toEqual(
+ `INTEGRATION_SETTINGS.WEBHOOK.FORM.SUBSCRIPTIONS.EVENTS.MESSAGE_CREATED`
+ );
+ });
+ });
+});
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/webhookMixin.js b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/webhookMixin.js
new file mode 100644
index 000000000..38283fe90
--- /dev/null
+++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/Webhooks/webhookMixin.js
@@ -0,0 +1,10 @@
+export default {
+ methods: {
+ getEventLabel(event) {
+ const eventName = event.toUpperCase();
+ return this.$t(
+ `INTEGRATION_SETTINGS.WEBHOOK.FORM.SUBSCRIPTIONS.EVENTS.${eventName}`
+ );
+ },
+ },
+};
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/integrations.routes.js b/app/javascript/dashboard/routes/dashboard/settings/integrations/integrations.routes.js
index 36596ad0e..4240062e6 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/integrations/integrations.routes.js
+++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/integrations.routes.js
@@ -1,6 +1,6 @@
import Index from './Index';
import SettingsContent from '../Wrapper';
-import Webhook from './Webhook';
+import Webhook from './Webhooks/Index';
import ShowIntegration from './ShowIntegration';
import { frontendURL } from '../../../../helper/URLHelper';
diff --git a/app/javascript/dashboard/store/modules/webhooks.js b/app/javascript/dashboard/store/modules/webhooks.js
index 11c0dec34..eb096468e 100644
--- a/app/javascript/dashboard/store/modules/webhooks.js
+++ b/app/javascript/dashboard/store/modules/webhooks.js
@@ -14,7 +14,7 @@ const state = {
export const getters = {
getWebhooks(_state) {
- return _state.records;
+ return _state.records.sort((w1, w2) => w1.id - w2.id);
},
getUIFlags(_state) {
return _state.uiFlags;
diff --git a/app/listeners/webhook_listener.rb b/app/listeners/webhook_listener.rb
index b0629a469..11a86e639 100644
--- a/app/listeners/webhook_listener.rb
+++ b/app/listeners/webhook_listener.rb
@@ -1,22 +1,4 @@
class WebhookListener < BaseListener
- # FIXME: deprecate the opened and resolved events in future in favor of status changed event.
- def conversation_resolved(event)
- conversation = extract_conversation_and_account(event)[0]
- changed_attributes = extract_changed_attributes(event)
- inbox = conversation.inbox
- payload = conversation.webhook_data.merge(event: __method__.to_s, changed_attributes: changed_attributes)
- deliver_webhook_payloads(payload, inbox)
- end
-
- # FIXME: deprecate the opened and resolved events in future in favor of status changed event.
- def conversation_opened(event)
- conversation = extract_conversation_and_account(event)[0]
- changed_attributes = extract_changed_attributes(event)
- inbox = conversation.inbox
- payload = conversation.webhook_data.merge(event: __method__.to_s, changed_attributes: changed_attributes)
- deliver_webhook_payloads(payload, inbox)
- end
-
def conversation_status_changed(event)
conversation = extract_conversation_and_account(event)[0]
changed_attributes = extract_changed_attributes(event)
@@ -71,15 +53,23 @@ class WebhookListener < BaseListener
private
- def deliver_webhook_payloads(payload, inbox)
- # Account webhooks
+ def deliver_account_webhooks(payload, inbox)
inbox.account.webhooks.account.each do |webhook|
+ next unless webhook.subscriptions.include?(payload[:event])
+
WebhookJob.perform_later(webhook.url, payload)
end
+ end
+ def deliver_api_inbox_webhooks(payload, inbox)
return unless inbox.channel_type == 'Channel::Api'
return if inbox.channel.webhook_url.blank?
WebhookJob.perform_later(inbox.channel.webhook_url, payload)
end
+
+ def deliver_webhook_payloads(payload, inbox)
+ deliver_account_webhooks(payload, inbox)
+ deliver_api_inbox_webhooks(payload, inbox)
+ end
end
diff --git a/app/models/webhook.rb b/app/models/webhook.rb
index a78e7c267..fe97fe583 100644
--- a/app/models/webhook.rb
+++ b/app/models/webhook.rb
@@ -2,13 +2,14 @@
#
# Table name: webhooks
#
-# id :bigint not null, primary key
-# url :string
-# webhook_type :integer default("account")
-# created_at :datetime not null
-# updated_at :datetime not null
-# account_id :integer
-# inbox_id :integer
+# id :bigint not null, primary key
+# subscriptions :jsonb
+# url :string
+# webhook_type :integer default("account")
+# created_at :datetime not null
+# updated_at :datetime not null
+# account_id :integer
+# inbox_id :integer
#
# Indexes
#
@@ -21,6 +22,18 @@ class Webhook < ApplicationRecord
validates :account_id, presence: true
validates :url, uniqueness: { scope: [:account_id] }, format: URI::DEFAULT_PARSER.make_regexp(%w[http https])
-
+ validate :validate_webhook_subscriptions
enum webhook_type: { account: 0, inbox: 1 }
+
+ ALLOWED_WEBHOOK_EVENTS = %w[conversation_status_changed conversation_updated conversation_created message_created message_updated
+ webwidget_triggered].freeze
+
+ private
+
+ def validate_webhook_subscriptions
+ invalid_subscriptions = !subscriptions.instance_of?(Array) ||
+ subscriptions.blank? ||
+ (subscriptions.uniq - ALLOWED_WEBHOOK_EVENTS).length.positive?
+ errors.add(:subscriptions, I18n.t('errors.webhook.invalid')) if invalid_subscriptions
+ end
end
diff --git a/app/views/api/v1/accounts/webhooks/_webhook.json.jbuilder b/app/views/api/v1/accounts/webhooks/_webhook.json.jbuilder
index b02de2098..fac8fdcf2 100644
--- a/app/views/api/v1/accounts/webhooks/_webhook.json.jbuilder
+++ b/app/views/api/v1/accounts/webhooks/_webhook.json.jbuilder
@@ -1,6 +1,7 @@
json.id webhook.id
json.url webhook.url
json.account_id webhook.account_id
+json.subscriptions webhook.subscriptions
if webhook.inbox
json.inbox do
json.id webhook.inbox.id
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 6a928e75a..0c92c32eb 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -36,6 +36,8 @@ en:
reset_password_failure: Uh ho! We could not find any user with the specified email.
errors:
+ webhook:
+ invalid: Invalid events
signup:
disposable_email: We do not allow disposable emails
invalid_email: You have entered an invalid email
diff --git a/db/migrate/20220424081117_add_subscriptions_to_webhooks.rb b/db/migrate/20220424081117_add_subscriptions_to_webhooks.rb
new file mode 100644
index 000000000..b4e8d4dfc
--- /dev/null
+++ b/db/migrate/20220424081117_add_subscriptions_to_webhooks.rb
@@ -0,0 +1,12 @@
+class AddSubscriptionsToWebhooks < ActiveRecord::Migration[6.1]
+ def change
+ add_column :webhooks, :subscriptions, :jsonb, default: %w[
+ conversation_status_changed
+ conversation_updated
+ conversation_created
+ message_created
+ message_updated
+ webwidget_triggered
+ ]
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 2d03ce428..a30f6e6cf 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2022_04_18_094715) do
+ActiveRecord::Schema.define(version: 2022_04_24_081117) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
@@ -763,6 +763,7 @@ ActiveRecord::Schema.define(version: 2022_04_18_094715) do
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "webhook_type", default: 0
+ t.jsonb "subscriptions", default: ["conversation_status_changed", "conversation_updated", "conversation_created", "message_created", "message_updated", "webwidget_triggered"]
t.index ["account_id", "url"], name: "index_webhooks_on_account_id_and_url", unique: true
end
diff --git a/spec/controllers/api/v1/accounts/webhook_controller_spec.rb b/spec/controllers/api/v1/accounts/webhook_controller_spec.rb
index ccafe2f56..aeea4d45f 100644
--- a/spec/controllers/api/v1/accounts/webhook_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts/webhook_controller_spec.rb
@@ -57,6 +57,36 @@ RSpec.describe 'Webhooks API', type: :request do
expect(response).to have_http_status(:unprocessable_entity)
expect(JSON.parse(response.body)['message']).to eql 'Url is invalid'
end
+
+ it 'throws error if subscription events are invalid' do
+ post "/api/v1/accounts/#{account.id}/webhooks",
+ params: { url: 'https://hello.com', subscriptions: ['conversation_random_event'] },
+ headers: administrator.create_new_auth_token,
+ as: :json
+ expect(response).to have_http_status(:unprocessable_entity)
+ expect(JSON.parse(response.body)['message']).to eql 'Subscriptions Invalid events'
+ end
+
+ it 'throws error if subscription events are empty' do
+ post "/api/v1/accounts/#{account.id}/webhooks",
+ params: { url: 'https://hello.com', subscriptions: [] },
+ headers: administrator.create_new_auth_token,
+ as: :json
+ expect(response).to have_http_status(:unprocessable_entity)
+ expect(JSON.parse(response.body)['message']).to eql 'Subscriptions Invalid events'
+ end
+
+ it 'use default if subscription events are nil' do
+ post "/api/v1/accounts/#{account.id}/webhooks",
+ params: { url: 'https://hello.com', subscriptions: nil },
+ headers: administrator.create_new_auth_token,
+ as: :json
+ expect(response).to have_http_status(:ok)
+ expect(
+ JSON.parse(response.body)['payload']['webhook']['subscriptions']
+ ).to eql %w[conversation_status_changed conversation_updated conversation_created message_created message_updated
+ webwidget_triggered]
+ end
end
end
diff --git a/spec/factories/webhooks.rb b/spec/factories/webhooks.rb
index e80ed1aeb..b49434fce 100644
--- a/spec/factories/webhooks.rb
+++ b/spec/factories/webhooks.rb
@@ -3,5 +3,15 @@ FactoryBot.define do
account_id { 1 }
inbox_id { 1 }
url { 'https://api.chatwoot.com' }
+ subscriptions do
+ %w[
+ conversation_status_changed
+ conversation_updated
+ conversation_created
+ message_created
+ message_updated
+ webwidget_triggered
+ ]
+ end
end
end
diff --git a/spec/listeners/webhook_listener_spec.rb b/spec/listeners/webhook_listener_spec.rb
index bcc990c5b..5dac1a8ec 100644
--- a/spec/listeners/webhook_listener_spec.rb
+++ b/spec/listeners/webhook_listener_spec.rb
@@ -23,14 +23,22 @@ describe WebhookListener do
end
end
- context 'when webhook is configured' do
- it 'triggers webhook' do
+ context 'when webhook is configured and event is subscribed' do
+ it 'triggers the webhook event' do
webhook = create(:webhook, inbox: inbox, account: account)
expect(WebhookJob).to receive(:perform_later).with(webhook.url, message.webhook_data.merge(event: 'message_created')).once
listener.message_created(message_created_event)
end
end
+ context 'when webhook is configured and 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_created(message_created_event)
+ end
+ end
+
context 'when inbox is an API Channel' do
it 'triggers webhook if webhook_url is present' do
channel_api = create(:channel_api, account: account)
@@ -106,36 +114,6 @@ describe WebhookListener do
end
end
- describe '#conversation_resolved' do
- let!(:conversation_resolved_event) do
- Events::Base.new(event_name, Time.zone.now, conversation: conversation.reload, changed_attributes: { status: [:open, :resolved] })
- end
- let(:event_name) { :'conversation.resolved' }
-
- context 'when webhook is not configured' do
- it 'does not trigger webhook' do
- expect(WebhookJob).to receive(:perform_later).exactly(0).times
- listener.conversation_resolved(conversation_resolved_event)
- end
- end
-
- context 'when webhook is configured' do
- it 'triggers webhook' do
- webhook = create(:webhook, inbox: inbox, account: account)
-
- conversation.update(status: :resolved)
-
- expect(WebhookJob).to receive(:perform_later).with(webhook.url,
- conversation.webhook_data.merge(event: 'conversation_resolved',
- changed_attributes: [{ status: {
- current_value: :resolved, previous_value: :open
- } }])).once
-
- listener.conversation_resolved(conversation_resolved_event)
- end
- end
- end
-
describe '#conversation_updated' do
let(:custom_attributes) { { test: nil } }
let!(:conversation_updated_event) do