notifications_opener 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 883f8b5c7c2d01571e1c0eab6304dce6be1b8b85
4
- data.tar.gz: 50e31296b78f07f8735a3d1a674ae749f2fd0c9f
3
+ metadata.gz: cbe997acbef7f55540dfe1e8742d55924d090b0e
4
+ data.tar.gz: 477e395a0513975bb2c8d2ae34aec3a47ce9f1c8
5
5
  SHA512:
6
- metadata.gz: 2ccef8872761f72855b4c71bc48e4b3c9986321ded79533eed8bbe81d9001efef09afc4918c3b9c63fc54ff54b3e3e6df134b7e1d1ef0dd687d8a7ebfbb4caac
7
- data.tar.gz: c7496ad12e0bfa3762ee66ea7de660e2a28cecd9fc1789a2f214d8de6777744d19730e72e93cb9e16d96a40e71d820e0d1e33b6e709cc18baaeb9363e76009d0
6
+ metadata.gz: f2015ace7ef91a4ad247068a8ab3584f8bf84af5612b97a19b4b0ddb1e7a1f7a87573c427511fb3e253ac12d7e78d465fb13aa79cad4a12cc192936419fbe88f
7
+ data.tar.gz: 8b490c37b4d2579874adff4f07953c6c41bfef3088397fbe552aee7775e40589c8f773edff5580f100e9fb54c0d051b07bf9be60cb7a639c52fb22af65990e86
data/README.md CHANGED
@@ -4,6 +4,9 @@
4
4
 
5
5
  Blocks SMSs from being delivered in development. Instead opens a preview in the browser by intercepting the request to the configured SMS API.
6
6
 
7
+ <img src="https://s13.postimg.org/r6yadbbg7/Screen_Shot_2016_10_03_at_5_35_05_PM.png" width="350"/>
8
+ <img src="https://s13.postimg.org/5w0q91tbr/Screen_Shot_2016_10_03_at_5_32_34_PM.png" width="350"/>
9
+
7
10
  ## Installation
8
11
 
9
12
  Add this line to your application's Gemfile:
@@ -44,14 +47,91 @@ NotificationsOpener.configure do | c |
44
47
  # The SMS API call to intercept
45
48
  c[:url] = /.*alerts.springedge.com.*/
46
49
  end
50
+
51
+
52
+ # For Android Notifications
53
+ NotificationsOpener.configure(:android) do | c |
54
+ # The GCM API call to intercept
55
+ c[:url] = /.*android.googleapis.com\/gcm.*/
56
+ c[:location] = '/tmp'
57
+ end
58
+
47
59
  ```
48
60
 
49
- ## Development
61
+ ## Development and Experimentation
50
62
 
51
63
  After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
52
64
 
53
65
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
54
66
 
67
+ ### SMS Notifications
68
+ Copy and paste the following lines of code after you run `bin/console` from the gem directory
69
+
70
+ ```ruby
71
+ NotificationsOpener.configure(:sms) do | c |
72
+ # Param name for the sender that will be passed to the SMS API
73
+ c[:from_key_name] = "sender"
74
+
75
+ # Param name for the receiver that will be passed to the SMS API
76
+ c[:to_key_name] = "to"
77
+
78
+ # Param name for the message that will be passed to the API
79
+ c[:message_key_name] = "message"
80
+
81
+ # Location to store the preview email files, usually tmp
82
+ c[:location] = '/tmp'
83
+
84
+ # The SMS API call to intercept
85
+ c[:url] = /.*alerts.springedge.com.*/
86
+ end
87
+ Net::HTTP.get('alerts.springedge.com', '/?to=8095456768&sender=NSTWY&message=Hello')
88
+ ```
89
+
90
+ ### Android Notifications
91
+ Copy and paste the following lines of code after you run `bin/console` from the gem directory
92
+
93
+ ```ruby
94
+ NotificationsOpener.configure(:android) do | c |
95
+ # The GCM API call to intercept
96
+ c[:url] = /.*android.googleapis.com\/gcm.*/
97
+ c[:location] = '/tmp'
98
+ end
99
+
100
+ data = {
101
+ "to" => "111111111",
102
+ "data" => {
103
+ "type" => "10041",
104
+ "message" => "You are required to pay an amount of 2500.0 against Rent september. Click here to view & pay",
105
+ "img_link" => nil,
106
+ "title" => "Payment update",
107
+ "time" => "1475480496",
108
+ "deep_link_url" => nil,
109
+ "data_json" => nil,
110
+ "short_msg" => "You are required to pay an amount of 200.0",
111
+ "action_button" => [
112
+ {
113
+ "text" => "View details",
114
+ "screen" => "5",
115
+ "data_json" => nil,
116
+ "deep_link_url" => ""
117
+ }
118
+ ]
119
+ }
120
+ }
121
+ params = {
122
+ :body => data.to_json,
123
+ :headers => {
124
+ 'Content-Type' => 'application/json',
125
+ 'Authorization' => "key=#{@api_key}"
126
+ }
127
+ }
128
+ require 'httparty'
129
+ include HTTParty
130
+
131
+ self.class.post('http://android.googleapis.com/gcm', params)
132
+ ```
133
+
134
+
55
135
  ## Contributing
56
136
 
57
137
  Bug reports and pull requests are welcome on GitHub at https://github.com/abhisheksarka/notifications_opener. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -1,5 +1,5 @@
1
1
  require "notifications_opener/version"
2
- require "notifications_opener/message"
2
+ require "notifications_opener/handler/handler"
3
3
  require "notifications_opener/response_handler"
4
4
  require "notifications_opener/interceptor"
5
5
  require 'fileutils'
@@ -14,11 +14,11 @@ module NotificationsOpener
14
14
  # * from_key_name - The parameter name you pass to the SMS API that identifies the sender
15
15
  # * to_key_name - The parameter name you pass to the SMS API that identifies the receiver
16
16
  # * message_key_name - The parameter name you pass to the SMS API that identifies the message
17
- def self.configure
17
+ def self.configure(type=:sms)
18
18
  c = { }
19
19
  yield(c)
20
20
  create_storage_directory(c)
21
- ins = Interceptor.new(c)
21
+ ins = Interceptor.new(c, type)
22
22
  ins.intercept_and_redirect_to_rack_app
23
23
  ins
24
24
  end
@@ -0,0 +1,24 @@
1
+ require 'json'
2
+
3
+ module NotificationsOpener
4
+ module Handler
5
+ class Android < Base
6
+ attr_accessor :to,
7
+ :message,
8
+ :title,
9
+ :params
10
+
11
+ def initialize(config, env)
12
+ super(config, env)
13
+ @params = JSON.parse(env["rack.input"].read)
14
+ @to = @params['to']
15
+ @message = @params['data']['message']
16
+ @title = @params['data']['title']
17
+ end
18
+
19
+ def notification_type
20
+ 'android'
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,46 @@
1
+ require 'erb'
2
+ require 'launchy'
3
+
4
+ module NotificationsOpener
5
+ module Handler
6
+ class Base
7
+ attr_accessor :config,
8
+ :env,
9
+ :file_path
10
+
11
+ def initialize(config, env)
12
+ @config = config
13
+ @env = env
14
+ @file_path = generate_file_path
15
+ @notification_type = notification_type.capitalize
16
+ end
17
+
18
+ # #
19
+ # Creates the file with the interpolated content in the specified location
20
+ # Opens it up in a browser from preview
21
+ def deliver
22
+ File.open(file_path, 'w') { |file| file.write(rendered_content) }
23
+ Launchy.open("file:///#{URI.parse(file_path)}")
24
+ end
25
+
26
+ # #
27
+ # Uses the message template and binds the instance variable to the template
28
+ # to generate the final markup
29
+ def rendered_content
30
+ ERB.new(template).result(binding)
31
+ end
32
+
33
+ def template
34
+ File.read(File.expand_path("../../template/#{notification_type}.html.erb", __FILE__))
35
+ end
36
+
37
+ def generate_file_path
38
+ config[:location] + '/' + SecureRandom.hex + '.html'
39
+ end
40
+
41
+ def notification_type
42
+ raise NotImplementedError
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,8 @@
1
+ require_relative './base'
2
+ require_relative './sms'
3
+ require_relative './ios'
4
+ require_relative './android'
5
+ module NotificationsOpener
6
+ module Handler
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module NotificationsOpener
2
+ module Handler
3
+ class Ios < Base
4
+ def notification_type
5
+ 'ios'
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,39 @@
1
+ module NotificationsOpener
2
+ module Handler
3
+ class Sms < Base
4
+ attr_accessor :from,
5
+ :to,
6
+ :message
7
+
8
+ def initialize(config, env)
9
+ super(config, env)
10
+ c = build_params(env['QUERY_STRING'])
11
+ @from = c[:from]
12
+ @to = c[:to]
13
+ @message = c[:message]
14
+ end
15
+
16
+ def notification_type
17
+ 'sms'
18
+ end
19
+
20
+ private
21
+
22
+ def build_params(q)
23
+ p = { }
24
+
25
+ q.split('&').each do |kv|
26
+ kv = kv.split('=')
27
+ p[kv[0]] = kv[1]
28
+ end
29
+
30
+ {
31
+ from: p[config[:from_key_name]],
32
+ to: p[config[:to_key_name]],
33
+ message: URI.decode(p[config[:message_key_name]]),
34
+ location: config[:location]
35
+ }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -12,11 +12,13 @@ module NotificationsOpener
12
12
  # specified URL
13
13
  class Interceptor
14
14
  attr_accessor :config,
15
- :response_handler
15
+ :response_handler,
16
+ :type
16
17
 
17
- def initialize(config)
18
+ def initialize(config, type)
18
19
  @config = config
19
- @response_handler = ResponseHandler.new(config)
20
+ @type = type
21
+ @response_handler = ResponseHandler.new(config, type)
20
22
  end
21
23
 
22
24
  ##
@@ -4,39 +4,21 @@ module NotificationsOpener
4
4
  # Responsible to handle a stubbed request manually
5
5
  class ResponseHandler
6
6
  attr_accessor :config,
7
+ :type,
7
8
  :message
8
9
 
9
- def initialize(config)
10
+ def initialize(config, type)
10
11
  @config = config
12
+ @type = type
11
13
  end
12
14
 
13
15
  def call(env)
14
- message_params = get_required_params(env['QUERY_STRING'])
15
- @message = NotificationsOpener::Message.new(message_params)
16
- message.deliver
16
+ @message = Object
17
+ .const_get("NotificationsOpener::Handler::#{type.capitalize}")
18
+ .new(config, env)
17
19
 
20
+ message.deliver
18
21
  [200, {}, []]
19
22
  end
20
-
21
- private
22
-
23
- def get_required_params(q)
24
- p = get_params_from_query_string(q)
25
- {
26
- from: p[config[:from_key_name]],
27
- to: p[config[:to_key_name]],
28
- message: URI.decode(p[config[:message_key_name]]),
29
- location: config[:location]
30
- }
31
- end
32
-
33
- def get_params_from_query_string(q)
34
- p = {}
35
- q.split('&').each do |kv|
36
- kv = kv.split('=')
37
- p[kv[0]] = kv[1]
38
- end
39
- p
40
- end
41
23
  end
42
24
  end
@@ -0,0 +1,84 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="Content-Type">
4
+ <title>Notifications Opener</title>
5
+
6
+ <style type="text/css">
7
+ body {
8
+ font-family: Arial;
9
+ font-weight: 100;
10
+ }
11
+ #container {
12
+ margin: 10px auto;
13
+ position: relative;
14
+ }
15
+ #screen-head {
16
+ text-align: center;
17
+ font-weight: 100;
18
+ opacity: 0.5;
19
+ }
20
+ #phone {
21
+ width: 300px;
22
+ height: 530px;
23
+ border: 10px solid #333;
24
+ border-top-width: 50px;
25
+ border-bottom-width: 50px;
26
+ border-radius: 15px;
27
+ position: relative;
28
+ top: 10px;
29
+ margin-left: auto;
30
+ margin-right: auto;
31
+ background: #111;
32
+ }
33
+ #text-container {
34
+ color: white;
35
+ background: #111;
36
+ border-radius: 3px;
37
+ padding: 10px;
38
+ margin: 10px;
39
+ border-bottom: 1px solid #222;
40
+ }
41
+ #message-content {
42
+ font-size: 11px;
43
+ }
44
+ #title-content {
45
+ opacity: 0.5;
46
+ font-size: 13px;
47
+ }
48
+ .text-center {
49
+ text-align: center;
50
+ }
51
+ </style>
52
+ </head>
53
+ <body>
54
+ <div id="container">
55
+ <h1 id="screen-head">Android/GCM Notification</h1>
56
+ <div id="phone">
57
+ <div id="text-container">
58
+ <div id="title-content">
59
+ <%= title %>
60
+ </div><br>
61
+ <div id="message-content">
62
+ <%= message %>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ <br>
67
+ <div class="text-center">
68
+ <p><strong>Configuration Hash</strong></p>
69
+ <%= config %>
70
+ </div>
71
+ <div class="text-center">
72
+ <p><strong>Params Hash</strong></p>
73
+ <%= params %>
74
+ </div>
75
+ </div>
76
+
77
+ <script type="text/javascript">
78
+ /*! srcdoc-polyfill - v0.1.1 - 2013-03-01
79
+ * http://github.com/jugglinmike/srcdoc-polyfill/
80
+ * Copyright (c) 2013 Mike Pennisi; Licensed MIT */
81
+ (function(t,e){var c,n,o=t.srcDoc,r=!!("srcdoc"in e.createElement("iframe")),i={compliant:function(t,e){e&&t.setAttribute("srcdoc",e)},legacy:function(t,e){var c;t&&t.getAttribute&&(e?t.setAttribute("srcdoc",e):e=t.getAttribute("srcdoc"),e&&(c="javascript: window.frameElement.getAttribute('srcdoc');",t.setAttribute("src",c),t.contentWindow&&(t.contentWindow.location=c)))}},s=t.srcDoc={set:i.compliant,noConflict:function(){return t.srcDoc=o,s}};if(!r)for(s.set=i.legacy,n=e.getElementsByTagName("iframe"),c=n.length;c--;)s.set(n[c])})(this,this.document);
82
+ </script>
83
+ </body>
84
+ </html>
@@ -0,0 +1,84 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="Content-Type">
4
+ <title>Notifications Opener</title>
5
+
6
+ <style type="text/css">
7
+ body {
8
+ font-family: Arial;
9
+ font-weight: 100;
10
+ }
11
+ #screen-head {
12
+ text-align: center;
13
+ font-weight: 100;
14
+ opacity: 0.5;
15
+ }
16
+ #container {
17
+ margin: 10px auto;
18
+ position: relative;
19
+ }
20
+ #phone {
21
+ width: 300px;
22
+ height: 530px;
23
+ border: 10px solid #333;
24
+ border-top-width: 50px;
25
+ border-bottom-width: 50px;
26
+ border-radius: 15px;
27
+ position: relative;
28
+ top: 10px;
29
+ margin-left: auto;
30
+ margin-right: auto;
31
+ }
32
+ #phone-head {
33
+ color: #333;
34
+ border-bottom: 1px solid lightgray;
35
+ min-height: 30px;
36
+ background: #efefef;
37
+ padding: 10px;
38
+ font-size: 13px;
39
+ }
40
+ #text-container {
41
+ color: white;
42
+ background: #0e86fe;
43
+ border-radius: 3px;
44
+ padding: 10px;
45
+ margin: 10px;
46
+ font-size: 13px;
47
+ }
48
+ .text-center {
49
+ text-align: center;
50
+ }
51
+ </style>
52
+ </head>
53
+ <body>
54
+ <div id="container">
55
+ <h1 id="screen-head">SMS Notification</h1>
56
+ <div id="phone">
57
+ <div id="phone-head">
58
+ <span>From: <strong><%= from %></strong></span>
59
+ <br>
60
+ <span>To: <strong><%= to %></strong></span>
61
+ </div>
62
+ <div id="text-container">
63
+ <%= message %>
64
+ </div>
65
+ </div>
66
+ <br>
67
+ <div class="text-center">
68
+ <p><strong>Configuration Hash</strong></p>
69
+ <%= @config %>
70
+ </div>
71
+ <div class="text-center">
72
+ <p><strong>Params Hash</strong></p>
73
+ <%= { 'from'=>@from, 'to'=>@to, 'message'=>@message } %>
74
+ </div>
75
+ </div>
76
+
77
+ <script type="text/javascript">
78
+ /*! srcdoc-polyfill - v0.1.1 - 2013-03-01
79
+ * http://github.com/jugglinmike/srcdoc-polyfill/
80
+ * Copyright (c) 2013 Mike Pennisi; Licensed MIT */
81
+ (function(t,e){var c,n,o=t.srcDoc,r=!!("srcdoc"in e.createElement("iframe")),i={compliant:function(t,e){e&&t.setAttribute("srcdoc",e)},legacy:function(t,e){var c;t&&t.getAttribute&&(e?t.setAttribute("srcdoc",e):e=t.getAttribute("srcdoc"),e&&(c="javascript: window.frameElement.getAttribute('srcdoc');",t.setAttribute("src",c),t.contentWindow&&(t.contentWindow.location=c)))}},s=t.srcDoc={set:i.compliant,noConflict:function(){return t.srcDoc=o,s}};if(!r)for(s.set=i.legacy,n=e.getElementsByTagName("iframe"),c=n.length;c--;)s.set(n[c])})(this,this.document);
82
+ </script>
83
+ </body>
84
+ </html>
@@ -1,3 +1,3 @@
1
1
  module NotificationsOpener
2
- VERSION = '0.1.2'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency 'bundler', '~> 1.11'
23
23
  spec.add_development_dependency 'rake', '~> 10.0'
24
24
  spec.add_development_dependency 'pry'
25
+ spec.add_development_dependency 'httparty'
25
26
 
26
27
  spec.add_dependency 'webmock', '>= 1.0'
27
28
  spec.add_dependency 'rack'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: notifications_opener
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - abhisheksarka
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-08-08 00:00:00.000000000 Z
11
+ date: 2016-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: httparty
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: webmock
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -110,10 +124,16 @@ files:
110
124
  - bin/console
111
125
  - bin/setup
112
126
  - lib/notifications_opener.rb
127
+ - lib/notifications_opener/handler/android.rb
128
+ - lib/notifications_opener/handler/base.rb
129
+ - lib/notifications_opener/handler/handler.rb
130
+ - lib/notifications_opener/handler/ios.rb
131
+ - lib/notifications_opener/handler/sms.rb
113
132
  - lib/notifications_opener/interceptor.rb
114
- - lib/notifications_opener/message.html.erb
115
- - lib/notifications_opener/message.rb
116
133
  - lib/notifications_opener/response_handler.rb
134
+ - lib/notifications_opener/template/android.html.erb
135
+ - lib/notifications_opener/template/ios.html.erb
136
+ - lib/notifications_opener/template/sms.html.erb
117
137
  - lib/notifications_opener/version.rb
118
138
  - notifications_opener.gemspec
119
139
  homepage: https://github.com/abhisheksarka/notifications_opener
@@ -140,4 +160,3 @@ signing_key:
140
160
  specification_version: 4
141
161
  summary: Preview notifications/SMS in browser instead of sending.
142
162
  test_files: []
143
- has_rdoc:
@@ -1,48 +0,0 @@
1
- require 'erb'
2
- require 'launchy'
3
-
4
- module NotificationsOpener
5
- ##
6
- # This class represents builds a usable message based on the parameters
7
- class Message
8
- attr_accessor :config,
9
- :from,
10
- :to,
11
- :message,
12
- :location,
13
- :file_path
14
-
15
- def initialize(config)
16
- @config = config
17
- @from = config[:from]
18
- @to = config[:to]
19
- @message = config[:message]
20
-
21
- @location = config[:location]
22
- @file_path = generate_file_path
23
- end
24
-
25
- # #
26
- # Creates the file with the interpolated content in the specified location
27
- # Opens it up in a browser from preview
28
- def deliver
29
- File.open(file_path, 'w') { |file| file.write(rendered_content) }
30
- Launchy.open("file:///#{URI.parse(file_path)}")
31
- end
32
-
33
- # #
34
- # Uses the message template and binds the instance variable to the template
35
- # to generate the final markup
36
- def rendered_content
37
- ERB.new(template).result(binding)
38
- end
39
-
40
- def template
41
- File.read(File.expand_path('../message.html.erb', __FILE__))
42
- end
43
-
44
- def generate_file_path
45
- location + '/' + SecureRandom.hex + '.html'
46
- end
47
- end
48
- end