intercom 0.0.1 → 0.0.2

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.
@@ -1,53 +1,118 @@
1
1
  require "intercom/version"
2
+ require "intercom/user_resource"
3
+ require "intercom/user"
4
+ require "intercom/message_thread"
5
+ require "intercom/impression"
2
6
  require "rest_client"
3
- require 'json'
7
+ require "json"
4
8
 
9
+ ##
10
+ # Intercom is a customer relationship management and messaging tool for web app owners
11
+ #
12
+ # This library provides ruby bindings for the Intercom API (https://api.intercom.io)
13
+ #
14
+ # == Basic Usage
15
+ # === Configure Intercom with your access credentials
16
+ # Intercom.app_id = "my_app_id"
17
+ # Intercom.secret_key = "my_secret_key"
18
+ # === Make requests to the API
19
+ # Intercom::User.find(:email => "bob@example.com")
20
+ #
5
21
  module Intercom
22
+ @hostname = "api.intercom.io"
23
+ @protocol = "https"
24
+ @app_id = nil
25
+ @secret_key = nil
26
+
27
+ ##
28
+ # Set the id of the application you want to interact with.
29
+ # When logged into your intercom console, the app_id is in the url after /apps (eg https://www.intercom.io/apps/<app-id>)
6
30
  def self.app_id=(app_id)
7
31
  @app_id = app_id
8
32
  end
9
33
 
34
+ ##
35
+ # Set the secret key to gain access to your application data.
36
+ # When logged into your intercom console, you can view/create api keys in the settings menu
10
37
  def self.secret_key=(secret_key)
11
38
  @secret_key = secret_key
12
39
  end
13
40
 
14
- def self.protocol
15
- "https"
41
+
42
+ private
43
+ def self.url_for_path(path)
44
+ raise ArgumentError, "You must set both Intercom.app_id and Intercom.secret_key to use this client. See https://github.com/intercom/intercom for usage examples." if [@app_id, @secret_key].any?(&:nil?)
45
+ "#{protocol}://#{@app_id}:#{@secret_key}@#{hostname}/v1/#{path}"
16
46
  end
17
47
 
18
- def self.hostname
19
- "api.intercom.io"
48
+ def self.post(path, payload_hash)
49
+ execute_request(:post, path, {}, {:content_type => :json, :accept => :json}, payload_hash)
50
+ end
51
+
52
+ def self.put(path, payload_hash)
53
+ execute_request(:put, path, {}, {:content_type => :json, :accept => :json}, payload_hash)
54
+ end
55
+
56
+ def self.get(path, params)
57
+ execute_request(:get, path, params)
58
+ end
59
+
60
+ def self.require_email_or_user_id(params)
61
+ raise ArgumentError.new("Expected params Hash, got #{params.class}") unless params.is_a?(Hash)
62
+ raise ArgumentError.new("Either email or user_id must be specified") unless params.keys.any? { |key| %W(email user_id).include?(key.to_s) }
20
63
  end
21
64
 
22
65
  def self.execute_request(method, path, params = {}, headers = {}, payload = nil)
23
- url = "https://#{@app_id}:#{@secret_key}@api.intercom.io/v1/#{path}"
24
- args = {
66
+ method.eql?(:get) ? require_email_or_user_id(params) : require_email_or_user_id(payload)
67
+ args =rest_client_args(method, path, params, headers, payload)
68
+ begin
69
+ response = RestClient::Request.execute(args)
70
+ JSON.parse(response.body)
71
+ rescue RestClient::ResourceNotFound
72
+ raise ResourceNotFound.new
73
+ rescue RestClient::Unauthorized
74
+ raise AuthenticationError.new
75
+ rescue RestClient::InternalServerError
76
+ raise ServerError.new
77
+ end
78
+ end
79
+
80
+ def self.rest_client_args(method, path, params, headers, payload)
81
+ url = url_for_path(path)
82
+ {
25
83
  :method => method,
26
84
  :url => url,
27
- :headers => {:params => params}.merge(headers),
85
+ :headers => {:params => params}.merge(headers).merge(:accept => :json),
28
86
  :open_timeout => 10,
29
- :payload => payload,
30
- :timeout => 30
87
+ :payload => payload.nil? ? nil : payload.to_json,
88
+ :timeout => 30,
89
+ :verify_ssl => OpenSSL::SSL::VERIFY_PEER,
90
+ :ssl_ca_file => File.join(File.dirname(__FILE__), 'data/cacert.pem')
31
91
  }
32
- RestClient::Request.execute(args)
33
92
  end
34
93
 
35
- class User
36
- def initialize(response)
37
- @response = response
38
- end
94
+ def self.protocol #nodoc
95
+ @protocol
96
+ end
39
97
 
40
- def self.find(params)
41
- response = Intercom.execute_request(:get, "users", params)
42
- User.new(response)
43
- end
98
+ def self.protocol=(override)
99
+ @protocol = override
100
+ end
44
101
 
45
- def save
46
- Intercom.execute_request(:post, "users", {}, {:content_type => :json}, {"email" => "bo@example.com"}.to_json)
47
- end
102
+ def self.hostname
103
+ @hostname
104
+ end
48
105
 
49
- def method_missing(method, *args, &block)
50
- @response[method.to_sym]
51
- end
106
+ def self.hostname=(override)
107
+ @hostname = override
108
+ end
109
+
110
+ class AuthenticationError < StandardError;
111
+ end
112
+
113
+ class ServerError < StandardError;
114
+ end
115
+
116
+ class ResourceNotFound < StandardError;
52
117
  end
53
- end
118
+ end
@@ -0,0 +1,47 @@
1
+ require 'intercom/user_resource'
2
+
3
+ module Intercom
4
+
5
+ ##
6
+ # Represents a users interaction with your app (eg page view, or using a particular feature)
7
+ class Impression < UserResource
8
+ ##
9
+ # Records that a user has interacted with your application, including the 'location' within the app they used
10
+ def self.create(params)
11
+ Impression.new(params).save
12
+ end
13
+
14
+ def save
15
+ response = Intercom.post("users/impressions", to_hash)
16
+ self.update_from_api_response(response)
17
+ end
18
+
19
+ def user_ip=(user_ip)
20
+ @attributes["user_ip"] = user_ip
21
+ end
22
+
23
+ def user_ip
24
+ @attributes["user_ip"]
25
+ end
26
+
27
+ def location=(location)
28
+ @attributes["location"] = location
29
+ end
30
+
31
+ def location
32
+ @attributes["location"]
33
+ end
34
+
35
+ def user_agent=(user_agent)
36
+ @attributes["user_agent"] = user_agent
37
+ end
38
+
39
+ def user_agent
40
+ @attributes["user_agent"]
41
+ end
42
+
43
+ def unread_messages
44
+ @attributes["unread_messages"]
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,128 @@
1
+ require 'intercom/user_resource'
2
+
3
+ module Intercom
4
+ ##
5
+ # object representing a conversation with a user
6
+ class MessageThread < UserResource
7
+ include UnixTimestampUnwrapper
8
+
9
+ ##
10
+ # Finds a particular Message identified by thread_id
11
+ def self.find(params)
12
+ requires_parameters(params, %W(thread_id))
13
+ api_response = Intercom.get("users/message_threads", params)
14
+ MessageThread.from_api(api_response)
15
+ end
16
+
17
+ ##
18
+ # Finds all Messages to show a particular user
19
+ def self.find_all(params)
20
+ response = Intercom.get("users/message_threads", params)
21
+ response.map { |message| MessageThread.from_api(message) }
22
+ end
23
+
24
+ ##
25
+ # Either creates a new message from this user to your application admins, or a comment on an existing one
26
+ def self.create(params)
27
+ requires_parameters(params, %W(body))
28
+ MessageThread.new(params).save
29
+ end
30
+
31
+ ##
32
+ # Marks a message (identified by thread_id) as read
33
+ def self.mark_as_read(params)
34
+ requires_parameters(params, %W(thread_id))
35
+ MessageThread.new({"read" => true}.merge(params)).save(:put)
36
+ end
37
+
38
+ def save(method=:post)
39
+ response = Intercom.send(method, "users/message_threads", to_hash)
40
+ self.update_from_api_response(response)
41
+ end
42
+
43
+ ##
44
+ # Set the content of the message. Supports standard markdown syntax
45
+ def body=(body)
46
+ @attributes["body"] = body
47
+ end
48
+
49
+ def body
50
+ @attributes["body"]
51
+ end
52
+
53
+ def created_at
54
+ time_at("created_at")
55
+ end
56
+
57
+ def updated_at
58
+ time_at("updated_at")
59
+ end
60
+
61
+
62
+ def thread_id=(thread_id)
63
+ @attributes["thread_id"] = thread_id
64
+ end
65
+
66
+ def thread_id
67
+ @attributes["thread_id"]
68
+ end
69
+
70
+ def read=(read)
71
+ @attributes["read"] = read
72
+ end
73
+
74
+ def read
75
+ @attributes["read"]
76
+ end
77
+
78
+ def messages
79
+ @attributes["messages"].map {|message_hash| Message.new(message_hash)}
80
+ end
81
+ end
82
+
83
+ class Message
84
+ include UnixTimestampUnwrapper
85
+
86
+ def initialize(params)
87
+ @attributes = params
88
+ end
89
+
90
+ def from
91
+ MessageAuthor.new(@attributes["from"])
92
+ end
93
+
94
+ def html
95
+ @attributes["html"]
96
+ end
97
+
98
+ def created_at
99
+ time_at("created_at")
100
+ end
101
+ end
102
+
103
+ class MessageAuthor
104
+ def initialize(params)
105
+ @attributes = params
106
+ end
107
+
108
+ def admin?
109
+ @attributes['is_admin']
110
+ end
111
+
112
+ def email
113
+ @attributes['email']
114
+ end
115
+
116
+ def user_id
117
+ @attributes['user_id']
118
+ end
119
+
120
+ def avatar_path_50
121
+ @attributes['avatar_path_50']
122
+ end
123
+
124
+ def name
125
+ @attributes['name']
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,8 @@
1
+ module Intercom
2
+ class ShallowHash < Hash #:nodoc:
3
+ def []=(key, value)
4
+ raise ArgumentError.new("custom_data does not support nested data structures (key: #{key}, value: #{value}") if value.is_a?(Array) || value.is_a?(Hash)
5
+ super(key, value)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,43 @@
1
+ require 'intercom/user_resource'
2
+
3
+ module Intercom
4
+ ##
5
+ # object representing a social profile for the User (see )http://docs.intercom.io/#SocialProfiles)
6
+ class SocialProfile < UserResource
7
+ def for_wire #:nodoc:
8
+ @attributes
9
+ end
10
+
11
+ def type
12
+ @attributes["type"]
13
+ end
14
+
15
+ def type=(type)
16
+ @attributes["type"]=type
17
+ end
18
+
19
+ def id
20
+ @attributes["id"]
21
+ end
22
+
23
+ def id=(id)
24
+ @attributes["id"]=id
25
+ end
26
+
27
+ def url
28
+ @attributes["url"]
29
+ end
30
+
31
+ def url=(url)
32
+ @attributes["url"]=url
33
+ end
34
+
35
+ def username
36
+ @attributes["username"]
37
+ end
38
+
39
+ def username=(username)
40
+ @attributes["username"]=username
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,11 @@
1
+ module Intercom
2
+ module UnixTimestampUnwrapper
3
+ def time_at(attribute_name)
4
+ Time.at(@attributes[attribute_name]) if @attributes[attribute_name]
5
+ end
6
+
7
+ def set_time_at(attribute_name, time)
8
+ @attributes[attribute_name.to_s] = time.to_i
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,133 @@
1
+ require 'intercom/user_resource'
2
+ require 'intercom/shallow_hash'
3
+ require 'intercom/social_profile'
4
+
5
+ module Intercom
6
+ ##
7
+ # Represents a user of your application on Intercom.
8
+ class User < UserResource
9
+ ##
10
+ # Fetches an Intercom::User from our API.
11
+ #
12
+ # Calls GET https://api.intercom.io/v1/users
13
+ #
14
+ # returns Intercom::User object representing the state on our servers.
15
+ #
16
+ def self.find(params)
17
+ response = Intercom.get("users", params)
18
+ User.from_api(response)
19
+ end
20
+
21
+ ##
22
+ # Creates (or updates when a user already exists for that email/user_id) a user record on your application.
23
+ #
24
+ # Calls POST https://api.intercom.io/v1/users
25
+ #
26
+ # returns Intercom::User object representing the state on our servers.
27
+ #
28
+ # This operation is idempotent.
29
+ def self.create(params)
30
+ User.new(params).save
31
+ end
32
+
33
+ ##
34
+ # instance method alternative to #create
35
+ def save
36
+ response = Intercom.post("users", to_hash)
37
+ self.update_from_api_response(response)
38
+ end
39
+
40
+ def name
41
+ @attributes["name"]
42
+ end
43
+
44
+ def name=(name)
45
+ @attributes["name"]=name
46
+ end
47
+
48
+ def last_seen_ip
49
+ @attributes["last_seen_ip"]
50
+ end
51
+
52
+ def last_seen_ip=(last_seen_ip)
53
+ @attributes["last_seen_ip"]=last_seen_ip
54
+ end
55
+
56
+ def last_seen_user_agent
57
+ @attributes["last_seen_user_agent"]
58
+ end
59
+
60
+ def last_seen_user_agent=(last_seen_user_agent)
61
+ @attributes["last_seen_user_agent"]=last_seen_user_agent
62
+ end
63
+
64
+ def relationship_score
65
+ @attributes["relationship_score"]
66
+ end
67
+
68
+ def session_count
69
+ @attributes["session_count"]
70
+ end
71
+
72
+ ##
73
+ # Get last time this User interacted with your application
74
+ def last_impression_at
75
+ time_at("last_impression_at")
76
+ end
77
+
78
+ ##
79
+ # Get Time at which this User started using your application.
80
+ def created_at
81
+ time_at("created_at")
82
+ end
83
+
84
+ ##
85
+ # Get Time at which this User started using your application.
86
+ def created_at=(time)
87
+ set_time_at("created_at", time)
88
+ end
89
+
90
+ ##
91
+ # Get array of Intercom::SocialProfile objects attached to this Intercom::User
92
+ #
93
+ # See http://docs.intercom.io/#SocialProfiles for more information
94
+ def social_profiles
95
+ @social_profiles ||= [].freeze
96
+ end
97
+
98
+ ##
99
+ # Get hash of location attributes associated with this Intercom::User
100
+ #
101
+ # Possible entries: city_name, continent_code, country_code, country_name, latitude, longitude, postal_code, region_name, timezone
102
+ #
103
+ # e.g.
104
+ #
105
+ # {"city_name"=>"Santiago", "continent_code"=>"SA", "country_code"=>"CHL", "country_name"=>"Chile",
106
+ # "latitude"=>-33.44999999999999, "longitude"=>-70.6667, "postal_code"=>"", "region_name"=>"12",
107
+ # "timezone"=>"Chile/Continental"}
108
+ def location_data
109
+ @location_data ||= {}.freeze
110
+ end
111
+
112
+ ##
113
+ # Get hash of custom attributes stored for this Intercom::User
114
+ #
115
+ # See http://docs.intercom.io/#CustomData for more information
116
+ def custom_data
117
+ @attributes["custom_data"] ||= ShallowHash.new
118
+ end
119
+
120
+ protected
121
+ def social_profiles=(social_profiles) #:nodoc:
122
+ @social_profiles = social_profiles.map { |account| SocialProfile.new(account) }.freeze
123
+ end
124
+
125
+ def location_data=(hash) #:nodoc:
126
+ @location_data = hash.freeze
127
+ end
128
+
129
+ def custom_data=(custom_data) #:nodoc:
130
+ @attributes["custom_data"] = ShallowHash.new.merge(custom_data)
131
+ end
132
+ end
133
+ end