Class: Nuntius::Message

Inherits:
ApplicationRecord show all
Includes:
Concerns::MetadataScoped
Defined in:
app/models/nuntius/message.rb

Overview

Stores individual messages to individual recipients

Nuntius will have messages in states:

pending - nothing done yet
sent - we've sent it on to the provider
delivered - have delivery confirmation
undelivered - have confirmation of non-delivery

Not all transports may provide all states

Instance Method Summary collapse

Instance Method Details

#add_attachment(options) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'app/models/nuntius/message.rb', line 63

def add_attachment(options)
  attachment = {}

  uri = options[:url] && URI.parse(options[:url])

  if uri&.scheme == 'file'
    attachment[:io] = File.open(uri.path)
  elsif uri
    client = HTTPClient.new
    client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
    client.ssl_config.set_default_paths unless Gem.win_platform?
    response = client.get(options[:url], follow_redirect: true)
    content_disposition = response.headers['Content-Disposition'] || ''
    options[:filename] ||= content_disposition[/filename="([^"]+)"/, 1]
    attachment[:content_type] = response.content_type
    attachment[:io] = if response.body.is_a? String
                        StringIO.new(response.body)
                      else
                        # Assume IO object
                        response.body
                      end
  elsif options[:content].respond_to?(:read)
    attachment[:content_type] = options[:content_type]
    attachment[:io] = options[:content]
  else
    raise 'Cannot add attachment without url or content'
  end

  # Set the filename
  attachment[:filename] = options[:filename] || uri.path.split('/').last || 'attachment'

  # (Try to) add file extension if it is missing
  file_extension = File.extname(attachment[:filename]).delete('.')
  attachment[:filename] += ".#{Mime::Type.lookup(attachment[:content_type].split(';').first).to_sym}" if file_extension.blank? && attachment[:content_type]

  # Fix content type if file extension known but content type blank
  attachment[:content_type] ||= Mime::Type.lookup_by_extension(file_extension)&.to_s if file_extension

  if options[:auto_zip] && attachment[:io].size > 1024 * 1024
    zip_stream = Zip::OutputStream.write_buffer do |zio|
      zio.put_next_entry attachment[:file_name]
      zio.write attachment[:io].read
    end
    attachment[:content_type] = 'application/zip'
    attachment[:io] = zip_stream
  end

  nuntius_attachment = Nuntius::Attachment.new
  nuntius_attachment.content.attach(io: attachment[:io],
                                    filename: attachment[:filename],
                                    content_type: attachment[:content_type])

  attachments.push(nuntius_attachment)
rescue StandardError => e
  Nuntius.config.logger.error "Message: Could not attach #{attachment[:filename]} #{e.message}"
end

#blocked?Boolean

Returns:

  • (Boolean)


42
43
44
# File 'app/models/nuntius/message.rb', line 42

def blocked?
  status == 'blocked'
end

#cleanup!Object

Removes only pending child messages



59
60
61
# File 'app/models/nuntius/message.rb', line 59

def cleanup!
  Nuntius::Message.where(status: 'pending').where(parent_message: self).destroy_all
end

#cleanup_attachmentsObject



120
121
122
123
124
# File 'app/models/nuntius/message.rb', line 120

def cleanup_attachments
  attachments.each do |attachment|
    attachment.destroy if attachment.messages.where.not(id: id).blank?
  end
end

#deliver_as(transport) ⇒ Object

Convenience method to easily send messages without having a template



142
143
144
145
146
# File 'app/models/nuntius/message.rb', line 142

def deliver_as(transport)
  klass = BaseTransport.class_from_name(transport).new
  klass.deliver(self)
  self
end

#delivered?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'app/models/nuntius/message.rb', line 46

def delivered?
  status == 'delivered'
end

#delivered_or_blocked?Boolean

Returns:

  • (Boolean)


50
51
52
# File 'app/models/nuntius/message.rb', line 50

def delivered_or_blocked?
  delivered? || blocked?
end

#nuntius_provider(message) ⇒ Object



126
127
128
129
130
# File 'app/models/nuntius/message.rb', line 126

def nuntius_provider(message)
  klass = Nuntius::BaseProvider.class_from_name(provider, transport)
  klass ||= Nuntius::BaseProvider
  klass.new(message)
end

#pending?Boolean

Weird loading sequence error, is fixed by the lib/nuntius/helpers begin

has_many_attached :attachments

rescue NoMethodError end

Returns:

  • (Boolean)


34
35
36
# File 'app/models/nuntius/message.rb', line 34

def pending?
  status == 'pending'
end

#resendObject



132
133
134
135
136
137
# File 'app/models/nuntius/message.rb', line 132

def resend
  return if pending?
  return unless transport

  deliver_as(transport)
end

#sent?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'app/models/nuntius/message.rb', line 38

def sent?
  status == 'sent'
end

#undelivered?Boolean

Returns:

  • (Boolean)


54
55
56
# File 'app/models/nuntius/message.rb', line 54

def undelivered?
  status == 'undelivered'
end