wor-push-notifications-aws 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +4 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +24 -0
- data/.travis.yml +14 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +21 -0
- data/README.md +163 -0
- data/Rakefile +6 -0
- data/lib/generators/templates/add_device_token.rb +5 -0
- data/lib/generators/wor/push/notifications/aws/install_generator.rb +51 -0
- data/lib/wor/push/notifications/aws.rb +110 -0
- data/lib/wor/push/notifications/aws/android_push_json_builder.rb +15 -0
- data/lib/wor/push/notifications/aws/ios_push_json_builder.rb +25 -0
- data/lib/wor/push/notifications/aws/push_notifications.rb +94 -0
- data/lib/wor/push/notifications/aws/services/sns_client.rb +15 -0
- data/lib/wor/push/notifications/aws/validators/push_notifications_validator.rb +65 -0
- data/lib/wor/push/notifications/aws/version.rb +9 -0
- data/wor-push-notifications-aws.gemspec +24 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3b8ea9f5f5acde332401fc297c566f3f5daec527
|
4
|
+
data.tar.gz: 7ac5140ce68d400bea02c177db0b93ca61086928
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1138461202f9f5c86bd61bd1ce8a71fbb284f2afee1f6f3a0324ebacd0d3fdf4b3101b8d0d2d039e07869894d844232ce75dcfd8e45dcfbe8e8d233a66d73871
|
7
|
+
data.tar.gz: 692de303da017b9df4fab6fc4df5b9db35113282c8f99c04fe0ea9b5f9eba65daf42360996f34d11fa143918899123214c12d29c956f0820d6383a6587b798cd
|
data/.codeclimate.yml
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# This is the configuration used to check the rubocop source code.
|
2
|
+
|
3
|
+
Rails:
|
4
|
+
Enabled: true
|
5
|
+
|
6
|
+
AllCops:
|
7
|
+
Exclude:
|
8
|
+
- wor-push-notifications-aws.gemspec
|
9
|
+
- lib/generators/templates/add_device_token.rb
|
10
|
+
|
11
|
+
Documentation:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
LineLength:
|
15
|
+
Max: 99
|
16
|
+
|
17
|
+
Style/FrozenStringLiteralComment:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Style/BlockDelimiters:
|
21
|
+
IgnoredMethods: ['have_structure']
|
22
|
+
|
23
|
+
Metrics/BlockLength:
|
24
|
+
ExcludedMethods: ['describe', 'context', 'before']
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in wor-push-notifications-aws.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
gem 'bundler', '~> 1.13'
|
8
|
+
gem 'byebug', '~> 9.0'
|
9
|
+
gem 'codeclimate-test-reporter', '~> 1.0.0'
|
10
|
+
gem 'generator_spec'
|
11
|
+
gem 'rake', '~> 10.0'
|
12
|
+
gem 'rspec', '~> 3.0'
|
13
|
+
gem 'rspec-rails', '~> 3.5'
|
14
|
+
gem 'rubocop', '~> 0.48'
|
15
|
+
gem 'simplecov', '~> 0.13'
|
16
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Wolox
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
# Wor::Push::Notifications::Aws
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/wor-push-notifications-aws.svg)](https://badge.fury.io/rb/wor-push-notifications-aws)
|
4
|
+
[![Dependency Status](https://gemnasium.com/badges/github.com/Wolox/wor-push-notifications-aws.svg)](https://gemnasium.com/github.com/Wolox/wor-push-notifications-aws)
|
5
|
+
[![Build Status](https://travis-ci.org/Wolox/wor-push-notifications-aws.svg)](https://travis-ci.org/Wolox/wor-push-notifications-aws)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/Wolox/wor-push-notifications-aws/badges/gpa.svg)](https://codeclimate.com/github/Wolox/wor-push-notifications-aws)
|
7
|
+
[![Test Coverage](https://codeclimate.com/github/Wolox/wor-push-notifications-aws/badges/coverage.svg)](https://codeclimate.com/github/Wolox/wor-push-notifications-aws/coverage)
|
8
|
+
|
9
|
+
Provide basic setup for storing device tokens and sending Push Notifications to your application using AWS Simple Notification Service (SNS).
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'wor-push-notifications-aws'
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install wor-push-notifications-aws
|
26
|
+
|
27
|
+
## Configuration
|
28
|
+
To use the gem, firstly we have to configure it. But don’t worry since the configuration simply consists of these two steps:
|
29
|
+
1. Firstly, under the config/initializers dir, create the file `wor_push_notifications_aws.rb`:
|
30
|
+
```ruby
|
31
|
+
Wor::Push::Notifications::Aws.configure do |config|
|
32
|
+
config.device_types = [:ios, :android] # optional
|
33
|
+
config.table_name = 'users' # optional
|
34
|
+
config.aws_region = 'us-east-1'
|
35
|
+
config.aws_android_arn = 'some:android:arn' # mandatory field if you choose to use Android devices
|
36
|
+
config.aws_ios_arn = 'some:ios:arn' # mandatory field if you choose to use iOS devices
|
37
|
+
config.aws_ios_sandbox = true # mandatory field if you choose to use iOS devices
|
38
|
+
end
|
39
|
+
```
|
40
|
+
If you don't know where to get the arn values, please see [SNS Setup](#sns-setup) section.
|
41
|
+
|
42
|
+
2. The following step involves running the install generator, which basically creates a migration file to add a column to your selected table in order to store the tokens. To run the generator, run the following commands:
|
43
|
+
```ruby
|
44
|
+
$ rails generate wor:push:notifications:aws:install
|
45
|
+
$ rake db:migrate
|
46
|
+
```
|
47
|
+
|
48
|
+
## Usage
|
49
|
+
***Note***: If you haven’t configured sns, now it’s the moment. (See [SNS Setup](#sns-setup)).
|
50
|
+
|
51
|
+
So far we have the gem and sns configured, so let’s move to what the gem can do.
|
52
|
+
As it’s purpose is to make the app send push notifications, there are 3 methods, **add_token**, **delete_token** and **send_message**, to add/delete the device_token, and to send the message.
|
53
|
+
|
54
|
+
The device token is a unique token obtained from each pair of App and Device. This token is used for creating an endpoint to identify your users' phones to which you will be sending the push notifications.
|
55
|
+
|
56
|
+
The device type identifies from which type of device you have obtained the device token, because the data used for each platform is different.
|
57
|
+
iOS and Android are the only device types supported for the moment.
|
58
|
+
|
59
|
+
### Add token
|
60
|
+
Attach device_tokens to a given user instance:
|
61
|
+
```ruby
|
62
|
+
Wor::Push::Notifications::Aws.add_token(user, device_token, device_type)
|
63
|
+
```
|
64
|
+
#### Parameters
|
65
|
+
- user: Instance where we want to store the device_token, to which we will send push notifications.
|
66
|
+
- device_token: Unique identifier you get from the the app.
|
67
|
+
- device_type: So far we support the values :android or :ios
|
68
|
+
|
69
|
+
### Delete token
|
70
|
+
Delete token from the user instance:
|
71
|
+
```ruby
|
72
|
+
Wor::Push::Notifications::Aws.delete_token(user, device_token)
|
73
|
+
```
|
74
|
+
#### Parameters
|
75
|
+
- user: Instance where we want to store the device_token, to which we will send push notifications.
|
76
|
+
- device_token: Unique identifier you get from the the app.
|
77
|
+
|
78
|
+
### Send message
|
79
|
+
Send a given message to the user instance:
|
80
|
+
```ruby
|
81
|
+
Wor::Push::Notifications::Aws.send_message(user, message_content)
|
82
|
+
```
|
83
|
+
#### Parameters
|
84
|
+
- user: Instance which will receive the message. It must have the `device_tokens` from the user's phones.
|
85
|
+
- message_content: Message you want to send to the user. This parameter must have a JSON format.
|
86
|
+
- It **requires** the `message` field.
|
87
|
+
- You can add a `badge` field (integer type) to be included in the app icon to show how many pending notifications the user has.
|
88
|
+
- You can include any other field in the JSON, with the information you need to send in the push notification
|
89
|
+
|
90
|
+
**\*BADGE:** iOS shows the badge automatically, but you have to include it yourself in Android devices.
|
91
|
+
|
92
|
+
***message_content example:***
|
93
|
+
|
94
|
+
Suppose you have a billing application, you will send the data related to the new bill that has been charged in the system and the amount of unread notifications.
|
95
|
+
|
96
|
+
```
|
97
|
+
message_content = { message: 'You have a new bill!', badge: 5, account_id: 93, bill_id: 45 }
|
98
|
+
```
|
99
|
+
|
100
|
+
## AWS Credentials
|
101
|
+
In order to use Aws SNS, you'll need to have Aws configured with the right credentials.
|
102
|
+
You can set up them according to one of the ways explained under the
|
103
|
+
"credentials" section at http://docs.aws.amazon.com/sdkforruby/api/Aws/SNS/Client.html.
|
104
|
+
We recommend to use ENV variables with Rails secrets when setting up the configuration.
|
105
|
+
|
106
|
+
*Note:* Aws region is specified in the [initializer file](#configuration).
|
107
|
+
|
108
|
+
## SNS Setup
|
109
|
+
|
110
|
+
**If you HAVE a SNS Application follow this instructions**
|
111
|
+
|
112
|
+
- i) Log in the AWS Console
|
113
|
+
- ii) Click on Services and select Simple Notification Services in Messaging group
|
114
|
+
- iii) Select Applications tab in the left panel
|
115
|
+
- iv) You will have your applications' **ARN** listed in a table
|
116
|
+
- v) When selecting any of them you can see more details of each application, with the information if it's a SANDBOX environment in the iOS case
|
117
|
+
|
118
|
+
You will have to create an instance profile for the Elastic Beanstalk environment that's running your application, with the permissions to access the Simple Notification Service or get an AWS_ACCESS_KEY and AWS_SECRET_KEY pair to access this service from outside of AWS.
|
119
|
+
|
120
|
+
If you want more information about AWS SNS visit the [documentation](http://docs.aws.amazon.com/sns/latest/dg/SNSMobilePush.html) page.
|
121
|
+
If you want more information on how to use AWS with Google Cloud Messaging (for Android) check this [documentation](http://docs.aws.amazon.com/sns/latest/dg/mobile-push-gcm.html).
|
122
|
+
If you want more information on how to use AWS with Apple Push Notifications Service (for iOS) check this [documentation](http://docs.aws.amazon.com/sns/latest/dg/mobile-push-apns.html).
|
123
|
+
|
124
|
+
## Requirements
|
125
|
+
Since a json attribute is needed to store device_tokens on the user table,
|
126
|
+
Postgres 9.3 or higher is required.
|
127
|
+
|
128
|
+
## Contributing
|
129
|
+
1. Fork it
|
130
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
131
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
132
|
+
4. Run rubocop lint (`bundle exec rubocop -R --format simple`)
|
133
|
+
5. Run rspec tests (`bundle exec rspec`)
|
134
|
+
6. Push your branch (`git push origin my-new-feature`)
|
135
|
+
7. Create a new Pull Request
|
136
|
+
|
137
|
+
## About
|
138
|
+
This project is maintained by [Leandro Masello](https://github.com/lmasello) along with
|
139
|
+
[Francisco Landino](https://github.com/plandino) and it was written by
|
140
|
+
[Wolox](http://www.wolox.com.ar).
|
141
|
+
![Wolox](https://raw.githubusercontent.com/Wolox/press-kit/master/logos/logo_banner.png)
|
142
|
+
|
143
|
+
## License
|
144
|
+
**wor-push-notifications-aws** is available under the MIT [license](https://raw.githubusercontent.com/Wolox/wor-push-notifications-aws/master/LICENSE.txt).
|
145
|
+
Copyright (c) 2017 Wolox
|
146
|
+
|
147
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
148
|
+
of this software and associated documentation files (the "Software"), to deal
|
149
|
+
in the Software without restriction, including without limitation the rights
|
150
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
151
|
+
copies of the Software, and to permit persons to whom the Software is
|
152
|
+
furnished to do so, subject to the following conditions:
|
153
|
+
|
154
|
+
The above copyright notice and this permission notice shall be included in
|
155
|
+
all copies or substantial portions of the Software.
|
156
|
+
|
157
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
158
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
159
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
160
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
161
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
162
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
163
|
+
THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'rails/generators'
|
3
|
+
require 'rails/generators/migration'
|
4
|
+
|
5
|
+
module Wor
|
6
|
+
module Push
|
7
|
+
module Notifications
|
8
|
+
module Aws
|
9
|
+
module Generators
|
10
|
+
class InstallGenerator < Rails::Generators::Base
|
11
|
+
include Rails::Generators::Migration
|
12
|
+
source_root File.expand_path('./../../../../../templates', __FILE__)
|
13
|
+
|
14
|
+
desc "This generator creates the migration file required to add the attribute
|
15
|
+
device_tokens to the given table"
|
16
|
+
|
17
|
+
def copy_migration
|
18
|
+
file_name = 'add_device_token'
|
19
|
+
migration_name = "#{file_name}_to_#{table_name}.rb"
|
20
|
+
if self.class.migration_exists?('db/migrate', migration_name)
|
21
|
+
say_status('skipped', "Migration #{migration_name} already exists")
|
22
|
+
else
|
23
|
+
migration_template "#{file_name}.rb", "db/migrate/#{migration_name}",
|
24
|
+
migration_version: migration_version, table_name: table_name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Implement the required interface for Rails::Generators::Migration
|
29
|
+
def self.next_migration_number(_path)
|
30
|
+
Time.now.utc.strftime('%Y%m%d%H%M%S')
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def rails5?
|
36
|
+
Rails.version.start_with? '5'
|
37
|
+
end
|
38
|
+
|
39
|
+
def migration_version
|
40
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if rails5?
|
41
|
+
end
|
42
|
+
|
43
|
+
def table_name
|
44
|
+
Wor::Push::Notifications::Aws.table_name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'wor/push/notifications/aws/version'
|
2
|
+
require 'wor/push/notifications/aws/push_notifications'
|
3
|
+
|
4
|
+
module Wor
|
5
|
+
module Push
|
6
|
+
module Notifications
|
7
|
+
module Aws
|
8
|
+
DEVICE_TYPES = %i[ios android].freeze
|
9
|
+
|
10
|
+
@config = {
|
11
|
+
device_types: DEVICE_TYPES,
|
12
|
+
table_name: :users
|
13
|
+
}
|
14
|
+
|
15
|
+
def self.configure
|
16
|
+
yield self
|
17
|
+
end
|
18
|
+
|
19
|
+
# Precondition: types must be an array of symbols containing valid device types.
|
20
|
+
# Every type included in this array must be a valid device type
|
21
|
+
# (you can ask for valid device types with the method valid_device_types).
|
22
|
+
# Default is ['ios' 'android'].
|
23
|
+
def self.device_types=(types)
|
24
|
+
raise ArgumentError, 'Argument must be an array of symbols' unless types.is_a?(Array)
|
25
|
+
types.each do |type|
|
26
|
+
raise ArgumentError, "Invalid type #{type}" unless DEVICE_TYPES.include?(type)
|
27
|
+
end
|
28
|
+
@config[:device_types] = types
|
29
|
+
end
|
30
|
+
|
31
|
+
# Precondition: table_name must be a string which points out the name of the table that
|
32
|
+
# will store the device_tokens.
|
33
|
+
# Default is 'users'.
|
34
|
+
def self.table_name=(table_name)
|
35
|
+
raise ArgumentError, 'Argument must be a string' unless table_name.is_a?(String)
|
36
|
+
raise ArgumentError, 'Argument must not be an empty string' if table_name.empty?
|
37
|
+
@config[:table_name] = table_name.pluralize.to_sym
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.aws_ios_arn=(aws_ios_arn)
|
41
|
+
raise ArgumentError, 'Argument must be a string' unless aws_ios_arn.is_a?(String)
|
42
|
+
@config[:aws_ios_arn] = aws_ios_arn
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.aws_ios_sandbox=(aws_ios_sandbox)
|
46
|
+
raise ArgumentError, 'Argument must be a boolean' unless boolean?(aws_ios_sandbox)
|
47
|
+
@config[:aws_ios_sandbox] = aws_ios_sandbox
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.aws_android_arn=(aws_android_arn)
|
51
|
+
raise ArgumentError, 'Argument must be a string' unless aws_android_arn.is_a?(String)
|
52
|
+
@config[:aws_android_arn] = aws_android_arn
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.aws_region=(aws_region)
|
56
|
+
raise ArgumentError, 'Argument must be a string' unless aws_region.is_a?(String)
|
57
|
+
@config[:aws_region] = aws_region
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.device_types
|
61
|
+
@config[:device_types]
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.table_name
|
65
|
+
@config[:table_name]
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.aws_ios_arn
|
69
|
+
@config[:aws_ios_arn]
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.aws_ios_sandbox
|
73
|
+
@config[:aws_ios_sandbox]
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.aws_android_arn
|
77
|
+
@config[:aws_android_arn]
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.aws_region
|
81
|
+
@config[:aws_region]
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.config
|
85
|
+
@config
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.add_token(user, device_token, device_type)
|
89
|
+
PushNotifications.add_token(user, device_token, device_type)
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.delete_token(user, device_token)
|
93
|
+
PushNotifications.delete_token(user, device_token)
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.send_message(user, message_content)
|
97
|
+
PushNotifications.send_message(user, message_content)
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.valid_device_types
|
101
|
+
DEVICE_TYPES
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.boolean?(value)
|
105
|
+
value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Wor
|
2
|
+
module Push
|
3
|
+
module Notifications
|
4
|
+
module Aws
|
5
|
+
class IosPushJsonBuilder
|
6
|
+
class << self
|
7
|
+
def build_json(message_content)
|
8
|
+
unless Wor::Push::Notifications::Aws.aws_ios_sandbox
|
9
|
+
return { APNS: aps_content(message_content) }
|
10
|
+
end
|
11
|
+
{ APNS_SANDBOX: aps_content(message_content) }
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def aps_content(message_content)
|
17
|
+
{ aps: { alert: message_content[:message], badge: message_content[:badge],
|
18
|
+
sound: 'default' } }.merge(message_content).to_json
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'wor/push/notifications/aws/android_push_json_builder'
|
2
|
+
require 'wor/push/notifications/aws/ios_push_json_builder'
|
3
|
+
require 'wor/push/notifications/aws/services/sns_client'
|
4
|
+
require 'wor/push/notifications/aws/validators/push_notifications_validator'
|
5
|
+
|
6
|
+
module Wor
|
7
|
+
module Push
|
8
|
+
module Notifications
|
9
|
+
module Aws
|
10
|
+
class PushNotifications
|
11
|
+
class << self
|
12
|
+
def add_token(user, device_token, device_type)
|
13
|
+
PushNotificationsValidator.new(user, device_token, device_type).validate_add_token
|
14
|
+
device_token = device_token.to_s.gsub(/\s+/, '')
|
15
|
+
return true if user.device_tokens.key?(device_token)
|
16
|
+
endpoint = sns.create_platform_endpoint(
|
17
|
+
platform_application_arn: app_arn(device_type), token: device_token
|
18
|
+
)
|
19
|
+
user.device_tokens[device_token] = { 'device_type' => device_type,
|
20
|
+
'endpoint_arn' => endpoint[:endpoint_arn] }
|
21
|
+
user.save
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_token(user, device_token)
|
25
|
+
PushNotificationsValidator.new(user).validate_delete_token
|
26
|
+
device_token = device_token.to_s.gsub(/\s+/, '')
|
27
|
+
return true unless user.device_tokens.key?(device_token)
|
28
|
+
sns.delete_endpoint(endpoint_arn: user.device_tokens[device_token]['endpoint_arn'])
|
29
|
+
user.device_tokens.delete(device_token)
|
30
|
+
user.save
|
31
|
+
end
|
32
|
+
|
33
|
+
def send_message(user, message_content)
|
34
|
+
PushNotificationsValidator.new(user).validate_send_message(message_content)
|
35
|
+
message_content = badge_check(message_content)
|
36
|
+
send_notifications_to_user(user, message_content)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def send_notifications_to_user(user, message_content)
|
42
|
+
return false if user.device_tokens.values.empty?
|
43
|
+
send_notifications_to_devices(user, message_content)
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
def send_notifications_to_devices(user, message_content)
|
48
|
+
user.device_tokens.each do |device_token, token|
|
49
|
+
message = prepare_message(token['device_type'], message_content)
|
50
|
+
begin
|
51
|
+
sns.publish(target_arn: token['endpoint_arn'], message: message.to_json,
|
52
|
+
message_structure: 'json')
|
53
|
+
rescue
|
54
|
+
user.device_tokens.delete(device_token)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
user.save if user.device_tokens_changed?
|
58
|
+
end
|
59
|
+
|
60
|
+
def prepare_message(device_type, message_content)
|
61
|
+
app_arn_for_device[device_type.to_sym][:json_builder].build_json(message_content)
|
62
|
+
end
|
63
|
+
|
64
|
+
def sns
|
65
|
+
@sns_client ||= SnsClient.new(Wor::Push::Notifications::Aws.aws_region)
|
66
|
+
end
|
67
|
+
|
68
|
+
def app_arn(device_type)
|
69
|
+
app_arn_for_device[device_type.to_sym][:arn]
|
70
|
+
end
|
71
|
+
|
72
|
+
def app_arn_for_device
|
73
|
+
{
|
74
|
+
ios: {
|
75
|
+
arn: Wor::Push::Notifications::Aws.aws_ios_arn,
|
76
|
+
json_builder: IosPushJsonBuilder
|
77
|
+
},
|
78
|
+
android: {
|
79
|
+
arn: Wor::Push::Notifications::Aws.aws_android_arn,
|
80
|
+
json_builder: AndroidPushJsonBuilder
|
81
|
+
}
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def badge_check(message_content)
|
86
|
+
message_content[:badge] = 1 if message_content[:badge].nil?
|
87
|
+
message_content
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Wor
|
2
|
+
module Push
|
3
|
+
module Notifications
|
4
|
+
module Aws
|
5
|
+
class PushNotificationsValidator
|
6
|
+
def initialize(model, device_token = nil, device_type = nil)
|
7
|
+
@model = model
|
8
|
+
@device_token = device_token
|
9
|
+
@device_type = device_type
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate_add_token
|
13
|
+
validate_existence_of_attributes_in_model
|
14
|
+
validate_parameters
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate_delete_token
|
18
|
+
validate_existence_of_attributes_in_model
|
19
|
+
end
|
20
|
+
|
21
|
+
def validate_send_message(message_content)
|
22
|
+
validate_existence_of_attributes_in_model
|
23
|
+
validate_message_content(message_content)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def validate_existence_of_attributes_in_model
|
29
|
+
raise message_for_missing_attribute unless @model.has_attribute?(:device_tokens)
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate_message_content(message_content)
|
33
|
+
raise message_for_invalid_message_content if message_content[:message].blank?
|
34
|
+
end
|
35
|
+
|
36
|
+
def validate_parameters
|
37
|
+
raise ArgumentError, message_for_invalid_device_type unless device_type_valid?
|
38
|
+
raise ArgumentError, message_for_nil_device_token if @device_token.blank?
|
39
|
+
end
|
40
|
+
|
41
|
+
def message_for_missing_attribute
|
42
|
+
'Missing attribute device_tokens for model. Have you run the gem migration?'
|
43
|
+
end
|
44
|
+
|
45
|
+
def message_for_invalid_device_type
|
46
|
+
"Invalid device_type. It has to be one of the types configured \
|
47
|
+
#{Wor::Push::Notifications::Aws.device_types}."
|
48
|
+
end
|
49
|
+
|
50
|
+
def message_for_nil_device_token
|
51
|
+
'device_token cannot be nil.'
|
52
|
+
end
|
53
|
+
|
54
|
+
def message_for_invalid_message_content
|
55
|
+
"the message_content must have a 'message' field"
|
56
|
+
end
|
57
|
+
|
58
|
+
def device_type_valid?
|
59
|
+
Wor::Push::Notifications::Aws.device_types.include? @device_type
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'wor/push/notifications/aws/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "wor-push-notifications-aws"
|
8
|
+
spec.version = Wor::Push::Notifications::Aws::VERSION
|
9
|
+
spec.authors = ["Leandro Masello", "Francisco Landino"]
|
10
|
+
spec.email = ["francisco.landino@wolox.com.ar", "leandro.masello@wolox.com.ar"]
|
11
|
+
|
12
|
+
spec.summary = 'Easily send Push Notifications to your application using AWS Simple Notification Service (SNS)'
|
13
|
+
spec.description = 'Provide basic set up for storing device tokens and sending Push Notifications to your application using AWS Simple Notification Service (SNS)'
|
14
|
+
spec.homepage = "https://github.com/Wolox/wor-push-notifications-aws"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency 'railties', '>= 4.1.0', '< 5.2'
|
23
|
+
spec.add_dependency 'aws-sdk-rails', "~> 1.0"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wor-push-notifications-aws
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Leandro Masello
|
8
|
+
- Francisco Landino
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2017-07-26 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: railties
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 4.1.0
|
21
|
+
- - "<"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '5.2'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 4.1.0
|
31
|
+
- - "<"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.2'
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: aws-sdk-rails
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
type: :runtime
|
42
|
+
prerelease: false
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
description: Provide basic set up for storing device tokens and sending Push Notifications
|
49
|
+
to your application using AWS Simple Notification Service (SNS)
|
50
|
+
email:
|
51
|
+
- francisco.landino@wolox.com.ar
|
52
|
+
- leandro.masello@wolox.com.ar
|
53
|
+
executables: []
|
54
|
+
extensions: []
|
55
|
+
extra_rdoc_files: []
|
56
|
+
files:
|
57
|
+
- ".codeclimate.yml"
|
58
|
+
- ".gitignore"
|
59
|
+
- ".rspec"
|
60
|
+
- ".rubocop.yml"
|
61
|
+
- ".travis.yml"
|
62
|
+
- Gemfile
|
63
|
+
- LICENSE.txt
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- lib/generators/templates/add_device_token.rb
|
67
|
+
- lib/generators/wor/push/notifications/aws/install_generator.rb
|
68
|
+
- lib/wor/push/notifications/aws.rb
|
69
|
+
- lib/wor/push/notifications/aws/android_push_json_builder.rb
|
70
|
+
- lib/wor/push/notifications/aws/ios_push_json_builder.rb
|
71
|
+
- lib/wor/push/notifications/aws/push_notifications.rb
|
72
|
+
- lib/wor/push/notifications/aws/services/sns_client.rb
|
73
|
+
- lib/wor/push/notifications/aws/validators/push_notifications_validator.rb
|
74
|
+
- lib/wor/push/notifications/aws/version.rb
|
75
|
+
- wor-push-notifications-aws.gemspec
|
76
|
+
homepage: https://github.com/Wolox/wor-push-notifications-aws
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata: {}
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.4.5
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: Easily send Push Notifications to your application using AWS Simple Notification
|
100
|
+
Service (SNS)
|
101
|
+
test_files: []
|