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.
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