Skip to content

Instantly share code, notes, and snippets.

@johnhamelink
Created September 14, 2016 20:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnhamelink/0446b992956ef529a00934861a45c5d0 to your computer and use it in GitHub Desktop.
Save johnhamelink/0446b992956ef529a00934861a45c5d0 to your computer and use it in GitHub Desktop.
class PushNotificationService
IOS_NAME = 'ios'.freeze
ANDROID_NAME = 'android'.freeze
attr_accessor :gcm_notification, :apns_notification,
:ios_app, :android_app
def gcm_notification
@gcm_notification || Rpush::Gcm::Notification
end
def apns_notification
@apns_notification || Rpush::Apns::Notification
end
def ios_app(device)
@ios_app || Rpush::Apns::App.all.find do |model|
model.name == "#{IOS_NAME}_#{device.environment}"
end
end
def android_app(device)
@android_app || Rpush::Gcm::App.all.find do |model|
model.name == "#{ANDROID_NAME}_#{device.environment}"
end
end
def message(user: nil, users: nil, message: nil, data: {}, category: nil)
return if [:test].include? Rails.env
raise 'No users to send messages to' if users.nil? && user.nil?
raise 'No message or data to send' if message.nil? && data.nil?
# If the message body has no content, don't send a notification
if message.nil? || message.squish.empty?
Rails.logger.info 'Ignoring push notification - no message data'
return
end
users = [user] if users.nil?
# Remove duplicate users
users.uniq!
ios = users.compact.find_all(&:has_ios?)
android = users.compact.find_all(&:has_android?)
Rails.logger.info "Sending Push Notification to #{users.inspect}"
store_message(users.compact, message, data, category)
send_message_via_apn(ios, message, data, category)
send_message_via_gcm(android, message, data, category)
end
def self.error!(user: nil, users: nil, message: nil, data: nil, category: nil)
raise 'No users to send messages to' if users.nil? && user.nil?
raise 'No message or data to send' if message.nil? && data.nil?
data = '' if data.nil?
users = [user] if users.nil?
opts = {
users: users,
message: "Error: #{message}",
data: data
}
opts[:category] = category unless category.nil?
PushNotificationService.message(opts)
end
def self.message(*args)
PushNotificationService.new.message(*args)
end
private
def store_message(users, message, data, category)
# If the data provided isn't already a string,
# and also isn't nil, then we'll convert it to JSON
data = data.to_json unless data.nil? || data.is_a?(String)
opts = {
sessions: users,
message: message,
data: data
}
opts[:category] = category unless category.nil?
Notification.create(opts)
end
def send_message_via_apn(users, msg, data, category)
users.each do |user|
devices = user.devices(device_type: IOS_NAME)
devices.each do |device|
begin
opts = {
app: ios_app(device),
device_token: device.token,
alert: msg,
data: data
}
opts[:category] = category unless category.nil?
apns_notification.create!(opts)
rescue Modis::RecordInvalid => error
Rails.logger.error "Device Token is invalid: #{device.token}"
Rails.logger.error error
end
end
end
end
def send_message_via_gcm(users, msg, data, category)
devices = users.flat_map(&:devices)
devices.each do |device|
begin
gcm_notification.create!(
app: android_app(device),
registration_ids: [device.token],
data: { message: msg, data: data, category: category }
)
rescue Modis::RecordInvalid => error
Rails.logger.error "Device Token is invalid: #{device}"
Rails.logger.error error
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment