59b31615ed
* Use "create!" when not checking for errors on the result * Use "save!" when not checking the result
126 lines
3 KiB
Ruby
126 lines
3 KiB
Ruby
class Twitter::DirectMessageParserService < Twitter::WebhooksBaseService
|
|
pattr_initialize [:payload]
|
|
|
|
def perform
|
|
return if source_app_id == parent_app_id
|
|
|
|
set_inbox
|
|
ensure_contacts
|
|
set_conversation
|
|
@message = @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,
|
|
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
|
|
|
|
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 media
|
|
message_create_data['message_data']['attachment']['media']
|
|
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.where("additional_attributes ->> 'type' = 'direct_message'").first
|
|
return if @conversation
|
|
|
|
@conversation = ::Conversation.create!(conversation_params)
|
|
end
|
|
|
|
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
|