Skip to content

Instantly share code, notes, and snippets.

@raviwu
Last active June 24, 2016 15:30
Show Gist options
  • Save raviwu/38952ac935f45cb93ace624ae9fb3512 to your computer and use it in GitHub Desktop.
Save raviwu/38952ac935f45cb93ace624ae9fb3512 to your computer and use it in GitHub Desktop.
AmazonSnsWrapper Setup
# In Gemfile
# Include AWS SDK V1 for paperclip if your paperclip version is less than 5.0
gem 'aws-sdk-v1'
# Need to AWS V2 SDK for SNS methods, gem 'aws-sdk', '~>1.6' doesn't have Aws::SNS methods
gem 'aws-sdk', '~> 2.0'
######################################################
# In app/services/amazon_sns_wrapper.rb
require 'aws-sdk'
require 'json/ext'
class AmazonSnsWrapper
AWS_SNS_CONFIG = {
apns: YOUR_APNS_PLATFORM_ENDPOINT,
gcm: YOUR_GCM_PLATFORM_ENDPOINT
}
def self.push_notification(options = {})
amazon_sns_info = options[:amazon_sns_info]
message = options[:message]
badge = options[:badge]
push_uri = options[:push_uri]
return false if message.blank?
topic_arn = options[:topic_arn]
target_arn = amazon_sns_info.endpoint_arn if amazon_sns_info.present?
custom_data = {
key_1: "value 1",
key_2: "value 2"
}
apns_payload = {
aps: {
alert: message,
badge: badge,
sound: "default",
url: push_uri
},
custom_data: custom_data
}
time_to_live_seconds = 60 * 60 * 24 * 7
gcm_payload = {
data: {
message: message,
collapse_key: "Ruby AWS",
time_to_live: time_to_live_seconds,
url: push_uri,
custom_data: custom_data
}
}
wrapped_message = {
default: message,
APNS: apns_payload.to_json,
APNS_SANDBOX: apns_payload.to_json,
GCM: gcm_payload.to_json
}.to_json
sns = self.get_amazon_sns_client
begin
push_params = {
message: wrapped_message,
message_structure: "json"
}
push_params[:topic_arn] = topic_arn if topic_arn.present?
push_params[:target_arn] = target_arn if topic_arn.blank? && target_arn.present?
response = sns.publish(push_params)
rescue => e
self.log(e)
false
end
end
def self.check_amazon_sns_platform_endpoint(amazon_sns_info)
return false if amazon_sns_info.endpoint_arn.blank?
sns = self.get_amazon_sns_client
begin
response = sns.get_endpoint_attributes({endpoint_arn: amazon_sns_info.endpoint_arn})
rescue => e
self.log(e)
false
end
end
def self.create_amazon_sns_platform_endpoint(amazon_sns_info)
platform_application_arn = AWS_SNS_CONFIG[amazon_sns_info.platform.to_sym]
token = amazon_sns_info.device_token
custom_user_data = {
user_id: amazon_sns_info.user_id,
email: amazon_sns_info.user.email
}.to_json
sns = self.get_amazon_sns_client
begin
response = sns.create_platform_endpoint(platform_application_arn: platform_application_arn, token: token, custom_user_data: custom_user_data)
response.endpoint_arn
rescue => e
self.log(e)
false
end
end
def self.delete_amazon_sns_platform_endpoint(amazon_sns_info)
sns = self.get_amazon_sns_client
# early return if the endpoint deos not exist
return false unless self.check_amazon_sns_platform_endpoint(amazon_sns_info)
begin
sns.delete_endpoint(endpoint_arn: amazon_sns_info.endpoint_arn)
rescue => e
self.log(e)
false
end
end
def self.check_amazon_sns_topic(topic)
topic_arn = "#{ARN_PREFIX_OF_YOUR_AMAZON_SNS_ACCOUNT}#{topic}"
sns = self.get_amazon_sns_client
begin
response = sns.get_topic_attributes(topic_arn: topic_arn)
rescue => e
self.log(e)
false
end
end
def self.create_amazon_sns_topic(topic)
sns = self.get_amazon_sns_client
begin
response = sns.create_topic(name: topic)
response.topic_arn
rescue => e
self.log(e)
false
end
end
def self.delete_amazon_sns_topic(topic)
topic_arn = "#{ARN_PREFIX_OF_YOUR_AMAZON_SNS_ACCOUNT}#{topic}"
sns = self.get_amazon_sns_client
response = sns.delete_topic(topic_arn: topic_arn)
end
def self.subscribe_amazon_sns_topic(amazon_sns_info)
topics = ["ASSIGNED_TOPIC_1", "ASSIGNED_TOPIC_2"]
# make sure the topic existed on SNS
topics.each do |topic|
self.create_amazon_sns_topic(topic) unless self.check_amazon_sns_topic(topic)
end
topic_arns = topics.map do |topic|
"#{ARN_PREFIX_OF_YOUR_AMAZON_SNS_ACCOUNT}#{topic}"
end
subscription_arns = []
sns = self.get_amazon_sns_client
topic_arns.each do |topic_arn|
begin
response = sns.subscribe({
topic_arn: topic_arn, # required
protocol: "application", # required
endpoint: amazon_sns_info.endpoint_arn
})
subscription_arns << response.subscription_arn if response.subscription_arn.present?
rescue => e
self.log(e)
end
end
subscription_arns
end
def self.unsubscribe_amazon_sns_topic(amazon_sns_info)
subscription_arns = amazon_sns_info.subscribed_topics[:subscription_arns]
sns = self.get_amazon_sns_client
subscription_arns.each do |subscription_arn|
begin
sns.unsubscribe({ subscription_arn: subscription_arn })
rescue => e
self.log(e)
end
end if subscription_arns.present?
end
private
def self.log(e)
Rails.logger.info("Amazon SNS Failed: #{e} with #{e.message}")
end
def self.get_amazon_sns_client
credential = YAML.load_file("#{Rails.root.to_s}/config/aws.yml")[Rails.env]
Aws.config.update({
region: AWS_SNS_REGION,
credentials: Aws::Credentials.new(credential['access_key_id'], credential['secret_access_key'])
})
Aws::SNS::Client.new
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment