cogniteev-intercom 2.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +13 -0
  5. data/MIT-LICENSE +21 -0
  6. data/README.md +378 -0
  7. data/Rakefile +21 -0
  8. data/changes.txt +168 -0
  9. data/intercom.gemspec +28 -0
  10. data/lib/data/cacert.pem +3965 -0
  11. data/lib/ext/sliceable_hash.rb +16 -0
  12. data/lib/intercom.rb +176 -0
  13. data/lib/intercom/admin.rb +9 -0
  14. data/lib/intercom/api_operations/convert.rb +19 -0
  15. data/lib/intercom/api_operations/count.rb +16 -0
  16. data/lib/intercom/api_operations/delete.rb +15 -0
  17. data/lib/intercom/api_operations/find.rb +23 -0
  18. data/lib/intercom/api_operations/find_all.rb +33 -0
  19. data/lib/intercom/api_operations/list.rb +17 -0
  20. data/lib/intercom/api_operations/load.rb +16 -0
  21. data/lib/intercom/api_operations/save.rb +51 -0
  22. data/lib/intercom/collection_proxy.rb +71 -0
  23. data/lib/intercom/company.rb +29 -0
  24. data/lib/intercom/contact.rb +22 -0
  25. data/lib/intercom/conversation.rb +17 -0
  26. data/lib/intercom/count.rb +21 -0
  27. data/lib/intercom/errors.rb +61 -0
  28. data/lib/intercom/event.rb +11 -0
  29. data/lib/intercom/extended_api_operations/reply.rb +16 -0
  30. data/lib/intercom/extended_api_operations/tags.rb +14 -0
  31. data/lib/intercom/extended_api_operations/users.rb +17 -0
  32. data/lib/intercom/generic_handlers/base_handler.rb +22 -0
  33. data/lib/intercom/generic_handlers/count.rb +59 -0
  34. data/lib/intercom/generic_handlers/tag.rb +71 -0
  35. data/lib/intercom/generic_handlers/tag_find_all.rb +47 -0
  36. data/lib/intercom/lib/dynamic_accessors.rb +59 -0
  37. data/lib/intercom/lib/dynamic_accessors_on_method_missing.rb +53 -0
  38. data/lib/intercom/lib/flat_store.rb +31 -0
  39. data/lib/intercom/lib/typed_json_deserializer.rb +53 -0
  40. data/lib/intercom/message.rb +9 -0
  41. data/lib/intercom/note.rb +17 -0
  42. data/lib/intercom/notification.rb +20 -0
  43. data/lib/intercom/request.rb +166 -0
  44. data/lib/intercom/segment.rb +14 -0
  45. data/lib/intercom/subscription.rb +15 -0
  46. data/lib/intercom/tag.rb +23 -0
  47. data/lib/intercom/traits/api_resource.rb +132 -0
  48. data/lib/intercom/traits/dirty_tracking.rb +33 -0
  49. data/lib/intercom/traits/generic_handler_binding.rb +29 -0
  50. data/lib/intercom/traits/incrementable_attributes.rb +12 -0
  51. data/lib/intercom/user.rb +30 -0
  52. data/lib/intercom/utils.rb +62 -0
  53. data/lib/intercom/version.rb +3 -0
  54. data/spec/spec_helper.rb +308 -0
  55. data/spec/unit/intercom/admin_spec.rb +9 -0
  56. data/spec/unit/intercom/collection_proxy_spec.rb +34 -0
  57. data/spec/unit/intercom/company_spec.rb +23 -0
  58. data/spec/unit/intercom/contact_spec.rb +25 -0
  59. data/spec/unit/intercom/event_spec.rb +25 -0
  60. data/spec/unit/intercom/lib/flat_store_spec.rb +29 -0
  61. data/spec/unit/intercom/message_spec.rb +21 -0
  62. data/spec/unit/intercom/note_spec.rb +19 -0
  63. data/spec/unit/intercom/notification_spec.rb +68 -0
  64. data/spec/unit/intercom/request_spec.rb +16 -0
  65. data/spec/unit/intercom/subscription_spec.rb +18 -0
  66. data/spec/unit/intercom/tag_spec.rb +23 -0
  67. data/spec/unit/intercom/traits/api_resource_spec.rb +85 -0
  68. data/spec/unit/intercom/user_spec.rb +230 -0
  69. data/spec/unit/intercom_spec.rb +90 -0
  70. metadata +214 -0
@@ -0,0 +1,29 @@
1
+ require 'intercom/api_operations/count'
2
+ require 'intercom/api_operations/list'
3
+ require 'intercom/api_operations/find'
4
+ require 'intercom/api_operations/find_all'
5
+ require 'intercom/api_operations/save'
6
+ require 'intercom/api_operations/load'
7
+ require 'intercom/extended_api_operations/users'
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 Company
14
+ include ApiOperations::Count
15
+ include ApiOperations::List
16
+ include ApiOperations::Find
17
+ include ApiOperations::FindAll
18
+ include ApiOperations::Save
19
+ include ApiOperations::Load
20
+ include ExtendedApiOperations::Users
21
+ include ExtendedApiOperations::Tags
22
+ include Traits::IncrementableAttributes
23
+ include Traits::ApiResource
24
+
25
+ def identity_vars ; [:id, :company_id] ; end
26
+ def flat_store_attributes ; [:custom_attributes] ; end
27
+ def update_verb ; 'post' ; end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ require 'intercom/api_operations/count'
2
+ require 'intercom/api_operations/load'
3
+ require 'intercom/api_operations/find'
4
+ require 'intercom/api_operations/find_all'
5
+ require 'intercom/api_operations/save'
6
+ require 'intercom/api_operations/convert'
7
+ require 'intercom/traits/api_resource'
8
+
9
+ module Intercom
10
+ class Contact
11
+ include ApiOperations::Load
12
+ include ApiOperations::Find
13
+ include ApiOperations::FindAll
14
+ include ApiOperations::Save
15
+ include ApiOperations::Convert
16
+ include Traits::ApiResource
17
+
18
+ def identity_vars ; [:email, :user_id] ; end
19
+ def flat_store_attributes ; [:custom_attributes] ; end
20
+ def update_verb; 'put' ; end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ require 'intercom/extended_api_operations/reply'
2
+ require 'intercom/api_operations/find_all'
3
+ require 'intercom/api_operations/find'
4
+ require 'intercom/api_operations/load'
5
+ require 'intercom/api_operations/save'
6
+ require 'intercom/traits/api_resource'
7
+
8
+ module Intercom
9
+ class Conversation
10
+ include ExtendedApiOperations::Reply
11
+ include ApiOperations::FindAll
12
+ include ApiOperations::Find
13
+ include ApiOperations::Load
14
+ include ApiOperations::Save
15
+ include Traits::ApiResource
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ require 'intercom/traits/api_resource'
2
+ require 'intercom/api_operations/find'
3
+ require 'intercom/traits/generic_handler_binding'
4
+ require 'intercom/generic_handlers/count'
5
+
6
+ module Intercom
7
+ class Count
8
+ include ApiOperations::Find
9
+ include Traits::ApiResource
10
+ include Traits::GenericHandlerBinding
11
+ include GenericHandlers::Count
12
+
13
+ def self.fetch_for_app
14
+ Intercom::Count.find({})
15
+ end
16
+
17
+ def self.fetch_broken_down_count(entity_to_count, count_context)
18
+ Intercom::Count.find(:type => entity_to_count, :count => count_context)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,61 @@
1
+ module Intercom
2
+
3
+ # Base class exception from which all public Intercom exceptions will be derived
4
+ class IntercomError < StandardError
5
+ attr_reader :http_code, :application_error_code
6
+ def initialize(message, http_code = nil, error_code = application_error_code)
7
+ @http_code = http_code
8
+ @application_error_code = error_code
9
+ super(message)
10
+ end
11
+ end
12
+
13
+ # Raised when the credentials you provide don't match a valid account on Intercom.
14
+ # Check that you have set <b>Intercom.app_id=</b> and <b>Intercom.app_api_key=</b> correctly.
15
+ class AuthenticationError < IntercomError; end
16
+
17
+ # Raised when something does wrong on within the Intercom API service.
18
+ class ServerError < IntercomError; end
19
+
20
+ # Raised when we have bad gateway errors.
21
+ class BadGatewayError < IntercomError; end
22
+
23
+ # Raised when we experience a socket read timeout
24
+ class ServiceUnavailableError < IntercomError; end
25
+
26
+ # Raised when we experience socket connect timeout
27
+ class ServiceConnectionError < IntercomError; end
28
+
29
+ # Raised when requesting resources on behalf of a user that doesn't exist in your application on Intercom.
30
+ class ResourceNotFound < IntercomError; end
31
+
32
+ # Raised when the request has a bad syntax
33
+ class BadRequestError < IntercomError; end
34
+
35
+ # Raised when you have exceed the API rate limit
36
+ class RateLimitExceeded < IntercomError; end
37
+
38
+ # Raised when the request throws an error not accounted for
39
+ class UnexpectedError < IntercomError; end
40
+
41
+ # Raised when multiple users match the query (typically duplicate email addresses)
42
+ class MultipleMatchingUsersError < IntercomError; end
43
+
44
+ # Raised when you try to call a non-setter method that does not exist on an object
45
+ class Intercom::AttributeNotSetError < IntercomError ; end
46
+
47
+ # Raised when unexpected nil returned from server
48
+ class Intercom::HttpError < IntercomError ; end
49
+
50
+ #
51
+ # Non-public errors (internal to the gem)
52
+ #
53
+
54
+ # Base class exception from which all public Intercom exceptions will be derived
55
+ class IntercomInternalError < StandardError; end
56
+
57
+ # Raised when we attempt to handle a method missing but are unsuccessful
58
+ class Intercom::NoMethodMissingHandler < IntercomInternalError; end
59
+
60
+ class Intercom::DeserializationError < IntercomInternalError; end
61
+ end
@@ -0,0 +1,11 @@
1
+ require 'intercom/api_operations/save'
2
+ require 'intercom/api_operations/find_all'
3
+ require 'intercom/traits/api_resource'
4
+
5
+ module Intercom
6
+ class Event
7
+ include ApiOperations::FindAll
8
+ include ApiOperations::Save
9
+ include Traits::ApiResource
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ require 'intercom/traits/api_resource'
2
+
3
+ module Intercom
4
+ module ExtendedApiOperations
5
+ module Reply
6
+
7
+ def reply(reply_data)
8
+ collection_name = Utils.resource_class_to_collection_name(self.class)
9
+ # TODO: For server, we should not need to merge in :conversation_id here (already in the URL)
10
+ response = Intercom.post("/#{collection_name}/#{id}/reply", reply_data.merge(:conversation_id => id))
11
+ from_response(response)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ require 'intercom/traits/api_resource'
2
+
3
+ module Intercom
4
+ module ExtendedApiOperations
5
+ module Tags
6
+
7
+ def tags
8
+ collection_name = Utils.resource_class_to_collection_name(self.class)
9
+ self.id ? Intercom::Tag.send("find_all_for_#{collection_name}", :id => id) : []
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ require 'intercom/traits/api_resource'
2
+
3
+ module Intercom
4
+ module ExtendedApiOperations
5
+ module Users
6
+
7
+ def users
8
+ collection_name = Utils.resource_class_to_collection_name(self.class)
9
+ finder_details = {}
10
+ finder_details[:url] = "/#{collection_name}/#{id}/users"
11
+ finder_details[:params] = {}
12
+ CollectionProxy.new("users", finder_details)
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ module Intercom
2
+ module GenericHandlers
3
+ class BaseHandler
4
+ attr_reader :method_sym, :arguments, :entity
5
+
6
+ def initialize(method_sym, arguments, entity)
7
+ @method_sym = method_sym
8
+ @arguments = arguments
9
+ @entity = entity
10
+ end
11
+
12
+ def method_string
13
+ method_sym.to_s
14
+ end
15
+
16
+ def raise_no_method_missing_handler
17
+ raise Intercom::NoMethodMissingHandler, "Could not handle '#{method_string}'"
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,59 @@
1
+ require 'intercom/generic_handlers/base_handler'
2
+
3
+ module Intercom
4
+ module GenericHandlers
5
+ module Count
6
+ module ClassMethods
7
+ def generic_count(method_sym, *arguments, &block)
8
+
9
+ handler_class = Class.new(GenericHandlers::BaseHandler) do
10
+ def handle
11
+ match = method_string.match(GenericHandlers::Count.count_breakdown_matcher)
12
+ if match && match[1] && match[2] && match[3].nil?
13
+ do_broken_down_count(match[1], match[2])
14
+ elsif method_string.end_with? '_count'
15
+ return do_count
16
+ else
17
+ raise_no_method_missing_handler
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def do_count
24
+ entity.fetch_for_app.send(appwide_entity_to_count)['count']
25
+ rescue Intercom::AttributeNotSetError
26
+ # Indicates this this kind of counting is not supported
27
+ raise_no_method_missing_handler
28
+ end
29
+
30
+ def do_broken_down_count(entity_to_count, count_context)
31
+ result = entity.fetch_broken_down_count(entity_to_count, count_context)
32
+ result.send(entity_to_count)[count_context]
33
+ rescue Intercom::BadRequestError => ex
34
+ # Indicates this this kind of counting is not supported
35
+ ex.application_error_code == 'parameter_invalid' ? raise_no_method_missing_handler : raise
36
+ end
37
+
38
+ def appwide_entity_to_count; method_string.gsub(/_count$/, ''); end
39
+ end
40
+
41
+ handler_class.new(method_sym, arguments, self).handle
42
+ end
43
+
44
+ end
45
+
46
+ def self.count_breakdown_matcher
47
+ /([[:alnum:]]+)_counts_for_each_([[:alnum:]]+)/
48
+ end
49
+
50
+ def self.handles_method?(method_sym)
51
+ method_sym.to_s.end_with? '_count' or method_sym.to_s.match(count_breakdown_matcher)
52
+ end
53
+
54
+ def self.included(base)
55
+ base.extend(ClassMethods)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,71 @@
1
+ require 'intercom/generic_handlers/base_handler'
2
+
3
+ module Intercom
4
+ module GenericHandlers
5
+ module Tag
6
+ module ClassMethods
7
+ def generic_tag(method_sym, *arguments, &block)
8
+
9
+ handler_class = Class.new(GenericHandlers::BaseHandler) do
10
+ def handle
11
+ if method_string.start_with? 'tag_'
12
+ return do_tagging
13
+ elsif method_string.start_with? 'untag_'
14
+ return do_untagging
15
+ else
16
+ raise_no_method_missing_handler
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def do_tagging
23
+ entity.create(:name => arguments[0], tagging_context.to_sym => tag_object_list(arguments))
24
+ end
25
+
26
+ def do_untagging
27
+ current_tag = find_tag(arguments[0])
28
+ return untag_via_save(current_tag) if current_tag
29
+ end
30
+
31
+ def find_tag(name_arg)
32
+ Intercom::Tag.find(:name => name_arg)
33
+ rescue Intercom::ResourceNotFound
34
+ return nil # Ignore if tag has since been deleted
35
+ end
36
+
37
+ def untag_via_save(current_tag)
38
+ current_tag.name = arguments[0]
39
+ current_tag.send("#{untagging_context}=", untag_object_list(arguments))
40
+ current_tag.save
41
+ end
42
+
43
+ def tag_object_list(args)
44
+ args[1].map { |id| { :id => id } }
45
+ end
46
+
47
+ def untag_object_list(args)
48
+ to_tag = tag_object_list(args)
49
+ to_tag.map { |tag_object| tag_object[:untag] = true }
50
+ to_tag
51
+ end
52
+
53
+ def tagging_context; method_string.gsub(/^tag_/, ''); end
54
+ def untagging_context; method_string.gsub(/^untag_/, ''); end
55
+ end
56
+
57
+ handler_class.new(method_sym, arguments, self).handle
58
+ end
59
+
60
+ end
61
+
62
+ def self.handles_method?(method_sym)
63
+ method_sym.to_s.start_with?('tag_') || method_sym.to_s.start_with?('untag_')
64
+ end
65
+
66
+ def self.included(base)
67
+ base.extend(ClassMethods)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,47 @@
1
+ require 'intercom/generic_handlers/base_handler'
2
+
3
+ module Intercom
4
+ module GenericHandlers
5
+ module TagFindAll
6
+ module ClassMethods
7
+ def generic_tag_find_all(method_sym, *arguments, &block)
8
+
9
+ handler_class = Class.new(GenericHandlers::BaseHandler) do
10
+ def handle
11
+ if method_string.start_with? 'find_all_for_'
12
+ return do_tag_find_all
13
+ else
14
+ raise_no_method_missing_handler
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def do_tag_find_all
21
+ Intercom::Tag.find_all(cleaned_arguments.merge(:taggable_type => Utils.singularize(context)))
22
+ end
23
+
24
+ def cleaned_arguments
25
+ cleaned_args = arguments[0]
26
+ cleaned_args[:taggable_id] = cleaned_args.delete(:id) if cleaned_args.has_key?(:id)
27
+ cleaned_args
28
+ end
29
+
30
+ def context; method_string.gsub(/^find_all_for_/, ''); end
31
+ end
32
+
33
+ handler_class.new(method_sym, arguments, self).handle
34
+ end
35
+
36
+ end
37
+
38
+ def self.handles_method?(method_sym)
39
+ method_sym.to_s.start_with? 'find_all_for_'
40
+ end
41
+
42
+ def self.included(base)
43
+ base.extend(ClassMethods)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,59 @@
1
+ module Intercom
2
+ module Lib
3
+ module DynamicAccessors
4
+
5
+ class << self
6
+
7
+ def define_accessors(attribute, value, object)
8
+ klass = object.class
9
+ if attribute.to_s.end_with?('_at') && attribute.to_s != 'update_last_request_at'
10
+ define_date_based_accessors(attribute, value, klass)
11
+ elsif object.flat_store_attribute?(attribute)
12
+ define_flat_store_based_accessors(attribute, value, klass)
13
+ else
14
+ define_standard_accessors(attribute, value, klass)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def define_flat_store_based_accessors(attribute, value, klass)
21
+ klass.class_eval %Q"
22
+ def #{attribute}=(value)
23
+ mark_field_as_changed!(:#{attribute})
24
+ @#{attribute} = Intercom::Lib::FlatStore.new(value)
25
+ end
26
+ def #{attribute}
27
+ @#{attribute}
28
+ end
29
+ "
30
+ end
31
+
32
+ def define_date_based_accessors(attribute, value, klass)
33
+ klass.class_eval %Q"
34
+ def #{attribute}=(value)
35
+ mark_field_as_changed!(:#{attribute})
36
+ @#{attribute} = value.nil? ? nil : value.to_i
37
+ end
38
+ def #{attribute}
39
+ @#{attribute}.nil? ? nil : Time.at(@#{attribute})
40
+ end
41
+ "
42
+ end
43
+
44
+ def define_standard_accessors(attribute, value, klass)
45
+ klass.class_eval %Q"
46
+ def #{attribute}=(value)
47
+ mark_field_as_changed!(:#{attribute})
48
+ @#{attribute} = value
49
+ end
50
+ def #{attribute}
51
+ @#{attribute}
52
+ end
53
+ "
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end