From 7b1fdc5fcdbb387c666aafe1ac07b747659cbb4d Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Wed, 5 Feb 2020 18:50:38 +0530 Subject: [PATCH] BugFix: Filter duplicate DMs in Twitter Integration (#468) BugFix: Filter duplicate DMs in Twitter Integration --- .env.example | 6 +- .../twitter/direct_message_parser_service.rb | 74 +++++++++++++++++++ app/services/twitter/webhooks_base_service.rb | 27 +++++++ lib/webhooks/twitter.rb | 62 +--------------- 4 files changed, 106 insertions(+), 63 deletions(-) create mode 100644 app/services/twitter/direct_message_parser_service.rb create mode 100644 app/services/twitter/webhooks_base_service.rb diff --git a/.env.example b/.env.example index 1b9cbb3e6..e6075e55e 100644 --- a/.env.example +++ b/.env.example @@ -20,14 +20,16 @@ FB_APP_SECRET= FB_APP_ID= #twitter app +TWITTER_APP_ID= TWITTER_CONSUMER_KEY= TWITTER_CONSUMER_SECRET= +TWITTER_ENVIRONMENT= #mail MAILER_SENDER_EMAIL=accounts@chatwoot.com SMTP_PORT=1025 SMTP_DOMAIN=chatwoot.com -# if you are running docker-compose, set SMTP_ADDRESS value as "mailhog", +# if you are running docker-compose, set SMTP_ADDRESS value as "mailhog", # else set the value as "localhost" SMTP_ADDRESS=mailhog SMTP_USERNAME= @@ -59,4 +61,4 @@ ENABLE_BILLING= CHARGEBEE_API_KEY= CHARGEBEE_SITE= CHARGEBEE_WEBHOOK_USERNAME= -CHARGEBEE_WEBHOOK_PASSWORD= \ No newline at end of file +CHARGEBEE_WEBHOOK_PASSWORD= diff --git a/app/services/twitter/direct_message_parser_service.rb b/app/services/twitter/direct_message_parser_service.rb new file mode 100644 index 000000000..d319dcf57 --- /dev/null +++ b/app/services/twitter/direct_message_parser_service.rb @@ -0,0 +1,74 @@ +class Twitter::DirectMessageParserService < Twitter::WebhooksBaseService + pattr_initialize [:payload] + + def perform + return if source_app_id == parent_app_id + + set_inbox + ensure_contacts + set_conversation + @conversation.messages.create( + content: message_create_data['message_data']['text'], + account_id: @inbox.account_id, + inbox_id: @inbox.id, + message_type: outgoing_message? ? :outgoing : :incoming + ) + end + + private + + def direct_message_events_params + payload['direct_message_events'] + end + + def direct_message_data + direct_message_events_params.first + end + + def message_create_data + direct_message_data['message_create'] + end + + def source_app_id + message_create_data['source_app_id'] + end + + def parent_app_id + ENV.fetch('TWITTER_APP_ID', '') + end + + def users + payload[:users] + end + + def ensure_contacts + users.each do |key, user| + next if key == profile_id + + find_or_create_contact(user) + end + end + + def conversation_params + { + account_id: @inbox.account_id, + inbox_id: @inbox.id, + contact_id: @contact.id, + contact_inbox_id: @contact_inbox.id, + additional_attributes: { + type: 'direct_message' + } + } + end + + def set_conversation + @conversation = @contact_inbox.conversations.first + return if @conversation + + @conversation = ::Conversation.create!(conversation_params) + end + + def outgoing_message? + message_create_data['sender_id'] == @inbox.channel.profile_id + end +end diff --git a/app/services/twitter/webhooks_base_service.rb b/app/services/twitter/webhooks_base_service.rb new file mode 100644 index 000000000..ffaba327c --- /dev/null +++ b/app/services/twitter/webhooks_base_service.rb @@ -0,0 +1,27 @@ +class Twitter::WebhooksBaseService + private + + def profile_id + payload[:for_user_id] + end + + def set_inbox + twitter_profile = ::Channel::TwitterProfile.find_by(profile_id: profile_id) + @inbox = ::Inbox.find_by!(channel: twitter_profile) + end + + def find_or_create_contact(user) + @contact_inbox = @inbox.contact_inboxes.where(source_id: user['id']).first + @contact = @contact_inbox.contact if @contact_inbox + return if @contact + + @contact_inbox = @inbox.channel.create_contact_inbox(user['id'], user['name']) + @contact = @contact_inbox.contact + avatar_resource = LocalResource.new(user['profile_image_url']) + @contact.avatar.attach( + io: avatar_resource.file, + filename: avatar_resource.tmp_filename, + content_type: avatar_resource.encoding + ) + end +end diff --git a/lib/webhooks/twitter.rb b/lib/webhooks/twitter.rb index 5e55cb82d..f7480732e 100644 --- a/lib/webhooks/twitter.rb +++ b/lib/webhooks/twitter.rb @@ -19,67 +19,7 @@ class Webhooks::Twitter @event_name ||= SUPPORTED_EVENTS.find { |key| @params.key?(key.to_s) } end - def users - @params[:users] - end - - def profile_id - @params[:for_user_id] - end - - def set_inbox - twitter_profile = Channel::TwitterProfile.find_by(profile_id: @params[:for_user_id]) - @inbox = Inbox.find_by!(channel: twitter_profile) - end - - def ensure_contacts - @params[:users].each do |key, user| - next if key == profile_id - - find_or_create_contact(user) - end - end - - def find_or_create_contact(user) - @contact_inbox = @inbox.contact_inboxes.where(source_id: user['id']).first - @contact = @contact_inbox.contact if @contact_inbox - return if @contact - - @contact_inbox = @inbox.channel.create_contact_inbox(user['id'], user['name']) - @contact = @contact_inbox.contact - avatar_resource = LocalResource.new(user['profile_image_url']) - @contact.avatar.attach(io: avatar_resource.file, filename: avatar_resource.tmp_filename, content_type: avatar_resource.encoding) - end - - def conversation_params - { - account_id: @inbox.account_id, - inbox_id: @inbox.id, - contact_id: @contact.id, - contact_inbox_id: @contact_inbox.id - } - end - - def set_conversation - @conversation = @contact_inbox.conversations.first - return if @conversation - - @conversation = ::Conversation.create!(conversation_params) - end - - def outgoing_message? - @params['direct_message_events'].first['message_create']['sender_id'] == @inbox.channel.profile_id - end - def direct_message_events - set_inbox - ensure_contacts - set_conversation - @conversation.messages.create( - content: @params['direct_message_events'].first['message_create']['message_data']['text'], - account_id: @inbox.account_id, - inbox_id: @inbox.id, - message_type: outgoing_message? ? :outgoing : :incoming - ) + ::Twitter::DirectMessageParserService.new(payload: @params).perform end end