Class: APN::Notification

Inherits:
ActiveRecord::Base
  • Object
show all
Extended by:
ActionView::Helpers::TextHelper
Includes:
ActionView::Helpers::TextHelper
Defined in:
lib/apn_on_rails/app/models/apn/notification.rb

Overview

Represents the message you wish to send. An APN::Notification belongs to an APN::Device.

Example:

apn = APN::Notification.new
apn.badge = 5
apn.sound = 'my_sound.aiff'
apn.alert = 'Hello!'
apn.device = APN::Device.find(1)
apn.save

To deliver call the following method:

APN::Notification.send_notifications

As each APN::Notification is sent the sent_at column will be timestamped, so as to not be sent again.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.send_notifications(notifications = APN::Notification.all(:conditions => {:sent_at => nil})) ⇒ Object

Opens a connection to the Apple APN server and attempts to batch deliver an Array of notifications.

This method expects an Array of APN::Notifications. If no parameter is passed in then it will use the following:

APN::Notification.all(:conditions => {:sent_at => nil})

As each APN::Notification is sent the sent_at column will be timestamped, so as to not be sent again.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/apn_on_rails/app/models/apn/notification.rb', line 87

def send_notifications(notifications = APN::Notification.all(:conditions => {:sent_at => nil}))
  unless notifications.nil? || notifications.empty?
    logger.info "APN: Attempting to deliver #{pluralize(notifications.size, 'notification')}."
    cert = File.read(configatron.apn.cert)
    ctx = OpenSSL::SSL::SSLContext.new
    ctx.key = OpenSSL::PKey::RSA.new(cert, configatron.apn.passphrase)
    ctx.cert = OpenSSL::X509::Certificate.new(cert)
  
    s = TCPSocket.new(configatron.apn.host, configatron.apn.port)
    ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
    ssl.sync = true
    ssl.connect
  
    notifications.each do |noty|
      ssl.write(noty.message_for_sending)
      noty.sent_at = Time.now
      noty.save
    end
  
    ssl.close
    s.close
  end
end

Instance Method Details

#alert=(message) ⇒ Object

Stores the text alert message you want to send to the device.

If the message is over 150 characters long it will get truncated to 150 characters with a ...



29
30
31
32
33
34
# File 'lib/apn_on_rails/app/models/apn/notification.rb', line 29

def alert=(message)
  if !message.blank? && message.size > 150
    message = truncate(message, :length => 150)
  end
  write_attribute('alert', message)
end

#apple_hashObject

Creates a Hash that will be the payload of an APN.

Example:

apn = APN::Notification.new
apn.badge = 5
apn.sound = 'my_sound.aiff'
apn.alert = 'Hello!'
apn.apple_hash # => {"aps" => {"badge" => 5, "sound" => "my_sound.aiff", "alert" => "Hello!"}}


44
45
46
47
48
49
50
51
52
53
54
# File 'lib/apn_on_rails/app/models/apn/notification.rb', line 44

def apple_hash
  result = {}
  result['aps'] = {}
  result['aps']['alert'] = self.alert if self.alert
  result['aps']['badge'] = self.badge.to_i if self.badge
  if self.sound
    result['aps']['sound'] = self.sound if self.sound.is_a? String
    result['aps']['sound'] = "1.aiff" if self.sound.is_a?(TrueClass)
  end
  result
end

#message_for_sendingObject

Creates the binary message needed to send to Apple.

Raises:



69
70
71
72
73
74
# File 'lib/apn_on_rails/app/models/apn/notification.rb', line 69

def message_for_sending
  json = self.to_apple_json
  message = "\0\0 #{self.device.to_hexa}\0#{json.length.chr}#{json}"
  raise APN::Errors::ExceededMessageSizeError.new(message) if message.size.to_i > 256
  message
end

#to_apple_jsonObject

Creates the JSON string required for an APN message.

Example:

apn = APN::Notification.new
apn.badge = 5
apn.sound = 'my_sound.aiff'
apn.alert = 'Hello!'
apn.to_apple_json # => '{"aps":{"badge":5,"sound":"my_sound.aiff","alert":"Hello!"}}'


64
65
66
# File 'lib/apn_on_rails/app/models/apn/notification.rb', line 64

def to_apple_json
  self.apple_hash.to_json
end