intercom-rails 0.2.24 → 0.2.25
Sign up to get free protection for your applications and to get access to all the features.
- data/README.mdown +50 -12
- data/Rakefile +3 -11
- data/lib/intercom-rails/auto_include_filter.rb +2 -2
- data/lib/intercom-rails/config.rb +6 -6
- data/lib/intercom-rails/custom_data_helper.rb +1 -1
- data/lib/intercom-rails/import.rb +6 -6
- data/lib/intercom-rails/proxy.rb +9 -4
- data/lib/intercom-rails/proxy/company.rb +3 -3
- data/lib/intercom-rails/script_tag_helper.rb +2 -2
- data/lib/intercom-rails/version.rb +1 -1
- data/lib/rails/generators/intercom/config/config_generator.rb +4 -4
- data/lib/rails/generators/intercom/config/intercom.rb.erb +12 -12
- metadata +75 -47
- checksums.yaml +0 -7
- data/test/action_controller_test_setup.rb +0 -29
- data/test/import_test_setup.rb +0 -84
- data/test/intercom-rails/auto_include_filter_test.rb +0 -187
- data/test/intercom-rails/config_test.rb +0 -79
- data/test/intercom-rails/import_network_test.rb +0 -122
- data/test/intercom-rails/import_unit_test.rb +0 -125
- data/test/intercom-rails/proxy/company_test.rb +0 -46
- data/test/intercom-rails/proxy/user_test.rb +0 -143
- data/test/intercom-rails/script_tag_helper_test.rb +0 -30
- data/test/intercom-rails/script_tag_test.rb +0 -110
- data/test/test_setup.rb +0 -51
data/README.mdown
CHANGED
@@ -17,13 +17,13 @@ Then run:
|
|
17
17
|
bundle install
|
18
18
|
```
|
19
19
|
|
20
|
-
Take note of your `app_id` from [here](https://
|
20
|
+
Take note of your `app_id` from [here](https://app.intercom.io/apps/api_keys) and generate a config file:
|
21
21
|
|
22
22
|
```
|
23
23
|
rails generate intercom:config YOUR-APP-ID
|
24
24
|
```
|
25
25
|
|
26
|
-
To make installing Intercom as easy as possible, where possible a `<script>` tag **will be automatically inserted before the closing `</body>` tag**. For most Rails apps, **you won't need to do any extra config**. Having trouble? Check out troubleshooting below.
|
26
|
+
To make installing Intercom as easy as possible, where possible a `<script>` tag **will be automatically inserted before the closing `</body>` tag**. For most Rails apps, **you won't need to do any extra config**. Having trouble? Check out troubleshooting below.
|
27
27
|
|
28
28
|
### Disabling automatic insertion
|
29
29
|
|
@@ -55,15 +55,16 @@ If you want to use secure mode, ensure you set your API secret in `config/initia
|
|
55
55
|
config.api_secret = '123456'
|
56
56
|
```
|
57
57
|
|
58
|
-
### Custom
|
59
|
-
|
58
|
+
### User Custom data attributes
|
59
|
+
You can associate any attributes, specific to your app, with a user in Intercom.
|
60
|
+
For custom data attributes you want updated on every request set them in `config/initializers/intercom.rb`, the latest value will be sent to Intercom on each page visit.
|
60
61
|
|
61
|
-
|
62
|
+
Configure what attributes will be sent using either a:
|
62
63
|
|
63
64
|
* `Proc` which will be passed the current user object
|
64
|
-
* Or, a method which will be sent to the current user object
|
65
|
-
|
66
|
-
|
65
|
+
* Or, a method which will be sent to the current user object
|
66
|
+
|
67
|
+
e.g.
|
67
68
|
|
68
69
|
```ruby
|
69
70
|
config.user.custom_data = {
|
@@ -73,7 +74,8 @@ to generate the values of the custom data:
|
|
73
74
|
}
|
74
75
|
```
|
75
76
|
|
76
|
-
In some situations you'll want to set some custom data specific to a request.
|
77
|
+
In some situations you'll want to set some custom data attribute specific to a request.
|
78
|
+
You can do this using the `intercom_custom_data` helper available in your controllers:
|
77
79
|
|
78
80
|
```ruby
|
79
81
|
class AppsController < ActionController::Base
|
@@ -89,8 +91,29 @@ class AppsController < ActionController::Base
|
|
89
91
|
end
|
90
92
|
```
|
91
93
|
|
92
|
-
Attributes must be accessible in order to sync with intercom.
|
94
|
+
Attributes must be accessible in order to sync with intercom.
|
95
|
+
Additionally, attributes ending in "_at" will be parsed as times.
|
96
|
+
|
97
|
+
### Companies
|
98
|
+
|
99
|
+
By default, Intercom treats all Users as unrelated individuals. If for example you know users are part of a company, you can group them as such.
|
100
|
+
|
101
|
+
Read more about it here http://docs.intercom.io/configuring-Intercom/grouping-users-by-company
|
102
|
+
|
103
|
+
Basic usage is as follows - in `config/initializers/intercom.rb`
|
93
104
|
|
105
|
+
```ruby
|
106
|
+
config.company.current = Proc.new { current_company }
|
107
|
+
```
|
108
|
+
|
109
|
+
and like with Users, you can set custom attribute on companies too:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
config.company.custom_data = {
|
113
|
+
:number_of_messages => Proc.new { |app| app.messages.count },
|
114
|
+
:is_interesting => :is_interesting?
|
115
|
+
}
|
116
|
+
```
|
94
117
|
|
95
118
|
### Inbox
|
96
119
|
Intercom includes an inbox which allows a user to read their past conversations with your app, and start new conversations. It's hidden by default, you can include a link to open it by adding a line to `config/initializers/intercom.rb`:
|
@@ -117,13 +140,13 @@ You can read more about configuring the Inbox within Intercom (Config menu -> In
|
|
117
140
|
|
118
141
|
### Environments
|
119
142
|
|
120
|
-
By default Intercom will be automatically inserted in
|
143
|
+
By default Intercom will be automatically inserted in development and production Rails environments. If you would like to specify the environments in which Intercom should be inserted, you can do so as follows:
|
121
144
|
|
122
145
|
```ruby
|
123
146
|
config.enabled_environments = ["production"]
|
124
147
|
```
|
125
148
|
|
126
|
-
### Manually Inserting the Intercom Javascript
|
149
|
+
### Manually Inserting the Intercom Javascript
|
127
150
|
|
128
151
|
Some situations may require manually inserting the Intercom script tag. If you simply wish to place the Intercom javascript in a different place within the page or, on a page without a closing `</body>` tag:
|
129
152
|
|
@@ -173,6 +196,17 @@ rake intercom:import
|
|
173
196
|
|
174
197
|
Any custom data defined in `config/initializers/intercom.rb` will also be sent.
|
175
198
|
|
199
|
+
## Running tests/specs
|
200
|
+
|
201
|
+
specs should run on a clean clone of this repo, using the following commands. (developed against ruby 2.1.2 and 1.9.3)
|
202
|
+
|
203
|
+
```
|
204
|
+
bundle install
|
205
|
+
bundle exec rake spec
|
206
|
+
or
|
207
|
+
bundle exec rspec spec/
|
208
|
+
```
|
209
|
+
|
176
210
|
## Contributors
|
177
211
|
|
178
212
|
- Dr Nic Williams (@drnic) - provided a rails generator for adding the Intercom javascript tag into your layout.
|
@@ -180,4 +214,8 @@ Any custom data defined in `config/initializers/intercom.rb` will also be sent.
|
|
180
214
|
|
181
215
|
## License
|
182
216
|
|
217
|
+
intercom-rails is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
218
|
+
|
219
|
+
## Copyright
|
220
|
+
|
183
221
|
Copyright (c) 2011-2012 Intercom, Inc. All rights reserved.
|
data/Rakefile
CHANGED
@@ -8,15 +8,7 @@ end
|
|
8
8
|
|
9
9
|
Bundler::GemHelper.install_tasks
|
10
10
|
|
11
|
-
require '
|
11
|
+
require 'rspec/core/rake_task'
|
12
|
+
RSpec::Core::RakeTask.new(:spec)
|
12
13
|
|
13
|
-
|
14
|
-
test.libs << 'lib'
|
15
|
-
test.libs << 'test'
|
16
|
-
|
17
|
-
test.test_files = FileList['test/**/*_test.rb']
|
18
|
-
test.warning = false
|
19
|
-
test.verbose = true
|
20
|
-
end
|
21
|
-
|
22
|
-
task :default => :test
|
14
|
+
task :default => :spec
|
@@ -21,10 +21,10 @@ module IntercomRails
|
|
21
21
|
attr_reader :controller
|
22
22
|
|
23
23
|
def initialize(kontroller)
|
24
|
-
@controller = kontroller
|
24
|
+
@controller = kontroller
|
25
25
|
end
|
26
26
|
|
27
|
-
def include_javascript!
|
27
|
+
def include_javascript!
|
28
28
|
response.body = response.body.gsub(CLOSING_BODY_TAG, intercom_script_tag.output + '\\0')
|
29
29
|
end
|
30
30
|
|
@@ -2,7 +2,7 @@ require 'active_support/inflector'
|
|
2
2
|
|
3
3
|
module IntercomRails
|
4
4
|
|
5
|
-
class ConfigSingleton
|
5
|
+
class ConfigSingleton
|
6
6
|
|
7
7
|
def self.config_accessor(*args, &block)
|
8
8
|
config_reader(*args)
|
@@ -25,7 +25,7 @@ module IntercomRails
|
|
25
25
|
|
26
26
|
if block && (block.arity > 1)
|
27
27
|
field_name = underscored_class_name ? "#{underscored_class_name}.#{name}" : name
|
28
|
-
block.call(value, field_name)
|
28
|
+
block.call(value, field_name)
|
29
29
|
end
|
30
30
|
|
31
31
|
instance_variable_set("@#{name}", value)
|
@@ -78,7 +78,7 @@ module IntercomRails
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
config_accessor :app_id
|
83
83
|
config_accessor :api_secret
|
84
84
|
config_accessor :api_key
|
@@ -86,15 +86,15 @@ module IntercomRails
|
|
86
86
|
config_accessor :enabled_environments, &ARRAY_VALIDATOR
|
87
87
|
|
88
88
|
config_group :user do
|
89
|
-
config_accessor :current, &IS_PROC_VALIDATOR
|
89
|
+
config_accessor :current, &IS_PROC_VALIDATOR
|
90
90
|
config_accessor :model, &IS_PROC_VALIDATOR
|
91
91
|
config_accessor :company_association, &IS_PROC_VALIDATOR
|
92
92
|
config_accessor :custom_data, &CUSTOM_DATA_VALIDATOR
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
config_group :company do
|
96
96
|
config_accessor :current, &IS_PROC_VALIDATOR
|
97
|
-
config_accessor :plan, &IS_PROC_VALIDATOR
|
97
|
+
config_accessor :plan, &IS_PROC_VALIDATOR
|
98
98
|
config_accessor :monthly_spend, &IS_PROC_VALIDATOR
|
99
99
|
config_accessor :custom_data, &CUSTOM_DATA_VALIDATOR
|
100
100
|
end
|
@@ -28,7 +28,7 @@ module IntercomRails
|
|
28
28
|
@status_enabled = !!options[:status_enabled]
|
29
29
|
|
30
30
|
if uri.scheme == 'https'
|
31
|
-
http.use_ssl = true
|
31
|
+
http.use_ssl = true
|
32
32
|
http.ca_file = File.join(File.dirname(__FILE__), '../data/cacert.pem')
|
33
33
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
34
34
|
end
|
@@ -70,7 +70,7 @@ module IntercomRails
|
|
70
70
|
end
|
71
71
|
info "Successfully created #{self.total_sent - self.failed.count} users", :new_line => true
|
72
72
|
info "Failed to create #{self.failed.count} #{(self.failed.count == 1) ? 'user' : 'users'}, this is likely due to bad data" unless failed.count.zero?
|
73
|
-
|
73
|
+
|
74
74
|
self
|
75
75
|
end
|
76
76
|
|
@@ -119,15 +119,15 @@ module IntercomRails
|
|
119
119
|
User
|
120
120
|
end
|
121
121
|
rescue NameError
|
122
|
-
# Rails lazy loads constants, so this is how we check
|
122
|
+
# Rails lazy loads constants, so this is how we check
|
123
123
|
nil
|
124
124
|
end
|
125
125
|
|
126
126
|
def send_users(users)
|
127
|
-
request = Net::HTTP::Post.new(uri.request_uri)
|
127
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
128
128
|
request.basic_auth(IntercomRails.config.app_id, IntercomRails.config.api_key)
|
129
129
|
request["Content-Type"] = "application/json"
|
130
|
-
request.body = users
|
130
|
+
request.body = users
|
131
131
|
|
132
132
|
response = perform_request(request)
|
133
133
|
JSON.parse(response.body)
|
@@ -136,7 +136,7 @@ module IntercomRails
|
|
136
136
|
MAX_REQUEST_ATTEMPTS = 3
|
137
137
|
def perform_request(request, attempts = 0, error = {})
|
138
138
|
if (attempts > 0) && (attempts < MAX_REQUEST_ATTEMPTS)
|
139
|
-
sleep(0.5)
|
139
|
+
sleep(0.5)
|
140
140
|
elsif error.present?
|
141
141
|
raise error[:exception] if error[:exception]
|
142
142
|
raise exception_for_failed_response(error[:failed_response])
|
data/lib/intercom-rails/proxy.rb
CHANGED
@@ -10,7 +10,7 @@ module IntercomRails
|
|
10
10
|
|
11
11
|
def self.inherited(subclass)
|
12
12
|
subclass.class_eval do
|
13
|
-
attr_reader class_string.downcase.to_s
|
13
|
+
attr_reader class_string.downcase.to_s
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -23,6 +23,11 @@ module IntercomRails
|
|
23
23
|
|
24
24
|
def to_hash
|
25
25
|
data = standard_data.merge(custom_data)
|
26
|
+
[:id, :user_id].each do |id_key|
|
27
|
+
if(data[id_key] && !data[id_key].is_a?(Numeric))
|
28
|
+
data[id_key] = data[id_key].to_s
|
29
|
+
end
|
30
|
+
end
|
26
31
|
DateHelper.convert_dates_to_unix_timestamps(data)
|
27
32
|
end
|
28
33
|
|
@@ -76,7 +81,7 @@ module IntercomRails
|
|
76
81
|
identity_attributes << attribute_name if options[:identity]
|
77
82
|
|
78
83
|
send(:define_method, attribute_name) do
|
79
|
-
return nil unless proxied_object.respond_to?(attribute_name)
|
84
|
+
return nil unless proxied_object.respond_to?(attribute_name)
|
80
85
|
|
81
86
|
current_value = instance_variable_get(instance_variable_name)
|
82
87
|
return current_value if current_value
|
@@ -116,13 +121,13 @@ module IntercomRails
|
|
116
121
|
|
117
122
|
private
|
118
123
|
|
119
|
-
def custom_data_from_request
|
124
|
+
def custom_data_from_request
|
120
125
|
search_object.intercom_custom_data.send(type)
|
121
126
|
rescue NoMethodError
|
122
127
|
{}
|
123
128
|
end
|
124
129
|
|
125
|
-
def custom_data_from_config
|
130
|
+
def custom_data_from_config
|
126
131
|
return {} if config.custom_data.blank?
|
127
132
|
config.custom_data.reduce({}) do |custom_data, (k,v)|
|
128
133
|
custom_data.merge(k => custom_data_value_from_proc_or_symbol(v))
|
@@ -22,17 +22,17 @@ module IntercomRails
|
|
22
22
|
def self.current_in_context(search_object)
|
23
23
|
begin
|
24
24
|
if config.current.present?
|
25
|
-
company_proxy = new(search_object.instance_eval(&config.current), search_object)
|
25
|
+
company_proxy = new(search_object.instance_eval(&config.current), search_object)
|
26
26
|
return company_proxy if company_proxy.valid?
|
27
27
|
end
|
28
28
|
rescue NameError
|
29
29
|
end
|
30
30
|
|
31
|
-
raise NoCompanyFoundError
|
31
|
+
raise NoCompanyFoundError
|
32
32
|
end
|
33
33
|
|
34
34
|
def valid?
|
35
|
-
company.present? && identity_present?
|
35
|
+
company.present? && identity_present?
|
36
36
|
end
|
37
37
|
|
38
38
|
end
|
@@ -3,7 +3,7 @@ module IntercomRails
|
|
3
3
|
|
4
4
|
module ScriptTagHelper
|
5
5
|
# Generate an intercom script tag.
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# @param user_details [Hash] a customizable hash of user details
|
8
8
|
# @param options [Hash] an optional hash for secure mode and widget customisation
|
9
9
|
# @option user_details [String] :app_id Your application id
|
@@ -12,7 +12,7 @@ module IntercomRails
|
|
12
12
|
# @option user_details [String] :name the users name, _optional_ but useful for identify people in the Intercom App.
|
13
13
|
# @option user_details [Hash] :custom_data custom attributes you'd like saved for this user on Intercom.
|
14
14
|
# @option options [String] :widget a hash containing a css selector for an element which when clicked should show the Intercom widget
|
15
|
-
# @option options [String] :secret Your app secret for secure mode
|
15
|
+
# @option options [String] :secret Your app secret for secure mode
|
16
16
|
# @return [String] Intercom script tag
|
17
17
|
# @example basic example
|
18
18
|
# <%= intercom_script_tag({ :app_id => "your-app-id",
|
@@ -6,7 +6,7 @@ module Intercom
|
|
6
6
|
File.dirname(__FILE__)
|
7
7
|
end
|
8
8
|
|
9
|
-
argument :app_id, :desc => "Your Intercom app-id, which can be found here: https://
|
9
|
+
argument :app_id, :desc => "Your Intercom app-id, which can be found here: https://app.intercom.io/apps/api_keys"
|
10
10
|
argument :api_secret, :desc => "Your Intercom api-secret, used for secure mode", :optional => true
|
11
11
|
argument :api_key, :desc => "An Intercom API key, for various rake tasks", :optional => true
|
12
12
|
|
@@ -17,7 +17,7 @@ module Intercom
|
|
17
17
|
@api_key = api_key
|
18
18
|
|
19
19
|
introduction = <<-desc
|
20
|
-
Intercom will automatically insert its javascript before the closing '</body>'
|
20
|
+
Intercom will automatically insert its javascript before the closing '</body>'
|
21
21
|
tag on every page where it can find a logged-in user. Intercom by default
|
22
22
|
looks for logged-in users, in the controller, via 'current_user' and '@user'.
|
23
23
|
|
@@ -25,9 +25,9 @@ Is the logged-in user accessible via either 'current_user' or '@user'? [Yn]
|
|
25
25
|
desc
|
26
26
|
|
27
27
|
print "#{introduction.strip} "
|
28
|
-
default_ok = $stdin.gets.strip.downcase
|
28
|
+
default_ok = $stdin.gets.strip.downcase
|
29
29
|
|
30
|
-
if FALSEY_RESPONSES.include?(default_ok)
|
30
|
+
if FALSEY_RESPONSES.include?(default_ok)
|
31
31
|
custom_current_user_question = <<-desc
|
32
32
|
|
33
33
|
How do you access the logged-in user in your controllers? This can be
|
@@ -1,12 +1,12 @@
|
|
1
1
|
IntercomRails.config do |config|
|
2
2
|
# == Intercom app_id
|
3
|
-
#
|
3
|
+
#
|
4
4
|
config.app_id = ENV["INTERCOM_APP_ID"] || "<%= @app_id %>"
|
5
5
|
|
6
|
-
# == Intercom secret key
|
7
|
-
# This is required to enable secure mode, you can find it on your Intercom
|
6
|
+
# == Intercom secret key
|
7
|
+
# This is required to enable secure mode, you can find it on your Intercom
|
8
8
|
# "security" configuration page.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
<%- if @api_secret -%>
|
11
11
|
config.api_secret = "<%= @api_secret %>"
|
12
12
|
<%- else -%>
|
@@ -15,7 +15,7 @@ IntercomRails.config do |config|
|
|
15
15
|
|
16
16
|
# == Intercom API Key
|
17
17
|
# This is required for some Intercom rake tasks like importing your users;
|
18
|
-
# you can generate one at https://
|
18
|
+
# you can generate one at https://app.intercom.io/apps/api_keys.
|
19
19
|
#
|
20
20
|
<%- if @api_key -%>
|
21
21
|
config.api_key = "<%= @api_key %>"
|
@@ -37,7 +37,7 @@ IntercomRails.config do |config|
|
|
37
37
|
<%- else -%>
|
38
38
|
# config.user.current = Proc.new { current_user }
|
39
39
|
<%- end -%>
|
40
|
-
|
40
|
+
|
41
41
|
# == User model class
|
42
42
|
# The class which defines your user model
|
43
43
|
#
|
@@ -56,13 +56,13 @@ IntercomRails.config do |config|
|
|
56
56
|
# == User -> Company association
|
57
57
|
# A Proc that given a user returns an array of companies
|
58
58
|
# that the user belongs to.
|
59
|
-
#
|
59
|
+
#
|
60
60
|
# config.user.company_association = Proc.new { |user| user.companies.to_a }
|
61
61
|
# config.user.company_association = Proc.new { |user| [user.company] }
|
62
62
|
|
63
63
|
# == Current company method/variable
|
64
64
|
# The method/variable that contains the current company for the current user,
|
65
|
-
# in your controllers. 'Companies' are generic groupings of users, so this
|
65
|
+
# in your controllers. 'Companies' are generic groupings of users, so this
|
66
66
|
# could be a company, app or group.
|
67
67
|
#
|
68
68
|
# config.company.current = Proc.new { current_company }
|
@@ -79,7 +79,7 @@ IntercomRails.config do |config|
|
|
79
79
|
# == Company Plan name
|
80
80
|
# This is the name of the plan a company is currently paying (or not paying) for.
|
81
81
|
# e.g. Messaging, Free, Pro, etc.
|
82
|
-
#
|
82
|
+
#
|
83
83
|
# config.company.plan = Proc.new { |current_company| current_company.plan.name }
|
84
84
|
|
85
85
|
# == Company Monthly Spend
|
@@ -88,15 +88,15 @@ IntercomRails.config do |config|
|
|
88
88
|
#
|
89
89
|
# config.company.monthly_spend = Proc.new { |current_company| current_company.plan.price }
|
90
90
|
# config.company.monthly_spend = Proc.new { |current_company| (current_company.plan.price - current_company.subscription.discount) }
|
91
|
-
|
91
|
+
|
92
92
|
# == Inbox Style
|
93
93
|
# This enables the Intercom inbox which allows your users to read their
|
94
|
-
# past conversations with your app, as well as start new ones. It is
|
94
|
+
# past conversations with your app, as well as start new ones. It is
|
95
95
|
# disabled by default.
|
96
96
|
# * :default shows a small tab with a question mark icon on it
|
97
97
|
# * :custom attaches the inbox open event to an anchor with an
|
98
98
|
# id of #Intercom.
|
99
99
|
#
|
100
|
-
# config.inbox.style = :default
|
100
|
+
# config.inbox.style = :default
|
101
101
|
# config.inbox.style = :custom
|
102
102
|
end
|