157 lines
4.4 KiB
Ruby
157 lines
4.4 KiB
Ruby
require 'postman/error'
|
||
require 'postman/header_set'
|
||
require 'postman/attachment'
|
||
|
||
module Postman
|
||
class Message
|
||
|
||
#
|
||
# Find a specific messsage with the given scope
|
||
#
|
||
def self.find_with_scope(scope, id)
|
||
api = scope.client.moonrope.messages.message(:id => id.to_i, :_expansions => scope.expansions)
|
||
if api.success?
|
||
Message.new(scope.client, api.data)
|
||
elsif api.status == 'error' && api.data['code'] == 'MessageNotFound'
|
||
raise MessageNotFound.new(id)
|
||
else
|
||
raise Error, "Couldn't load message from API (#{api.data})"
|
||
end
|
||
end
|
||
|
||
#
|
||
# If methods are called directly on the Message class, we likely want to see if we can
|
||
# run them through the global client message scope.
|
||
#
|
||
def self.method_missing(name, *args, &block)
|
||
if MessageScope.instance_methods(false).include?(name)
|
||
Postman::Client.instance.messages.send(name, *args, &block)
|
||
else
|
||
super
|
||
end
|
||
end
|
||
|
||
#
|
||
# Initialize a new message object with the client and a set of initial attributes.
|
||
#
|
||
def initialize(client, attributes)
|
||
@client = client
|
||
@attributes = attributes
|
||
end
|
||
|
||
#
|
||
# Return the message ID
|
||
#
|
||
def id
|
||
@attributes['id']
|
||
end
|
||
|
||
#
|
||
# Return the message token
|
||
#
|
||
def token
|
||
@attributes['token']
|
||
end
|
||
|
||
#
|
||
# Set a has of all the attributes from the API that should be exposed through
|
||
# the Message class.
|
||
#
|
||
ATTRIBUTES = {
|
||
:status => [:status, :status],
|
||
:last_delivery_attempt => [:status, :last_delivery_attempt, :timestamp],
|
||
:held? => [:status, :held, :boolean],
|
||
:hold_expiry => [:status, :hold_expiry, :timestamp],
|
||
:rcpt_to => [:details, :rcpt_to],
|
||
:mail_from => [:details, :mail_from],
|
||
:subject => [:details, :subject],
|
||
:message_id => [:details, :message_id],
|
||
:timestamp => [:details, :timestamp, :timestamp],
|
||
:direction => [:details, :direction],
|
||
:size => [:details, :size],
|
||
:bounce? => [:details, :bounce, :boolean],
|
||
:bounce_for_id => [:details, :bounce],
|
||
:tag => [:details, :tag],
|
||
:received_with_ssl? => [:details, :received_with_ssl, :boolean],
|
||
:inspected? => [:inspection, :inspected, :boolean],
|
||
:spam? => [:inspection, :spam, :boolean],
|
||
:spam_score => [:inspection, :spam_score],
|
||
:threat? => [:inspection, :thret, :boolean],
|
||
:threat_details => [:inspection, :threat_details],
|
||
:plain_body => [:plain_body],
|
||
:html_body => [:html_body],
|
||
}
|
||
|
||
#
|
||
# Catch calls to any of the default attributes for a message and return the
|
||
# data however we'd like it
|
||
#
|
||
def method_missing(name, *args, &block)
|
||
if mapping = ATTRIBUTES[name.to_sym]
|
||
expansion, attribute, type = mapping
|
||
value = from_expansion(expansion, attribute)
|
||
case type
|
||
when :timestamp
|
||
value ? Time.at(value) : nil
|
||
when :boolean
|
||
value == 1
|
||
else
|
||
value
|
||
end
|
||
else
|
||
super
|
||
end
|
||
end
|
||
|
||
#
|
||
# Return a set of headers which can be queried like a hash however looking up
|
||
# values using [] will be case-insensitive.
|
||
#
|
||
def headers
|
||
@headers ||= HeaderSet.new(from_expansion(:headers))
|
||
end
|
||
|
||
#
|
||
# Return an array of attachment objects
|
||
#
|
||
def attachments
|
||
@attachments ||= from_expansion(:attachments).map do |a|
|
||
Attachment.new(a)
|
||
end
|
||
end
|
||
|
||
#
|
||
# Return the full raw message
|
||
#
|
||
def raw_message
|
||
@raw_message ||= Base64.decode64(from_expansion(:raw_message))
|
||
end
|
||
|
||
private
|
||
|
||
def from_expansion(expansion, attribute = nil, loaded = false)
|
||
if @attributes.has_key?(expansion.to_s) || loaded
|
||
attribute ? @attributes[expansion.to_s][attribute.to_s] : @attributes[expansion.to_s]
|
||
else
|
||
load_expansions(expansion)
|
||
from_expansion(expansion, attribute, true)
|
||
end
|
||
end
|
||
|
||
def load_expansions(*names)
|
||
puts "\e[31mLoading expansion #{names}\e[0m"
|
||
api = @client.moonrope.messages.message(:id => self.id, :_expansions => names)
|
||
if api.success?
|
||
names.each do |expansion_name|
|
||
if api.data.has_key?(expansion_name.to_s)
|
||
@attributes[expansion_name.to_s] = api.data[expansion_name.to_s]
|
||
end
|
||
end
|
||
else
|
||
raise Postman::Error, "Couldn't load expansion data (#{names.join(', ')}) for message ID '#{self.id}'"
|
||
end
|
||
end
|
||
|
||
end
|
||
end
|