123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- class Channel::Driver::Sms::Twilio
- NAME = 'sms/twilio'.freeze
- def fetchable?(_channel)
- false
- end
- def send(options, attr, _notification = false)
- Rails.logger.info "Sending SMS to recipient #{attr[:recipient]}"
- return true if Setting.get('import_mode')
- Rails.logger.info "Backend sending Twilio SMS to #{attr[:recipient]}"
- begin
- if Setting.get('developer_mode') != true
- result = api(options).messages.create(
- from: options[:sender],
- to: attr[:recipient],
- body: attr[:message],
- )
- raise result.error_message if result.error_code.positive?
- end
- true
- rescue => e
- Rails.logger.debug "Twilio error: #{e.inspect}"
- raise e
- end
- end
- def process(_options, attr, channel)
- Rails.logger.info "Receiving SMS frim recipient #{attr[:From]}"
- # prevent already created articles
- if Ticket::Article.exists?(message_id: attr[:SmsMessageSid])
- return ['application/xml; charset=UTF-8;', Twilio::TwiML::MessagingResponse.new.to_s]
- end
- # find sender
- user = User.where(mobile: attr[:From]).order(:updated_at).first
- if !user
- _from_comment, preferences = Cti::CallerId.get_comment_preferences(attr[:From], 'from')
- if preferences && preferences['from'] && preferences['from'][0]
- if preferences['from'][0]['level'] == 'known' && preferences['from'][0]['object'] == 'User'
- user = User.find_by(id: preferences['from'][0]['o_id'])
- end
- end
- end
- if !user
- user = User.create!(
- firstname: attr[:From],
- mobile: attr[:From],
- )
- end
- UserInfo.current_user_id = user.id
- # find ticket
- article_type_sms = Ticket::Article::Type.find_by(name: 'sms')
- state_ids = Ticket::State.where(name: %w[closed merged removed]).pluck(:id)
- ticket = Ticket.where(customer_id: user.id, create_article_type_id: article_type_sms.id).where.not(state_id: state_ids).order(:updated_at).first
- if ticket
- new_state = Ticket::State.find_by(default_create: true)
- if ticket.state_id != new_state.id
- ticket.state = Ticket::State.find_by(default_follow_up: true)
- ticket.save!
- end
- else
- if channel.group_id.blank?
- raise Exceptions::UnprocessableEntity, 'Group needed in channel definition!'
- end
- group = Group.find_by(id: channel.group_id)
- if !group
- raise Exceptions::UnprocessableEntity, 'Group is invalid!'
- end
- title = attr[:Body]
- if title.length > 40
- title = "#{title[0, 40]}..."
- end
- ticket = Ticket.new(
- group_id: channel.group_id,
- title: title,
- state_id: Ticket::State.find_by(default_create: true).id,
- priority_id: Ticket::Priority.find_by(default_create: true).id,
- customer_id: user.id,
- preferences: {
- channel_id: channel.id,
- sms: {
- AccountSid: attr['AccountSid'],
- From: attr['From'],
- To: attr['To'],
- }
- }
- )
- ticket.save!
- end
- Ticket::Article.create!(
- ticket_id: ticket.id,
- type: article_type_sms,
- sender: Ticket::Article::Sender.find_by(name: 'Customer'),
- body: attr[:Body],
- from: attr[:From],
- to: attr[:To],
- message_id: attr[:SmsMessageSid],
- content_type: 'text/plain',
- preferences: {
- channel_id: channel.id,
- sms: {
- AccountSid: attr['AccountSid'],
- From: attr['From'],
- To: attr['To'],
- }
- }
- )
- ['application/xml; charset=UTF-8;', Twilio::TwiML::MessagingResponse.new.to_s]
- end
- def self.definition
- {
- name: 'twilio',
- adapter: 'sms/twilio',
- account: [
- { name: 'options::webhook_token', display: 'Webhook Token', tag: 'input', type: 'text', limit: 200, null: false, default: Digest::MD5.hexdigest(rand(999_999_999_999).to_s), disabled: true, readonly: true },
- { name: 'options::account_id', display: 'Account SID', tag: 'input', type: 'text', limit: 200, null: false, placeholder: 'XXXXXX' },
- { name: 'options::token', display: 'Token', tag: 'input', type: 'text', limit: 200, null: false },
- { name: 'options::sender', display: 'Sender', tag: 'input', type: 'text', limit: 200, null: false, placeholder: '+491710000000' },
- { name: 'group_id', display: 'Destination Group', tag: 'select', null: false, relation: 'Group', nulloption: true, filter: { active: true } },
- ],
- notification: [
- { name: 'options::account_id', display: 'Account SID', tag: 'input', type: 'text', limit: 200, null: false, placeholder: 'XXXXXX' },
- { name: 'options::token', display: 'Token', tag: 'input', type: 'text', limit: 200, null: false },
- { name: 'options::sender', display: 'Sender', tag: 'input', type: 'text', limit: 200, null: false, placeholder: '+491710000000' },
- ],
- }
- end
- private
- def api(options)
- @api ||= ::Twilio::REST::Client.new options[:account_id], options[:token]
- end
- end
|