magicbell 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 489e38783982ec38f0044781f6bfdb156d7feb782a4bf51d624659fb35accd25
4
+ data.tar.gz: 3283ccf989b48e59448386d6471e31bd0e34fb5ef3a33e2ed9df9ec78e11545b
5
+ SHA512:
6
+ metadata.gz: 1c463bee03db65cbde34bc722a5ee368965e56342e0207426daf61337eb1f4fc56b3a394ef4133407beb641b36434085936a81669b9a4f48d78c162453aebee8
7
+ data.tar.gz: 26906f1128c18a296bd0478682e79c0151bccbf9b21e809ac07a22840e0cf9e79d52c1f1b97c54078c84386c14a9d789793494856d1d65f1630e95c66693a253
@@ -0,0 +1,20 @@
1
+ Copyright 2020 MagicBell
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,193 @@
1
+ # magicbell-rails
2
+
3
+ Convert your email notifications to an in-app notification center. This gem makes it easy to add [MagicBell's](https://magicbell.io/) notification center widget to your rails app.
4
+
5
+ <img width="415" alt="magicbell notification center widget" src="https://user-images.githubusercontent.com/1789832/28327736-f3503f44-6c01-11e7-9a72-c15023db18c6.png">
6
+
7
+ ## Installation
8
+
9
+ Add the magicbell-rails gem to your app's Gemfile
10
+
11
+ ```ruby
12
+ gem "magicbell-rails"
13
+ ```
14
+
15
+ Run
16
+
17
+ ```
18
+ bundle install
19
+ ```
20
+
21
+ Create the initializer file `config/initializers/magicbell-rails.rb` and add your MagicBell credentials there.
22
+
23
+ ```
24
+ vim config/initializers/magicbell-rails.rb
25
+ ```
26
+
27
+ ```ruby
28
+ MagicBell.configure do |config|
29
+ config.api_key = "your_magicbell_api_key"
30
+ config.api_secret = "your_magicbell_api_secret"
31
+ config.project_id = 1 # your magicbell project id
32
+ config.magic_address = "your_magicell_magic_address@ring.magicbell.io"
33
+ end
34
+ ```
35
+
36
+ If you haven't signed up for MagicBell yet and don't have credentials, visit https://magicbell.io/, sign in with your google account and create a Project.
37
+
38
+ Add MagicBell's icon to your app's interface. Our customers usually add MagicBell's icon to their app's navigation bar.
39
+
40
+ ```html
41
+ <div id="magicbell_notifications" style="display:inline-block;">
42
+ <i class="icon-magicbell"></i>
43
+ </div>
44
+ ```
45
+
46
+ Create the partial file `config/layouts/_magicbell.html.erb` and copy paste the code below
47
+
48
+ ```erb
49
+ <!-- MagicBell notification center widget -->
50
+ <script>
51
+ $('<link/>', {
52
+ rel: 'stylesheet',
53
+ type: 'text/css',
54
+ href: "<%= MagicBell.extras_css_url %>"
55
+ }).appendTo('head');
56
+ $(document).ready(function () {
57
+ // Initialize the widget after fetching its javascript
58
+ $.getScript("<%= MagicBell.widget_javascript_url %>", initializeMagicBell);
59
+ });
60
+ function initializeMagicBell() {
61
+ MagicBell.initialize({
62
+ target: document.getElementById('magicbell_notifications'),
63
+ projectId: "<%= MagicBell.project_id %>",
64
+ apiKey: "<%= MagicBell.api_key %>",
65
+ userEmail: "<%= current_user.email %>",
66
+ userKey: "<%= MagicBell.user_key(current_user.email) %>"
67
+ });
68
+ }
69
+ </script>
70
+ ```
71
+
72
+ Render the `_magicbell.html.erb` partial in your app's layout. Say, your app's layout file is `config/layouts/app.html.erb`, render the partial at the bottom. Here's an example
73
+
74
+ ```erb
75
+ <html>
76
+ <body>
77
+ <p>This is your app's layout</p>
78
+ </body>
79
+
80
+ <%= render layouts/magicbell %>
81
+ </html>
82
+ ```
83
+
84
+ Now, call the `ring_the_magicbell` method in your notification mailers. Here's an example
85
+
86
+ ```ruby
87
+ class NotificationMailer < ActionMailer::Base
88
+ # This method will bcc your email notifications to your magicbell magic address
89
+ #
90
+ # Upon receiving the bcc'ed email notifications, magicbell.io will automatically
91
+ # create in-app notications for users
92
+ ring_the_magicbell
93
+
94
+ # This is an email notification in your app
95
+ def new_comment
96
+ # ...
97
+ end
98
+
99
+ # This is another email notification in your app
100
+ def mentioned
101
+ # ...
102
+ end
103
+ end
104
+ ```
105
+
106
+ Deploy your app.
107
+
108
+ That's it! All your users now benefit from having in-app notifications.
109
+
110
+ If you've trouble adding MagicBell to your app or find yourself stuck, please don't hestitate to reach out to us at hana@magicbell.io We usually respond within 24 hours (often much lesser).
111
+
112
+ ## Advanced Features
113
+
114
+ #### ActionUrl
115
+
116
+ When a user clicks on a notification in MagicBell's widget, the widget redirects the user to the first URL the body of the email notification. We call this URL the `ActionUrl`.
117
+
118
+ If you wish to redirect users to a different URL instead, set a custom `ActionUrl` in your mailers
119
+
120
+ ```ruby
121
+ class NotificationMailer < ActionMailer::Base
122
+ ring_the_magicbell
123
+
124
+ def new_comment(comment)
125
+ # ...
126
+ magicbell_notification_action_url("https://myapp.com/comments/#{comment.id}")
127
+ # ...
128
+ end
129
+ end
130
+ ```
131
+
132
+ #### Title
133
+
134
+ We use the subject of the email notification as a notification's title. If this behaviour isn't sutiable for your app, you can set a custom title in your mailers
135
+
136
+ ```ruby
137
+ class NotificationMailer < ActionMailer::Base
138
+ ring_the_magicbell
139
+
140
+ def new_comment(comment)
141
+ # ...
142
+ magicbell_notification_title("Richard commented on your post Drive to Lake Tahoe")
143
+ # ...
144
+ end
145
+ end
146
+ ```
147
+
148
+ #### Metadata
149
+
150
+ Its possible to attach custom metadata to every notification. Say you wish to attach a comment's id to a new comment notification, here's how it can be done
151
+
152
+ ```ruby
153
+ class NotificationMailer < ActionMailer::Base
154
+ ring_the_magicbell
155
+
156
+ def new_comment(comment)
157
+ # ...
158
+ magicbell_notification_metadata(comment_id: comment.id)
159
+ # ...
160
+ end
161
+ end
162
+ ```
163
+
164
+ You can later use this metadata to customize the behaviour of MagicBell's widget.
165
+
166
+ #### Customize widget behaviour
167
+
168
+ When a user clicks on a notification in MagicBell's widget, the widget redirects the user to the notification's `ActionUrl`. If this behaviour isn't suitable for your app (if your app is a Single Page Application for example), you can customize it.
169
+
170
+ When initializing the widget, pass a `onNotificationClick` callback to customize the widget's behaviour
171
+
172
+ ```javascript
173
+ function initializeMagicBell() {
174
+ MagicBell.initialize({
175
+ target: document.getElementById('magicbell_notifications'),
176
+ projectId: "<%= MagicBell.project_id %>",
177
+ apiKey: "<%= MagicBell.api_key %>",
178
+ userEmail: <%= current_user.email %>,
179
+ userKey: "<%= MagicBell.user_key(current_user.email) %>",
180
+ onNotificationClick: function (notification) {
181
+ // openComment is a function that you've defined in your app's javascript to open
182
+ // and display a specific comment to the user
183
+ openComment(notification.meta_data.comment_id)
184
+ }
185
+ });
186
+ }
187
+ ```
188
+
189
+ If you'd like us to add more callbacks to the widget, reach out to us at hana@supportbee.com
190
+
191
+ ## Documentation
192
+
193
+ Visit our [Docs Site](https://magicbell.supportbee.com/149-magicbell-s-help-docs) for more information on MagicBell, MagicBell's widget and Advanced Features.
@@ -0,0 +1,27 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'MagicbellRuby'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ require 'bundler/gem_tasks'
18
+
19
+ require 'rake/testtask'
20
+
21
+ Rake::TestTask.new(:test) do |t|
22
+ t.libs << 'test'
23
+ t.pattern = 'test/**/*_test.rb'
24
+ t.verbose = false
25
+ end
26
+
27
+ task default: :test
@@ -0,0 +1,65 @@
1
+ require "magicbell/config"
2
+ require "magicbell/hmac"
3
+ require "magicbell/user"
4
+
5
+
6
+ module MagicBell
7
+ CLOUDFRONT_DOMAIN = "dxd8ma9fvw6e2.cloudfront.net"
8
+
9
+ class << self
10
+ def configure
11
+ yield(config)
12
+ end
13
+
14
+ def config
15
+ @config ||= Config.new
16
+ end
17
+
18
+ def reset_config
19
+ @config = nil
20
+ end
21
+
22
+ def extras_css_url
23
+ "//#{CLOUDFRONT_DOMAIN}/extras.magicbell.css"
24
+ end
25
+ alias_method :host_page_css_url, :extras_css_url # Backward compatibility
26
+
27
+ def api_host
28
+ config.api_host
29
+ end
30
+
31
+ def widget_javascript_url
32
+ "//#{CLOUDFRONT_DOMAIN}/widget.magicbell.js"
33
+ end
34
+
35
+ def api_key
36
+ config.api_key
37
+ end
38
+
39
+ def api_secret
40
+ config.api_secret
41
+ end
42
+
43
+ def project_id
44
+ config.project_id
45
+ end
46
+
47
+ def magic_address
48
+ config.magic_address
49
+ end
50
+
51
+ def project_specific_headers
52
+ {
53
+ 'X-MAGICBELL-API-KEY' => config.api_key,
54
+ 'X-MAGICBELL-API-SECRET' => config.api_secret
55
+ }
56
+ end
57
+
58
+ # Calculate HMAC for user's email
59
+ def user_key(user_email)
60
+ MagicBell::HMAC.calculate(user_email, MagicBell.api_secret)
61
+ end
62
+ end
63
+ end
64
+
65
+ require "magicbell/railtie"
@@ -0,0 +1,31 @@
1
+ require "json"
2
+
3
+ module MagicBell
4
+ module ActionMailerExtension
5
+ def self.included(mailer_class)
6
+ mailer_class.send :extend, ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def ring_the_magicbell
11
+ default bcc: MagicBell.magic_address
12
+ end
13
+ end
14
+
15
+ def magicbell_notification_action_url(action_url)
16
+ headers["X-MagicBell-Notification-ActionUrl"] = action_url
17
+ end
18
+
19
+ def magicbell_notification_metadata(metadata)
20
+ headers["X-MagicBell-Notification-Metadata"] = metadata.to_json
21
+ end
22
+
23
+ def magicbell_notification_title(title)
24
+ headers["X-MagicBell-Notification-Title"] = title
25
+ end
26
+
27
+ def magicbell_notification_skip
28
+ headers["X-MagicBell-Notification-Skip"] = true
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ module MagicBell
2
+ class Config
3
+ attr_accessor :api_key
4
+ attr_accessor :api_secret
5
+ attr_accessor :project_id
6
+ attr_accessor :magic_address
7
+ attr_accessor :api_host
8
+
9
+ def initialize
10
+ @api_host = "https://api.magicbell.io"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ require "openssl"
2
+ require "base64"
3
+
4
+ module MagicBell
5
+ module HMAC
6
+ class << self
7
+ def calculate(message)
8
+ secret = MagicBell.api_secret
9
+ digest = OpenSSL::Digest::Digest.new('sha256')
10
+ Base64.encode64(OpenSSL::HMAC.digest(digest, secret, message)).strip
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ require 'rails'
2
+ require 'yaml'
3
+
4
+ module MagicBell
5
+ module Init
6
+ module Rails
7
+ class Railtie < ::Rails::Railtie
8
+ #rake_tasks do
9
+ # load 'magicbell/tasks.rb'
10
+ #end
11
+
12
+ config.after_initialize do
13
+ MagicBell.init!({
14
+ :root => ::Rails.root.to_s,
15
+ :env => ::Rails.env,
16
+ :'config.path' => ::Rails.root.join('config', 'magicbell.yml'),
17
+ :logger => Logging::FormattedLogger.new(::Rails.logger),
18
+ :framework => :rails
19
+ })
20
+ MagicBell.load_plugins!
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ MagicBell.install_at_exit_callback
@@ -0,0 +1,10 @@
1
+ require "rails/railtie"
2
+ require "magicbell/action_mailer_extension"
3
+
4
+ module MagicBell
5
+ class Railtie < Rails::Railtie
6
+ initializer 'magicbell' do
7
+ ActionMailer::Base.send :include, MagicBell::ActionMailerExtension
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,40 @@
1
+ require 'faraday'
2
+
3
+ module MagicBell
4
+ class User
5
+
6
+ attr_accessor :email
7
+ attr_accessor :preferences
8
+
9
+ def initialize(attributes)
10
+ @attributes = attributes
11
+ @email = @attributes[:email]
12
+ @conn = Faraday.new({
13
+ url: MagicBell.api_host,
14
+ headers: MagicBell.project_specific_headers.merge(
15
+ 'X-MAGICBELL-USER-EMAIL' => @email
16
+ )
17
+ })
18
+ end
19
+
20
+ def notifications
21
+ response = @conn.get "/notifications.json"
22
+ JSON.parse(response.body)["notifications"]
23
+ end
24
+
25
+ def hmac_signature
26
+ MagicBell::HMAC.calculate @email
27
+ end
28
+
29
+ def notification_preferences
30
+ response = @conn.get "/notification_preferences.json"
31
+ JSON.parse(response.body)["notification_preferences"]
32
+ end
33
+
34
+ def notification_preferences=(preferences)
35
+ @conn.put "/notification_preferences.json",
36
+ {notification_preferences: preferences}
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module MagicBell
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: magicbell
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Hana Mohan
8
+ - Nisanth Chunduru
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2020-04-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: faraday
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rails
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '3.9'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.9'
70
+ description: Notifications like never before!
71
+ email:
72
+ - hana@magicbell.io
73
+ - nisanth@supportbee.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - MIT-LICENSE
79
+ - README.md
80
+ - Rakefile
81
+ - lib/magicbell.rb
82
+ - lib/magicbell/action_mailer_extension.rb
83
+ - lib/magicbell/config.rb
84
+ - lib/magicbell/hmac.rb
85
+ - lib/magicbell/init/rails.rb
86
+ - lib/magicbell/railtie.rb
87
+ - lib/magicbell/user.rb
88
+ - lib/magicbell/version.rb
89
+ homepage: https://magicbell.io
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubygems_version: 3.1.2
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Ruby wrapper for MagicBell.io
112
+ test_files: []