cogniteev-intercom 2.5.4
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.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +6 -0
- data/Gemfile +13 -0
- data/MIT-LICENSE +21 -0
- data/README.md +378 -0
- data/Rakefile +21 -0
- data/changes.txt +168 -0
- data/intercom.gemspec +28 -0
- data/lib/data/cacert.pem +3965 -0
- data/lib/ext/sliceable_hash.rb +16 -0
- data/lib/intercom.rb +176 -0
- data/lib/intercom/admin.rb +9 -0
- data/lib/intercom/api_operations/convert.rb +19 -0
- data/lib/intercom/api_operations/count.rb +16 -0
- data/lib/intercom/api_operations/delete.rb +15 -0
- data/lib/intercom/api_operations/find.rb +23 -0
- data/lib/intercom/api_operations/find_all.rb +33 -0
- data/lib/intercom/api_operations/list.rb +17 -0
- data/lib/intercom/api_operations/load.rb +16 -0
- data/lib/intercom/api_operations/save.rb +51 -0
- data/lib/intercom/collection_proxy.rb +71 -0
- data/lib/intercom/company.rb +29 -0
- data/lib/intercom/contact.rb +22 -0
- data/lib/intercom/conversation.rb +17 -0
- data/lib/intercom/count.rb +21 -0
- data/lib/intercom/errors.rb +61 -0
- data/lib/intercom/event.rb +11 -0
- data/lib/intercom/extended_api_operations/reply.rb +16 -0
- data/lib/intercom/extended_api_operations/tags.rb +14 -0
- data/lib/intercom/extended_api_operations/users.rb +17 -0
- data/lib/intercom/generic_handlers/base_handler.rb +22 -0
- data/lib/intercom/generic_handlers/count.rb +59 -0
- data/lib/intercom/generic_handlers/tag.rb +71 -0
- data/lib/intercom/generic_handlers/tag_find_all.rb +47 -0
- data/lib/intercom/lib/dynamic_accessors.rb +59 -0
- data/lib/intercom/lib/dynamic_accessors_on_method_missing.rb +53 -0
- data/lib/intercom/lib/flat_store.rb +31 -0
- data/lib/intercom/lib/typed_json_deserializer.rb +53 -0
- data/lib/intercom/message.rb +9 -0
- data/lib/intercom/note.rb +17 -0
- data/lib/intercom/notification.rb +20 -0
- data/lib/intercom/request.rb +166 -0
- data/lib/intercom/segment.rb +14 -0
- data/lib/intercom/subscription.rb +15 -0
- data/lib/intercom/tag.rb +23 -0
- data/lib/intercom/traits/api_resource.rb +132 -0
- data/lib/intercom/traits/dirty_tracking.rb +33 -0
- data/lib/intercom/traits/generic_handler_binding.rb +29 -0
- data/lib/intercom/traits/incrementable_attributes.rb +12 -0
- data/lib/intercom/user.rb +30 -0
- data/lib/intercom/utils.rb +62 -0
- data/lib/intercom/version.rb +3 -0
- data/spec/spec_helper.rb +308 -0
- data/spec/unit/intercom/admin_spec.rb +9 -0
- data/spec/unit/intercom/collection_proxy_spec.rb +34 -0
- data/spec/unit/intercom/company_spec.rb +23 -0
- data/spec/unit/intercom/contact_spec.rb +25 -0
- data/spec/unit/intercom/event_spec.rb +25 -0
- data/spec/unit/intercom/lib/flat_store_spec.rb +29 -0
- data/spec/unit/intercom/message_spec.rb +21 -0
- data/spec/unit/intercom/note_spec.rb +19 -0
- data/spec/unit/intercom/notification_spec.rb +68 -0
- data/spec/unit/intercom/request_spec.rb +16 -0
- data/spec/unit/intercom/subscription_spec.rb +18 -0
- data/spec/unit/intercom/tag_spec.rb +23 -0
- data/spec/unit/intercom/traits/api_resource_spec.rb +85 -0
- data/spec/unit/intercom/user_spec.rb +230 -0
- data/spec/unit/intercom_spec.rb +90 -0
- metadata +214 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Intercom
|
4
|
+
module Traits
|
5
|
+
module DirtyTracking
|
6
|
+
|
7
|
+
def reset_changed_fields!
|
8
|
+
@changed_fields = Set.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def mark_fields_as_changed!(field_names)
|
12
|
+
@changed_fields ||= Set.new
|
13
|
+
field_names.each do |attr|
|
14
|
+
@changed_fields.add(attr.to_s)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def mark_field_as_changed!(field_name)
|
19
|
+
@changed_fields ||= Set.new
|
20
|
+
@changed_fields.add(field_name.to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
def field_changed?(field_name)
|
24
|
+
@changed_fields ||= Set.new
|
25
|
+
@changed_fields.include?(field_name.to_s)
|
26
|
+
end
|
27
|
+
|
28
|
+
def instance_variables_excluding_dirty_tracking_field
|
29
|
+
instance_variables.reject{|var| var == :@changed_fields}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Intercom
|
2
|
+
module Traits
|
3
|
+
|
4
|
+
# Allows us to have one class level method missing handler across all entities
|
5
|
+
# which can dispatch to the appropriate function based on the method name
|
6
|
+
module GenericHandlerBinding
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def method_missing(method_sym, *arguments, &block)
|
10
|
+
if respond_to? :generic_tag and GenericHandlers::Tag.handles_method?(method_sym)
|
11
|
+
return generic_tag(method_sym, *arguments, block)
|
12
|
+
elsif respond_to? :generic_tag_find_all and GenericHandlers::TagFindAll.handles_method?(method_sym)
|
13
|
+
return generic_tag_find_all(method_sym, *arguments, block)
|
14
|
+
elsif respond_to? :generic_count and GenericHandlers::Count.handles_method?(method_sym)
|
15
|
+
return generic_count(method_sym, *arguments, block)
|
16
|
+
end
|
17
|
+
super
|
18
|
+
rescue Intercom::NoMethodMissingHandler
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.included(base)
|
24
|
+
base.extend(ClassMethods)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'intercom/api_operations/count'
|
2
|
+
require 'intercom/api_operations/list'
|
3
|
+
require 'intercom/api_operations/load'
|
4
|
+
require 'intercom/api_operations/find'
|
5
|
+
require 'intercom/api_operations/find_all'
|
6
|
+
require 'intercom/api_operations/save'
|
7
|
+
require 'intercom/api_operations/delete'
|
8
|
+
require 'intercom/extended_api_operations/tags'
|
9
|
+
require 'intercom/traits/incrementable_attributes'
|
10
|
+
require 'intercom/traits/api_resource'
|
11
|
+
|
12
|
+
module Intercom
|
13
|
+
class User
|
14
|
+
include ApiOperations::Count
|
15
|
+
include ApiOperations::List
|
16
|
+
include ApiOperations::Load
|
17
|
+
include ApiOperations::Find
|
18
|
+
include ApiOperations::FindAll
|
19
|
+
include ApiOperations::Save
|
20
|
+
include ApiOperations::Delete
|
21
|
+
include ExtendedApiOperations::Tags
|
22
|
+
include Traits::IncrementableAttributes
|
23
|
+
include Traits::ApiResource
|
24
|
+
|
25
|
+
def identity_vars ; [:id, :email, :user_id] ; end
|
26
|
+
def flat_store_attributes ; [:custom_attributes] ; end
|
27
|
+
def update_verb ; 'post' ; end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Intercom
|
2
|
+
module Utils
|
3
|
+
class << self
|
4
|
+
def singularize(str)
|
5
|
+
str.gsub(/ies$/, 'y').gsub(/s$/, '')
|
6
|
+
end
|
7
|
+
|
8
|
+
def pluralize(str)
|
9
|
+
return str.gsub(/y$/, 'ies') if str =~ /y$/
|
10
|
+
"#{str}s"
|
11
|
+
end
|
12
|
+
|
13
|
+
# the constantize method that exists in rails to allow for ruby 1.9 to get namespaced constants
|
14
|
+
def constantize(camel_cased_word)
|
15
|
+
names = camel_cased_word.split('::')
|
16
|
+
names.shift if names.empty? || names.first.empty?
|
17
|
+
|
18
|
+
constant = Object
|
19
|
+
names.each do |name|
|
20
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
21
|
+
end
|
22
|
+
constant
|
23
|
+
end
|
24
|
+
|
25
|
+
def resource_class_to_singular_name(resource_class)
|
26
|
+
resource_class.to_s.split('::')[-1].downcase
|
27
|
+
end
|
28
|
+
|
29
|
+
def resource_class_to_collection_name(resource_class)
|
30
|
+
Utils.pluralize(resource_class_to_singular_name(resource_class))
|
31
|
+
end
|
32
|
+
|
33
|
+
def constantize_resource_name(resource_name)
|
34
|
+
class_name = Utils.singularize(resource_name.capitalize)
|
35
|
+
define_lightweight_class(class_name) unless Intercom.const_defined?(class_name, false)
|
36
|
+
namespaced_class_name = "Intercom::#{class_name}"
|
37
|
+
constantize namespaced_class_name
|
38
|
+
end
|
39
|
+
|
40
|
+
def constantize_singular_resource_name(resource_name)
|
41
|
+
class_name = resource_name.split('_').map(&:capitalize).join
|
42
|
+
define_lightweight_class(class_name) unless Intercom.const_defined?(class_name, false)
|
43
|
+
namespaced_class_name = "Intercom::#{class_name}"
|
44
|
+
constantize namespaced_class_name
|
45
|
+
end
|
46
|
+
|
47
|
+
def define_lightweight_class(class_name)
|
48
|
+
#File.open('./intercom_ruby_dynamically_defined_classes.log', 'a') {|f| f.puts("Dynamically defining the class Intercom::#{class_name}") } #HACK
|
49
|
+
new_class_definition = Class.new(Object) do
|
50
|
+
include Traits::ApiResource
|
51
|
+
end
|
52
|
+
Intercom.const_set(class_name, new_class_definition)
|
53
|
+
end
|
54
|
+
|
55
|
+
def entity_key_from_type(type)
|
56
|
+
is_list = type.split('.')[1] == 'list'
|
57
|
+
entity_name = type.split('.')[0]
|
58
|
+
is_list ? Utils.pluralize(entity_name) : entity_name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,308 @@
|
|
1
|
+
require 'intercom'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'mocha/setup'
|
4
|
+
|
5
|
+
def test_user(email="bob@example.com")
|
6
|
+
{
|
7
|
+
"type" =>"user",
|
8
|
+
"id" =>"aaaaaaaaaaaaaaaaaaaaaaaa",
|
9
|
+
"user_id" => 'id-from-customers-app',
|
10
|
+
"email" => email,
|
11
|
+
"name" => "Joe Schmoe",
|
12
|
+
"avatar" => {"type"=>"avatar", "image_url"=>"https://graph.facebook.com/1/picture?width=24&height=24"},
|
13
|
+
"app_id" => "the-app-id",
|
14
|
+
"custom_attributes" => {"a" => "b", "b" => 2},
|
15
|
+
"companies" =>
|
16
|
+
{"type"=>"company.list",
|
17
|
+
"companies"=>
|
18
|
+
[{"type"=>"company",
|
19
|
+
"company_id"=>"123",
|
20
|
+
"id"=>"bbbbbbbbbbbbbbbbbbbbbbbb",
|
21
|
+
"app_id"=>"the-app-id",
|
22
|
+
"name"=>"Company 1",
|
23
|
+
"remote_created_at"=>1390936440,
|
24
|
+
"created_at"=>1401970114,
|
25
|
+
"updated_at"=>1401970114,
|
26
|
+
"last_request_at"=>1401970113,
|
27
|
+
"monthly_spend"=>0,
|
28
|
+
"session_count"=>0,
|
29
|
+
"user_count"=>1,
|
30
|
+
"tag_ids"=>[],
|
31
|
+
"custom_attributes"=>{"category"=>"Tech"}}]},
|
32
|
+
"session_count" => 123,
|
33
|
+
"unsubscribed_from_emails" => true,
|
34
|
+
"last_request_at" =>1401970113,
|
35
|
+
"created_at" =>1401970114,
|
36
|
+
"remote_created_at" =>1393613864,
|
37
|
+
"updated_at" =>1401970114,
|
38
|
+
"user_agent_data" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
|
39
|
+
"social_profiles" =>{"type"=>"social_profile.list",
|
40
|
+
"social_profiles" => [
|
41
|
+
{"type" => "social_profile", "name" => "twitter", "url" => "http://twitter.com/abc", "username" => "abc", "id" => nil},
|
42
|
+
{"type" => "social_profile", "name" => "twitter", "username" => "abc2", "url" => "http://twitter.com/abc2", "id" => nil},
|
43
|
+
{"type" => "social_profile", "name" => "facebook", "url" => "http://facebook.com/abc", "username" => "abc", "id" => "1234242"},
|
44
|
+
{"type" => "social_profile", "name" => "quora", "url" => "http://facebook.com/abc", "username" => "abc", "id" => "1234242"}
|
45
|
+
]},
|
46
|
+
"location_data"=>
|
47
|
+
{"type"=>"location_data",
|
48
|
+
"city_name"=> 'Dublin',
|
49
|
+
"continent_code"=> 'EU',
|
50
|
+
"country_name"=> 'Ireland',
|
51
|
+
"latitude"=> '90',
|
52
|
+
"longitude"=> '10',
|
53
|
+
"postal_code"=> 'IE',
|
54
|
+
"region_name"=> 'Europe',
|
55
|
+
"timezone"=> '+1000',
|
56
|
+
"country_code" => "IRL"}
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_messages
|
61
|
+
[test_message, test_message]
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_message
|
65
|
+
{
|
66
|
+
"created_at" => 1329837506,
|
67
|
+
"updated_at" => 1329664706,
|
68
|
+
"read" => true,
|
69
|
+
"created_by_user" => true,
|
70
|
+
"thread_id" => 5591,
|
71
|
+
"messages" => [
|
72
|
+
{
|
73
|
+
"created_at" => 1329837506,
|
74
|
+
"html" => "<p>Hey Intercom, What is up?</p>\n",
|
75
|
+
"from" => {
|
76
|
+
"email" => "bob@example.com",
|
77
|
+
"name" => "Bob",
|
78
|
+
"user_id" => "123",
|
79
|
+
"is_admin" => false
|
80
|
+
}
|
81
|
+
},
|
82
|
+
{
|
83
|
+
"created_at" => 1329664706,
|
84
|
+
"rendered_body" => "<p>Not much, you?</p>\n",
|
85
|
+
"from" => {
|
86
|
+
"name" => "Super Duper Admin",
|
87
|
+
"avatar" => {
|
88
|
+
"square_25" => "https://static.intercomcdn.com/avatars/13347/square_25/Ruairi_Profile.png?1375368166",
|
89
|
+
"square_50" => "https://static.intercomcdn.com/avatars/13347/square_50/Ruairi_Profile.png?1375368166",
|
90
|
+
"square_128" => "https://static.intercomcdn.com/avatars/13347/square_128/Ruairi_Profile.png?1375368166"
|
91
|
+
},
|
92
|
+
"is_admin" => true
|
93
|
+
}
|
94
|
+
},
|
95
|
+
{
|
96
|
+
"created_at" => 1329664806,
|
97
|
+
"rendered_body" => "<p>Not much either :(</p>\n",
|
98
|
+
"from" => {
|
99
|
+
"email" => "bob@example.com",
|
100
|
+
"name" => "Bob",
|
101
|
+
"user_id" => "123",
|
102
|
+
"is_admin" => false
|
103
|
+
}
|
104
|
+
}
|
105
|
+
]
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
def page_of_users(include_next_link= false)
|
110
|
+
{
|
111
|
+
"type"=>"user.list",
|
112
|
+
"pages"=>
|
113
|
+
{
|
114
|
+
"type"=>"pages",
|
115
|
+
"next"=> (include_next_link ? "https://api.intercom.io/users?per_page=50&page=2" : nil),
|
116
|
+
"page"=>1,
|
117
|
+
"per_page"=>50,
|
118
|
+
"total_pages"=>7
|
119
|
+
},
|
120
|
+
"users"=> [test_user("user1@example.com"), test_user("user2@example.com"), test_user("user3@example.com")],
|
121
|
+
"total_count"=>314
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_tag
|
126
|
+
{
|
127
|
+
"id" => "4f73428b5e4dfc000b000112",
|
128
|
+
"name" => "Test Tag",
|
129
|
+
"segment" => false,
|
130
|
+
"tagged_user_count" => 2
|
131
|
+
}
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_user_notification
|
135
|
+
{
|
136
|
+
"type" => "notification_event",
|
137
|
+
"id" => "notif_123456-56465-546546",
|
138
|
+
"topic" => "user.created",
|
139
|
+
"app_id" => "aaaaaa",
|
140
|
+
"data" =>
|
141
|
+
{
|
142
|
+
"type" => "notification_event_data",
|
143
|
+
"item" =>
|
144
|
+
{
|
145
|
+
"type" => "user",
|
146
|
+
"id" => "aaaaaaaaaaaaaaaaaaaaaaaa",
|
147
|
+
"user_id" => nil,
|
148
|
+
"email" => "joe@example.com",
|
149
|
+
"name" => "Joe Schmoe",
|
150
|
+
"avatar" =>
|
151
|
+
{
|
152
|
+
"type" => "avatar",
|
153
|
+
"image_url" => nil
|
154
|
+
},
|
155
|
+
"app_id" => "aaaaa",
|
156
|
+
"companies" =>
|
157
|
+
{
|
158
|
+
"type" => "company.list",
|
159
|
+
"companies" => [ ]
|
160
|
+
},
|
161
|
+
"location_data" =>
|
162
|
+
{
|
163
|
+
},
|
164
|
+
"last_request_at" => nil,
|
165
|
+
"created_at" => "1401970114",
|
166
|
+
"remote_created_at" => nil,
|
167
|
+
"updated_at" => "1401970114",
|
168
|
+
"session_count" => 0,
|
169
|
+
"social_profiles" =>
|
170
|
+
{
|
171
|
+
"type" => "social_profile.list",
|
172
|
+
"social_profiles" => [ ]
|
173
|
+
},
|
174
|
+
"unsubscribed_from_emails" => false,
|
175
|
+
"user_agent_data" => nil,
|
176
|
+
"tags" =>
|
177
|
+
{
|
178
|
+
"type" => "tag.list",
|
179
|
+
"tags" => [ ]
|
180
|
+
},
|
181
|
+
"segments" =>
|
182
|
+
{
|
183
|
+
"type" => "segment.list",
|
184
|
+
"segments" => [ ]
|
185
|
+
},
|
186
|
+
"custom_attributes" =>
|
187
|
+
{
|
188
|
+
}
|
189
|
+
}
|
190
|
+
},
|
191
|
+
"delivery_status" => nil,
|
192
|
+
"delivery_attempts" => 1,
|
193
|
+
"delivered_at" => 0,
|
194
|
+
"first_sent_at" => 1410188629,
|
195
|
+
"created_at" => 1410188628,
|
196
|
+
"links" => { },
|
197
|
+
"self" => nil
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_conversation_notification
|
202
|
+
{
|
203
|
+
"type"=>"notification_event",
|
204
|
+
"id"=>"notif_123456-56465-546546",
|
205
|
+
"topic"=>"conversation.user.created",
|
206
|
+
"app_id"=>"aaaaa",
|
207
|
+
"data"=>
|
208
|
+
{
|
209
|
+
"type"=>"notification_event_data",
|
210
|
+
"item"=>
|
211
|
+
{
|
212
|
+
"type"=>"conversation",
|
213
|
+
"id"=>"123456789",
|
214
|
+
"created_at"=>"1410335293",
|
215
|
+
"updated_at"=>"1410335293",
|
216
|
+
"user"=>
|
217
|
+
{
|
218
|
+
"type"=>"user",
|
219
|
+
"id"=>"540f1de7112d3d1d51001637",
|
220
|
+
"name"=>"Kill Bill",
|
221
|
+
"email"=>"bill@bill.bill"},
|
222
|
+
"assignee"=>
|
223
|
+
{
|
224
|
+
"type"=>"nobody_admin",
|
225
|
+
"id"=>nil
|
226
|
+
},
|
227
|
+
"conversation_message"=>
|
228
|
+
{
|
229
|
+
"type"=>"conversation_message",
|
230
|
+
"id"=>"321546",
|
231
|
+
"subject"=>"",
|
232
|
+
"body"=>"<p>An important message</p>",
|
233
|
+
"author"=>
|
234
|
+
{
|
235
|
+
"type"=>"user",
|
236
|
+
"id"=>"aaaaaaaaaaaaaaaaaaaaaa",
|
237
|
+
"name"=>"Kill Bill",
|
238
|
+
"email"=>"bill@bill.bill"},
|
239
|
+
"attachments"=>[]
|
240
|
+
},
|
241
|
+
"conversation_parts"=>
|
242
|
+
{
|
243
|
+
"type"=>"conversation_part.list",
|
244
|
+
"conversation_parts"=>[]
|
245
|
+
},
|
246
|
+
"open"=>nil,
|
247
|
+
"read"=>true,
|
248
|
+
"links"=>
|
249
|
+
{
|
250
|
+
"conversation_web"=>
|
251
|
+
"https://app.intercom.io/a/apps/aaaaaa/inbox/all/conversations/123456789"}
|
252
|
+
}
|
253
|
+
},
|
254
|
+
"delivery_status"=>nil,
|
255
|
+
"delivery_attempts"=>1,
|
256
|
+
"delivered_at"=>0,
|
257
|
+
"first_sent_at"=>1410335293,
|
258
|
+
"created_at"=>1410335293,
|
259
|
+
"links"=>{},
|
260
|
+
"self"=>nil
|
261
|
+
}
|
262
|
+
end
|
263
|
+
|
264
|
+
def test_subscription
|
265
|
+
{"request"=>
|
266
|
+
{"type"=>"notification_subscription",
|
267
|
+
"id"=>"nsub_123456789",
|
268
|
+
"created_at"=>1410368642,
|
269
|
+
"updated_at"=>1410368642,
|
270
|
+
"service_type"=>"web",
|
271
|
+
"app_id"=>"3qmk5gyg",
|
272
|
+
"url"=>
|
273
|
+
"http://example.com",
|
274
|
+
"self"=>
|
275
|
+
"https://api.intercom.io/subscriptions/nsub_123456789",
|
276
|
+
"topics"=>["user.created", "conversation.user.replied", "conversation.admin.replied"],
|
277
|
+
"active"=>true,
|
278
|
+
"metadata"=>{},
|
279
|
+
"hub_secret"=>nil,
|
280
|
+
"mode"=>"point",
|
281
|
+
"links"=>
|
282
|
+
{"sent"=>
|
283
|
+
"https://api.intercom.io/subscriptions/nsub_123456789/sent",
|
284
|
+
"retry"=>
|
285
|
+
"https://api.intercom.io/subscriptions/nsub_123456789/retry",
|
286
|
+
"errors"=>
|
287
|
+
"https://api.intercom.io/subscriptions/nsub_123456789/errors"},
|
288
|
+
"notes"=>[]}}
|
289
|
+
end
|
290
|
+
|
291
|
+
def error_on_modify_frozen
|
292
|
+
RUBY_VERSION =~ /1.8/ ? TypeError : RuntimeError
|
293
|
+
end
|
294
|
+
|
295
|
+
def capture_exception(&block)
|
296
|
+
begin
|
297
|
+
block.call
|
298
|
+
rescue => e
|
299
|
+
return e
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def unshuffleable_array(array)
|
304
|
+
def array.shuffle
|
305
|
+
self
|
306
|
+
end
|
307
|
+
array
|
308
|
+
end
|