magicbell 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []