hubspot 0.0.1

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 (73) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +149 -0
  3. data/Rakefile +38 -0
  4. data/app/helpers/hubspot_helper.rb +17 -0
  5. data/app/models/hubspot/base.rb +40 -0
  6. data/app/models/hubspot/blog.rb +35 -0
  7. data/app/models/hubspot/blogs/blog_association.rb +35 -0
  8. data/app/models/hubspot/blogs/comment.rb +5 -0
  9. data/app/models/hubspot/blogs/post.rb +12 -0
  10. data/app/models/hubspot/blogs/posts/comment.rb +23 -0
  11. data/app/models/hubspot/connection.rb +35 -0
  12. data/app/models/hubspot/event.rb +39 -0
  13. data/app/models/hubspot/keyword.rb +49 -0
  14. data/app/models/hubspot/lead.rb +26 -0
  15. data/app/models/hubspot/performable/event.rb +67 -0
  16. data/lib/hubspot.rb +8 -0
  17. data/lib/hubspot/action_controller_extensions.rb +15 -0
  18. data/lib/hubspot/engine.rb +30 -0
  19. data/lib/hubspot/version.rb +3 -0
  20. data/lib/tasks/hubspot_tasks.rake +4 -0
  21. data/test/dummy/README.rdoc +261 -0
  22. data/test/dummy/Rakefile +7 -0
  23. data/test/dummy/app/assets/javascripts/application.js +15 -0
  24. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  25. data/test/dummy/app/controllers/application_controller.rb +3 -0
  26. data/test/dummy/app/helpers/application_helper.rb +2 -0
  27. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  28. data/test/dummy/config.ru +4 -0
  29. data/test/dummy/config/application.rb +56 -0
  30. data/test/dummy/config/boot.rb +10 -0
  31. data/test/dummy/config/database.yml +25 -0
  32. data/test/dummy/config/environment.rb +5 -0
  33. data/test/dummy/config/environments/development.rb +37 -0
  34. data/test/dummy/config/environments/production.rb +67 -0
  35. data/test/dummy/config/environments/test.rb +37 -0
  36. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  37. data/test/dummy/config/initializers/inflections.rb +15 -0
  38. data/test/dummy/config/initializers/mime_types.rb +5 -0
  39. data/test/dummy/config/initializers/secret_token.rb +7 -0
  40. data/test/dummy/config/initializers/session_store.rb +8 -0
  41. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  42. data/test/dummy/config/locales/en.yml +5 -0
  43. data/test/dummy/config/routes.rb +58 -0
  44. data/test/dummy/db/test.sqlite3 +0 -0
  45. data/test/dummy/log/test.log +2056 -0
  46. data/test/dummy/public/404.html +26 -0
  47. data/test/dummy/public/422.html +26 -0
  48. data/test/dummy/public/500.html +25 -0
  49. data/test/dummy/public/favicon.ico +0 -0
  50. data/test/dummy/script/rails +6 -0
  51. data/test/fixtures/vcr_cassettes/blog-comments.yml +74 -0
  52. data/test/fixtures/vcr_cassettes/blog-find.yml +36 -0
  53. data/test/fixtures/vcr_cassettes/blog-posts.yml +75 -0
  54. data/test/fixtures/vcr_cassettes/blogs-list.yml +39 -0
  55. data/test/fixtures/vcr_cassettes/event-create.yml +36 -0
  56. data/test/fixtures/vcr_cassettes/event-record.yml +47 -0
  57. data/test/fixtures/vcr_cassettes/events-list.yml +41 -0
  58. data/test/fixtures/vcr_cassettes/keyword-create.yml +36 -0
  59. data/test/fixtures/vcr_cassettes/keywords-list.yml +385 -0
  60. data/test/fixtures/vcr_cassettes/lead-find.yml +103 -0
  61. data/test/fixtures/vcr_cassettes/lead-update.yml +239 -0
  62. data/test/fixtures/vcr_cassettes/leads-list.yml +190 -0
  63. data/test/fixtures/vcr_cassettes/post-comments.yml +72 -0
  64. data/test/fixtures/vcr_cassettes/post-find.yml +39 -0
  65. data/test/hubspot_test.rb +5 -0
  66. data/test/test_helper.rb +22 -0
  67. data/test/unit/blog_test.rb +37 -0
  68. data/test/unit/event_test.rb +21 -0
  69. data/test/unit/keyword_test.rb +22 -0
  70. data/test/unit/lead_test.rb +31 -0
  71. data/test/unit/performable_event_test.rb +22 -0
  72. data/test/unit/post_test.rb +20 -0
  73. metadata +207 -0
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Reinier de Lange
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,149 @@
1
+ = Hubspot
2
+
3
+ This gem is a Rails Engine for communicating with several Hubspot API's. Furthermore, it provides some helpers
4
+ to easily integrate Hubspot in your website. This gem only uses standard ActiveResource and Net/HTTP and has been
5
+ tested with unit tests and VCR for replaying HTTP requests.
6
+
7
+ == Requirements
8
+
9
+ Rails 3
10
+
11
+ == Installation
12
+
13
+ Add hubspot to your Gemfile:
14
+
15
+ gem 'hubspot'
16
+
17
+ == Configuration
18
+
19
+ This gem is a Rails Engine. The gem can be configured by changing the default engine configuration. The following settings
20
+ can be added to your application.rb or an initializer:
21
+
22
+ * Hubspot.config.hubspot_site = 'demo.app11.hubspot.com'
23
+ The domain of your Hubspot site, which is used in the javascript tracker code
24
+
25
+ * Hubspot.config.hubspot_access_token = 'demooooo-oooo-oooo-oooo-oooooooooooo'
26
+ The access token for authenticating to several Hubspot services
27
+
28
+ * Hubspot.config.hubspot_key = 'demo'
29
+ Your API key
30
+
31
+ * Hubspot.config.hubspot_portal_id = '62515'
32
+ Your Portal ID
33
+
34
+ * Hubspot.config.debug_http_output = false
35
+ Enables/disables logging of HTTP requests and response. False disables debugging, setting it to STDOUT enables logging to STDOUT. Of course you can specify any IO object you want.
36
+
37
+ == Usage
38
+
39
+ Currently, the gem supports the following Hubspot API's:
40
+
41
+ * Leads
42
+
43
+ See: http://developers.hubspot.com/docs/endpoints#leads-api
44
+
45
+ ** Finds
46
+
47
+ Hubspot::Lead.find :all, :params => { :search => 'test' }
48
+ Hubspot::Lead.find <GUID>
49
+
50
+ ** Updates
51
+
52
+ lead.firstName = 'Reinier'; lead.save!
53
+ lead.update_attributes(:firstName => 'Reinier')
54
+
55
+ * Blogs (including posts and comments)
56
+
57
+ See: http://developers.hubspot.com/docs/endpoints#blog-api
58
+
59
+ ** Finds
60
+ Hubspot::Blog.find :all, :params => { :max => 10 }
61
+ Hubspot::Blog.find <GUID>
62
+
63
+ ** Posts
64
+ Hubspot::Blog.find('guid').posts
65
+
66
+ *** Post comments
67
+ Hubspot::Blogs::Post.find("6ca6fdc5-a81f-44db-a63b-f56ab2636c69", :params => { :blog_guid => "0d61e4ca-e395-4c1c-8766-afaa48bf68db" }).comments
68
+
69
+ ** Comments
70
+ Hubspot::Blog.find('guid').comments
71
+
72
+ * Keywords
73
+
74
+ See: http://developers.hubspot.com/docs/endpoints#keywords-api
75
+
76
+ ** Finds
77
+
78
+ Hubspot::Keyword.find(:all, :params => { :max => 5 })
79
+ Hubspot::Keyword.find('guid')
80
+
81
+ ** Creates
82
+
83
+ Hubspot::Keyword.create!({ :keyword => { :keyword => 'key' }})
84
+ Hubspot::Keyword.create({ :keyword => { :keyword => 'key' }})
85
+
86
+ * Events
87
+
88
+ See: http://developers.hubspot.com/docs/endpoints#events-api
89
+
90
+ ** Finds
91
+
92
+ Hubspot::Event.find(:all, :params => { :max => 5 })
93
+
94
+ ** Creates
95
+
96
+ Hubspot::Event.create!(:eventType => 'new event', :description => 'test')
97
+ Hubspot::Event.create(:eventType => 'new event', :description => 'test')
98
+
99
+ * Performable events
100
+
101
+ See: http://performabledoc.hubspot.com/display/DOC/HTTP+API
102
+
103
+ ** Records
104
+
105
+ event = Hubspot::Performable::Event.new('event-12345', Date.civil(2012), nil, 'http://example.com')
106
+ event.custom_parameters = { :email => 'test@example.com' }
107
+ event.save!
108
+
109
+ Please take a look at the unit tests for examples!
110
+
111
+ == Action controller extensions
112
+
113
+ For now, there is only a convenience method for getting the current user token:
114
+
115
+ hubspot_user_token # Retrieves the user token from the Hubspot 'hubspotutk' cookie (if any)
116
+
117
+ == HubspotHelper
118
+
119
+ The HubspotHelper can be used to insert the Hubspot javascript tracker code to your website. First include the helper:
120
+
121
+ class ApplicationController < ActionController::Base
122
+ helper HubspotHelper
123
+ end
124
+
125
+ Then, you can add the javascript tracker code easily by calling the helper:
126
+
127
+ <body>
128
+ ...
129
+ <%= hubspot_javascript_tracker %>
130
+ </body>
131
+
132
+ == Acknowledgements
133
+
134
+ * Thanks go to Josh Lane from which I took some of the code of his Hubspot API implementation (https://github.com/lanej/hubspot-api)
135
+
136
+ == Note on Patches/Pull Requests
137
+
138
+ * Fork the project.
139
+ * Make your feature addition or bug fix.
140
+ * Add tests for it. This is important so I don't break it in a
141
+ future version unintentionally.
142
+ * Commit, do not mess with rakefile, version, or history.
143
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
144
+ * Send me a pull request. Bonus points for topic branches.
145
+
146
+ == Copyright
147
+
148
+ Copyright (c) 2012 Reinier de Lange. See LICENSE for details.
149
+
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Hubspot'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
28
+ require 'rake/testtask'
29
+
30
+ Rake::TestTask.new(:test) do |t|
31
+ t.libs << 'lib'
32
+ t.libs << 'test'
33
+ t.pattern = 'test/**/*_test.rb'
34
+ t.verbose = false
35
+ end
36
+
37
+
38
+ task :default => :test
@@ -0,0 +1,17 @@
1
+ module HubspotHelper
2
+
3
+ # Should be included at the bottom of any HTML page (before </body>) you want to track
4
+ def hubspot_javascript_tracker
5
+ raw <<-EOS
6
+ <!-- Start of HubSpot Logging Code -->
7
+ <script type="text/javascript" language="javascript">
8
+ var hs_portalid=#{Hubspot.config.hubspot_portal_id};
9
+ var hs_salog_version = "2.00";
10
+ var hs_ppa = "#{Hubspot.config.hubspot_site}";
11
+ document.write(unescape("%3Cscript src='" + document.location.protocol + "//" + hs_ppa + "/salog.js.aspx' type='text/javascript'%3E%3C/script%3E"));
12
+ </script>
13
+ <!-- End of HubSpot Logging Code -->
14
+ EOS
15
+ end
16
+
17
+ end
@@ -0,0 +1,40 @@
1
+ require "active_resource"
2
+
3
+ # Hubspot::Base initializes ActiveResource to use JSON and to use our own Connection class that adds authentication
4
+ # information to each request. Moreover, as Hubspot's API paths are very inconsistent, it provides the most common
5
+ # paths to object collections and members. This can be overridden if necessary
6
+ module Hubspot
7
+
8
+ class Base < ActiveResource::Base
9
+ self.format = ActiveResource::Formats::JsonFormat
10
+
11
+ # Only serialize the attributes listed in the schema. Leads can contain much more information than can be passed
12
+ # back to Hubspot, therefore we need to ensure they are not serialized on save.
13
+ def to_json(options={})
14
+ super(options.reverse_merge(:root => nil, :only => schema.keys))
15
+ end
16
+
17
+ class << self
18
+
19
+ # Use our own connection class
20
+ def connection(refresh = false)
21
+ @connection = Hubspot::Connection.new(site, format) if @connection.nil? || refresh
22
+ return @connection
23
+ end
24
+
25
+ # ==== Set paths ====
26
+
27
+ def element_path(id, prefix_options = {}, query_options = nil)
28
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
29
+ "#{prefix(prefix_options)}#{collection_name.singularize}/#{URI.escape id.to_s}.#{format.extension}#{query_string(query_options)}"
30
+ end
31
+
32
+ def collection_path(prefix_options = {}, query_options = nil)
33
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
34
+ "#{prefix(prefix_options)}list.#{format.extension}#{query_string(query_options)}"
35
+ end
36
+
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,35 @@
1
+ module Hubspot
2
+
3
+ # Finds blogs
4
+ #
5
+ # Finds:
6
+ # Hubspot::Blog.find :all, :params => { :max => 10 }
7
+ # Hubspot::Blog.find <GUID>
8
+ class Blog < Hubspot::Base
9
+ self.site = 'https://api.hubapi.com/blog/v1'
10
+
11
+ schema do
12
+ string 'guid', 'blogTitle', 'feedUrl', 'jsonUrl', 'webUrl'
13
+ end
14
+
15
+ alias_attribute :id, :guid
16
+
17
+ # Convenience methods for retrieving a blog's posts and comments
18
+
19
+ def comments(params = {})
20
+ Hubspot::Blogs::Comment.find :all, :params => params.merge(:blog_guid => guid)
21
+ end
22
+
23
+ def posts(params = {})
24
+ Hubspot::Blogs::Post.find :all, :params => params.merge(:blog_guid => guid)
25
+ end
26
+
27
+ # Explicitly set element path
28
+ def self.element_path(id, prefix_options = {}, query_options = nil)
29
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
30
+ "#{prefix(prefix_options)}#{URI.escape id.to_s}.#{format.extension}#{query_string(query_options)}"
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,35 @@
1
+ module Hubspot
2
+ module Blogs
3
+
4
+ # Define an assocation base class from which blog child associations should inherit
5
+ class BlogAssociation < Hubspot::Base
6
+ self.site = Hubspot::Blog.site
7
+
8
+ alias_attribute :id, :guid
9
+
10
+ class << self
11
+ def element_path(id, prefix_options = {}, query_options = nil)
12
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
13
+ "#{prefix(prefix_options)}#{collection_name}/#{URI.escape id.to_s}.#{format.extension}#{query_string(query_options)}"
14
+ end
15
+
16
+ def collection_path(prefix_options = {}, query_options = nil)
17
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
18
+ raise(ActiveResource::MissingPrefixParam, ":blog_guid prefix_option is missing") unless prefix_options[:blog_guid] && defined?(ActiveResource::MissingPrefixParam)
19
+ "#{prefix(prefix_options)}#{prefix_options[:blog_guid].to_s}/#{collection_name}.#{format.extension}#{query_string(query_options)}"
20
+ end
21
+
22
+ private
23
+
24
+ def prefix_parameters
25
+ @prefix_parameters ||= begin
26
+ params = super
27
+ params << :blog_guid
28
+ params
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,5 @@
1
+ module Hubspot
2
+ module Blogs
3
+ class Comment < Hubspot::Blogs::BlogAssociation; end
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ module Hubspot
2
+ module Blogs
3
+ class Post < Hubspot::Blogs::BlogAssociation
4
+
5
+ # Convenience method for retrieving a post's comments
6
+ def comments(params = {})
7
+ Hubspot::Blogs::Posts::Comment.find :all, :params => params.merge(:post_guid => guid)
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,23 @@
1
+ module Hubspot
2
+ module Blogs
3
+ module Posts
4
+
5
+ # This type of Comment will be instantiated when finding comments that belong to Posts
6
+ class Comment < Hubspot::Base
7
+ self.site = 'https://api.hubapi.com/blog/v1/posts/:post_guid'
8
+
9
+ alias_attribute :id, :guid
10
+
11
+ class << self
12
+
13
+ def collection_path(prefix_options = {}, query_options = nil)
14
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
15
+ "#{prefix(prefix_options)}comments.#{format.extension}#{query_string(query_options)}"
16
+ end
17
+
18
+ end
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ module Hubspot
2
+
3
+ class Connection < ActiveResource::Connection
4
+
5
+ # Set default parameters to send along with each request
6
+ def self.default_parameters
7
+ @default_parameters ||= { 'access_token' => Hubspot.config.hubspot_access_token, 'portalId' => Hubspot.config.hubspot_portal_id }
8
+ end
9
+
10
+ # Override to support debug output
11
+ def configure_http(http)
12
+ http.set_debug_output(Hubspot.config.debug_http_output) if Hubspot.config.debug_http_output
13
+ super
14
+ end
15
+
16
+ private
17
+
18
+ # Makes a request to the remote service and appends the default parameters
19
+ def request(method, path, *arguments)
20
+ uri = URI.parse(path)
21
+
22
+ Hubspot::Connection.default_parameters.to_param.tap do |default_parameters|
23
+ if uri.query.present?
24
+ uri.query += '&' + default_parameters
25
+ else
26
+ uri.query = default_parameters
27
+ end
28
+ end
29
+
30
+ super(method, uri.to_s, *arguments)
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,39 @@
1
+ module Hubspot
2
+
3
+ # Finds and updates events
4
+ #
5
+ # Finds:
6
+ # Hubspot::Event.find :all, :params => { :max => 5 }
7
+ #
8
+ # Creates:
9
+ # Hubspot::Event.create(:eventType => 'new event', :description => 'test', :url => 'http://dev.hubspot.com', :createDate => '1323272544000' )
10
+ class Event < Hubspot::Base
11
+ self.site = 'https://api.hubapi.com/events/v1'
12
+
13
+ schema do
14
+ string 'description', 'eventType', 'url', 'createDate'
15
+ end
16
+
17
+ class << self
18
+ def create attributes
19
+ create!(attributes) rescue false
20
+ end
21
+
22
+ def create! attributes
23
+ return Hubspot::Event.post('events', attributes).code.to_i
24
+ end
25
+
26
+ def custom_method_collection_url(method_name, options = {})
27
+ prefix_options, query_options = split_options(options)
28
+ "#{prefix(prefix_options)}#{method_name}#{query_string(query_options)}"
29
+ end
30
+
31
+ def collection_path(prefix_options = {}, query_options = nil)
32
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
33
+ "#{prefix(prefix_options)}#{collection_name}#{query_string(query_options)}"
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ end