From a6b119d1876b09a54675c04371c9d0a7323fccad Mon Sep 17 00:00:00 2001 From: Tejaswini Chile Date: Wed, 13 Apr 2022 01:29:51 +0530 Subject: [PATCH] Feat: twitter image support (#4429) --- .../twitter/direct_message_parser_service.rb | 52 ++++++++++++- .../twitter/webhook_subscribe_service.rb | 2 +- .../twitter/twitter_dm_image_event.rb | 75 +++++++++++++++++++ spec/lib/webhooks/twitter_spec.rb | 16 ++++ 4 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 spec/factories/twitter/twitter_dm_image_event.rb diff --git a/app/services/twitter/direct_message_parser_service.rb b/app/services/twitter/direct_message_parser_service.rb index 04e68e590..e3679f278 100644 --- a/app/services/twitter/direct_message_parser_service.rb +++ b/app/services/twitter/direct_message_parser_service.rb @@ -7,7 +7,7 @@ class Twitter::DirectMessageParserService < Twitter::WebhooksBaseService set_inbox ensure_contacts set_conversation - @conversation.messages.create( + @message = @conversation.messages.create( content: message_create_data['message_data']['text'], account_id: @inbox.account_id, inbox_id: @inbox.id, @@ -15,10 +15,24 @@ class Twitter::DirectMessageParserService < Twitter::WebhooksBaseService sender: @contact, source_id: direct_message_data['id'] ) + attach_files end private + def attach_files + return if message_create_data['message_data']['attachment'].blank? + + save_media + @message + end + + def save_media_urls(file) + @message.content_attributes[:media_url] = file['media_url'] + @message.content_attributes[:display_url] = file['display_url'] + @message.save + end + def direct_message_events_params payload['direct_message_events'] end @@ -39,6 +53,10 @@ class Twitter::DirectMessageParserService < Twitter::WebhooksBaseService ENV.fetch('TWITTER_APP_ID', '') end + def media + message_create_data['message_data']['attachment']['media'] + end + def users payload[:users] end @@ -73,4 +91,36 @@ class Twitter::DirectMessageParserService < Twitter::WebhooksBaseService def outgoing_message? message_create_data['sender_id'] == @inbox.channel.profile_id end + + def api_client + @api_client ||= begin + consumer = OAuth::Consumer.new(ENV.fetch('TWITTER_CONSUMER_KEY', nil), ENV.fetch('TWITTER_CONSUMER_SECRET', nil), + { site: 'https://api.twitter.com' }) + token = { oauth_token: @inbox.channel.twitter_access_token, oauth_token_secret: @inbox.channel.twitter_access_token_secret } + OAuth::AccessToken.from_hash(consumer, token) + end + end + + def save_media + save_media_urls(media) + response = api_client.get(media['media_url'], []) + + temp_file = Tempfile.new('twitter_attachment') + temp_file.binmode + temp_file << response.body + temp_file.rewind + + return unless media['type'] == 'photo' + + @message.attachments.new( + account_id: @inbox.account_id, + file_type: 'image', + file: { + io: temp_file, + filename: 'twitter_attachment', + content_type: media['type'] + } + ) + @message.save + end end diff --git a/app/services/twitter/webhook_subscribe_service.rb b/app/services/twitter/webhook_subscribe_service.rb index 7d7734231..f052bf551 100644 --- a/app/services/twitter/webhook_subscribe_service.rb +++ b/app/services/twitter/webhook_subscribe_service.rb @@ -43,7 +43,7 @@ class Twitter::WebhookSubscribeService def register_webhook register_response = twitter_client.register_webhook(url: twitter_url) - Rails.logger.info "TWITTER_UNREGISTER_WEBHOOK: #{register_response.body}" + Rails.logger.info "TWITTER_REGISTER_WEBHOOK: #{register_response.body}" end def subscription? diff --git a/spec/factories/twitter/twitter_dm_image_event.rb b/spec/factories/twitter/twitter_dm_image_event.rb new file mode 100644 index 000000000..dded4fc2d --- /dev/null +++ b/spec/factories/twitter/twitter_dm_image_event.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :twitter_dm_image_event, class: Hash do + for_user_id { '1' } + direct_message_events do + [{ + 'type' => 'message_create', + 'id' => '123', + 'message_create' => { + 'target' => { 'recipient_id' => '1' }, + 'sender_id' => '2', + 'source_app_id' => '268278', + 'message_data' => { + 'text' => 'Blue Bird', + 'attachment' => { + 'media' => { + 'display_url' => 'pic.twitter.com/5J1WJSRCy9', + 'expanded_url' => 'https://twitter.com/nolan_test/status/930077847535812610/photo/1', + 'id' => 9.300778475358126e17, + 'id_str' => '930077847535812610', + 'indices' => [ + 13, + 36 + ], + 'media_url' => 'http://pbs.twimg.com/media/DOhM30VVwAEpIHq.jpg', + 'media_url_https' => 'https://pbs.twimg.com/media/DOhM30VVwAEpIHq.jpg', + 'sizes' => { + 'thumb' => { + 'h' => 150, + 'resize' => 'crop', + 'w' => 150 + }, + 'large' => { + 'h' => 1366, + 'resize' => 'fit', + 'w' => 2048 + }, + 'medium' => { + 'h' => 800, + 'resize' => 'fit', + 'w' => 1200 + }, + 'small' => { + 'h' => 454, + 'resize' => 'fit', + 'w' => 680 + } + }, + 'type' => 'photo', + 'url' => 'https://t.co/5J1WJSRCy9' + } + }.with_indifferent_access + } + } + }.with_indifferent_access] + end + users do + { + '1' => { + id: '1', + name: 'person 1', + profile_image_url: 'https://chatwoot-assets.local/sample.png' + }, + '2' => { + id: '1', + name: 'person 1', + profile_image_url: 'https://chatwoot-assets.local/sample.png' + } + } + end + + initialize_with { attributes } + end +end diff --git a/spec/lib/webhooks/twitter_spec.rb b/spec/lib/webhooks/twitter_spec.rb index 74820c609..598ef4295 100644 --- a/spec/lib/webhooks/twitter_spec.rb +++ b/spec/lib/webhooks/twitter_spec.rb @@ -9,6 +9,7 @@ describe Webhooks::Twitter do let!(:twitter_channel) { create(:channel_twitter_profile, account: account, profile_id: '1', tweets_enabled: true) } let!(:twitter_inbox) { create(:inbox, channel: twitter_channel, account: account, greeting_enabled: false) } let!(:dm_params) { build(:twitter_message_create_event).with_indifferent_access } + let!(:dm_image_params) { build(:twitter_dm_image_event).with_indifferent_access } let!(:tweet_params) { build(:tweet_create_event).with_indifferent_access } let!(:tweet_params_from_blocked_user) { build(:tweet_create_event, user_has_blocked: true).with_indifferent_access } @@ -22,6 +23,21 @@ describe Webhooks::Twitter do end end + context 'with direct_message attachment params' do + before do + stub_request(:get, 'http://pbs.twimg.com/media/DOhM30VVwAEpIHq.jpg') + .to_return(status: 200, body: '', headers: {}) + end + + it 'creates incoming message with attachments in the twitter inbox' do + twitter_webhook.new(dm_image_params).consume + expect(twitter_inbox.contacts.count).to be 1 + expect(twitter_inbox.conversations.count).to be 1 + expect(twitter_inbox.messages.count).to be 1 + expect(twitter_inbox.messages.last.attachments.count).to be 1 + end + end + context 'with tweet_params params' do it 'does not create incoming message in the twitter inbox if it is a blocked user' do twitter_webhook.new(tweet_params_from_blocked_user).consume