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



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
119
120
121
122
123
# File 'app/models/nuntius/message.rb', line 64

def add_attachment(options)
  attachment = {}

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

  if uri&.scheme == "file"
    # FIXME: This is a possible security problem
    attachment[:io] = File.open(uri.path)
  elsif uri
    client = Faraday.new(ssl: {verify: false}) do |builder|
      builder.response :follow_redirects
      builder.adapter Faraday.default_adapter
    end

    response = client.get(options[:url])
    content_disposition = response.headers["Content-Disposition"] || ""

    options[:filename] ||= content_disposition[/filename="([^"]+)"/, 1]
    attachment[:content_type] = response.headers["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 => e
  Nuntius.config.logger.error "Message: Could not attach #{attachment[:filename]} #{e.message}"
end

#blocked?Boolean

Returns:

  • (Boolean)


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

def blocked?
  status == "blocked"
end

#cleanup!Object

Removes only pending child messages



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

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

#cleanup_attachmentsObject



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

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



147
148
149
150
151
# File 'app/models/nuntius/message.rb', line 147

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

#delivered?Boolean

Returns:

  • (Boolean)


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

def delivered?
  status == "delivered"
end

#delivered_or_blocked?Boolean

Returns:

  • (Boolean)


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

def delivered_or_blocked?
  delivered? || blocked?
end

#nuntius_provider(message) ⇒ Object



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

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)


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

def pending?
  status == "pending"
end

#resendObject



137
138
139
140
141
142
# File 'app/models/nuntius/message.rb', line 137

def resend
  return if pending?
  return unless transport

  deliver_as(transport)
end

#sent?Boolean

Returns:

  • (Boolean)


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

def sent?
  status == "sent"
end

#undelivered?Boolean

Returns:

  • (Boolean)


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

def undelivered?
  status == "undelivered"
end