How to push notification in Rails using Amazon SNS

Just a memo 😉

1. Initialize

sns = AWS::SNS.new(
    access_key_id: Settings.aws.access_key_id,
    secret_access_key: Settings.aws.secret_access_key,
    region: Settings.aws.region
)
client = sns.client

2. Create platform endpoint from device token

response = client.create_platform_endpoint(
    platform_application_arn: Settings.application_arn,
    token: device_token
)
endpoint_arn = response[:endpoint_arn]

Somehow the following error happens

AWS::SNS::Errors::InvalidParameter Invalid parameter: Token Reason: Endpoint arn:aws:sns:us-east-1:**** already exists with the same Token, but different attributes.

We can try to obtain endpoint_arn from the error message 😄

begin
    response = client.create_platform_endpoint(
        platform_application_arn: Settings.application_arn,
        token: device_token
    )
    endpoint_arn = response[:endpoint_arn]
rescue => e
    result = e.message.match(/Endpoint(.*)already/)
    if result.present?
        endpoint_arn = result[1].strip
    end
end

3. Push notification

3.1 Push notification directly

data = {
    'aps' => {
        'alert' => 'Hi there!',
        'badge' => 1,
        'sound' => 'default'
    }
}

# double json encode
message_json = {
    'APNS' => data.to_json
}.to_json

client.publish(
    target_arn: endpoint_arn,
    message: message_json,
    message_structure: 'json'
)

3.2 Push notification using topic

  • Create topic
topic = client.create_topic(name: 'Topic name')
topic_arn = topic[:topic_arn]
  • Subscribe endpoint to topic
client.subscribe(
    topic_arn: topic_arn,
    protocol: 'application',
    endpoint: endpoint_arn
)
  • Push notification
data = {
    'aps' => {
        'alert' => 'Hi there!',
        'badge' => 1,
        'sound' => 'default'
    }
}

# double json encode
message_json = {
    'default' => 'Hi there!',
    'APNS' => data.to_json
}.to_json

client.publish(
    target_arn: topic_arn,
    message: message_json,
    message_structure: 'json'
)