intercom 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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