-
Notifications
You must be signed in to change notification settings - Fork 332
/
push-notification.rb
111 lines (84 loc) · 2.7 KB
/
push-notification.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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
require 'rack/push-notification'
require 'sinatra/base'
require 'sinatra/param'
require 'houston'
class Helios::Backend::PushNotification < Sinatra::Base
helpers Sinatra::Param
attr_reader :apn_certificate, :apn_environment
def initialize(app, options = {}, &block)
super(Rack::PushNotification.new)
@apn_certificate = options[:apn_certificate] || ENV['APN_CERTIFICATE']
@apn_environment = options[:apn_environment] || ENV['APN_ENVIRONMENT']
end
before do
content_type :json
end
get '/devices/?' do
param :q, String
devices = ::Rack::PushNotification::Device.dataset
devices = devices.filter("tsv @@ to_tsquery('english', ?)", "#{params[:q]}:*") if params[:q] and not params[:q].empty?
if params[:page] or params[:per_page]
param :page, Integer, default: 1, min: 1
param :per_page, Integer, default: 100, in: (1..100)
{
devices: devices.limit(params[:per_page], (params[:page] - 1) * params[:per_page]),
page: params[:page],
total: devices.count
}.to_json
else
param :limit, Integer, default: 100, in: (1..100)
param :offset, Integer, default: 0, min: 0
{
devices: devices.limit(params[:limit], params[:offset])
}.to_json
end
end
get '/devices/:token/?' do
record = ::Rack::PushNotification::Device.find(token: params[:token])
if record
{device: record}.to_json
else
status 404
end
end
head '/message' do
status 503 and return unless client
status 204
end
post '/message' do
status 503 and return unless client
param :payload, String, empty: false
param :tokens, Array, empty: false
tokens = params[:tokens] || ::Rack::PushNotification::Device.all.collect(&:token)
options = JSON.parse(params[:payload])
options[:alert] = options["aps"]["alert"]
options[:badge] = options["aps"]["badge"]
options[:sound] = options["aps"]["sound"]
options[:'content-available'] = options["aps"]["content-available"]
options.delete("aps")
begin
notifications = tokens.collect{|token| Houston::Notification.new(options.dup.update({device: token}))}
client.push(*notifications)
status 204
rescue => error
status 500
{error: error}.to_json
end
end
private
def client
begin
return nil unless apn_certificate and ::File.exist?(apn_certificate)
client = case apn_environment.to_sym
when :development
Houston::Client.development
when :production
Houston::Client.production
end
client.certificate = ::File.read(apn_certificate)
return client
rescue
return nil
end
end
end