Class: APND::Notification

Inherits:
Object
  • Object
show all
Defined in:
lib/apnd/notification.rb

Overview

APND::Notification is the base class for creating new push notifications.

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ Notification

Create a new Notification object from a hash



129
130
131
132
133
134
135
# File 'lib/apnd/notification.rb', line 129

def initialize(params = {})
  @token  = params[:token]
  @alert  = params[:alert]
  @badge  = params[:badge]
  @sound  = params[:sound]
  @custom = params[:custom]
end

Class Attribute Details

.upstream_hostObject

The host notifications will be written to, usually one running APND



14
15
16
# File 'lib/apnd/notification.rb', line 14

def upstream_host
  @upstream_host
end

.upstream_portObject

The port to connect to upstream_host on



19
20
21
# File 'lib/apnd/notification.rb', line 19

def upstream_port
  @upstream_port
end

Instance Attribute Details

#alertObject

The alert to send



36
37
38
# File 'lib/apnd/notification.rb', line 36

def alert
  @alert
end

#badgeObject

The badge number to set



41
42
43
# File 'lib/apnd/notification.rb', line 41

def badge
  @badge
end

#customObject

Custom data to send



51
52
53
# File 'lib/apnd/notification.rb', line 51

def custom
  @custom
end

#soundObject

The sound to play



46
47
48
# File 'lib/apnd/notification.rb', line 46

def sound
  @sound
end

#tokenObject

The device token from Apple



31
32
33
# File 'lib/apnd/notification.rb', line 31

def token
  @token
end

Class Method Details

.create(params = {}, push = true) ⇒ Object

Create a new APN



72
73
74
75
76
# File 'lib/apnd/notification.rb', line 72

def self.create(params = {}, push = true)
  notification = Notification.new(params)
  notification.push! if push
  notification
end

.open_upstream_socket {|socket| ... } ⇒ Object

Opens a new socket upstream, yields it, and closes it

Yields:

  • (socket)


63
64
65
66
67
# File 'lib/apnd/notification.rb', line 63

def self.open_upstream_socket(&block)
  socket = upstream_socket
  yield socket
  socket.close
end

.parse(data) ⇒ Object

Parse raw data into a new Notification



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
124
# File 'lib/apnd/notification.rb', line 93

def self.parse(data)
  buffer = data.dup
  notification = Notification.new

  header = buffer.slice!(0, 3).unpack('ccc')

  if header[0] != 0
    raise APND::Errors::InvalidNotificationHeader.new(header)
  end

  notification.token = buffer.slice!(0, 32).unpack('H*').first

  json_length = buffer.slice!(0, 2).unpack('CC')

  json = buffer.slice!(0, json_length.last)

  payload = JSON.parse(json)

  %w[alert sound badge].each do |key|
    if payload['aps'] && payload['aps'][key]
      notification.send("#{key}=", payload['aps'][key])
    end
  end

  payload.delete('aps')

  unless payload.empty?
    notification.custom = payload
  end

  notification
end

.upstream_socketObject

Creates a new socket to upstream_host:upstream_port



56
57
58
# File 'lib/apnd/notification.rb', line 56

def self.upstream_socket
  @socket = TCPSocket.new(upstream_host, upstream_port)
end

.valid?(data) ⇒ Boolean

Try to create a new Notification from raw data Used by Daemon::Protocol to validate incoming data

Returns:

  • (Boolean)


82
83
84
85
86
87
88
# File 'lib/apnd/notification.rb', line 82

def self.valid?(data)
  parse(data)
rescue => e
  puts e.inspect
  puts e.backtrace
  false
end

Instance Method Details

#apsObject

aps hash sent to Apple



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/apnd/notification.rb', line 147

def aps
  aps = {}
  aps['alert'] = self.alert      if self.alert
  aps['badge'] = self.badge.to_i if self.badge
  aps['sound'] = self.sound      if self.sound

  output = { 'aps' => aps }

  if self.custom
    self.custom.each do |key, value|
      output[key.to_s] = value
    end
  end
  output
end

#aps_jsonObject

Returns the Notification’s aps hash as json



173
174
175
176
177
178
# File 'lib/apnd/notification.rb', line 173

def aps_json
  return @aps_json if @aps_json
  json = aps.to_json
  raise APND::Errors::InvalidPayload.new(json) if json.size > 256
  @aps_json = json
end

#hex_tokenObject

Token in hex format



140
141
142
# File 'lib/apnd/notification.rb', line 140

def hex_token
  [self.token.delete(' ')].pack('H*')
end

#push!Object

Pushes notification to upstream host:port (default is localhost:22195)



166
167
168
# File 'lib/apnd/notification.rb', line 166

def push!
  self.class.open_upstream_socket { |sock| sock.write(to_bytes) }
end

#to_bytesObject

Format the notification as a string for submission to Apple



184
185
186
# File 'lib/apnd/notification.rb', line 184

def to_bytes
  @bytes ||= "\0\0 %s\0%s%s" % [hex_token, aps_json.length.chr, aps_json]
end