litmus-instant 0.1.0

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 (36) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +4 -0
  6. data/Guardfile +18 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +182 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +7 -0
  12. data/examples/Gemfile +4 -0
  13. data/examples/Gemfile.lock +32 -0
  14. data/examples/README.md +29 -0
  15. data/examples/email/test-email.html +330 -0
  16. data/examples/example_batch.rb +50 -0
  17. data/examples/example_simple.rb +35 -0
  18. data/fixtures/vcr_cassettes/Litmus_Instant/client_configurations/returns_a_Hash_of_clients_and_their_available_options.yml +419 -0
  19. data/fixtures/vcr_cassettes/Litmus_Instant/clients/returns_an_array_of_client_names.yml +86 -0
  20. data/fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_invalid_email_Hash_raise_a_request_error.yml +77 -0
  21. data/fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_valid_email_Hash_optional_end_user_id_is_relayed.yml +44 -0
  22. data/fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_valid_email_Hash_prerequest_configurations_is_relayed.yml +55 -0
  23. data/fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_valid_email_Hash_response_.yml +81 -0
  24. data/fixtures/vcr_cassettes/Litmus_Instant/create_email/unauthenticated_raises_an_authentication_error.yml +41 -0
  25. data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/raises_NotFound_for_an_expired_email_guid.yml +1668 -0
  26. data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/raises_RequestError_for_an_invalid_client.yml +79 -0
  27. data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/raises_RequestError_for_an_invalid_email_guid.yml +39 -0
  28. data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/returns_a_Hash_of_the_image_types.yml +85 -0
  29. data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/supports_optional_capture_configuration.yml +121 -0
  30. data/fixtures/vcr_cassettes/Litmus_Instant/prefetch_previews/raises_RequestError_for_an_invalid_email_guid.yml +39 -0
  31. data/fixtures/vcr_cassettes/Litmus_Instant/prefetch_previews/raises_RequestError_if_any_invalid_configurations_are_present.yml +79 -0
  32. data/fixtures/vcr_cassettes/Litmus_Instant/prefetch_previews/responds_with_an_array_of_the_requested_configurations.yml +88 -0
  33. data/lib/litmus/instant.rb +216 -0
  34. data/lib/litmus/instant/version.rb +5 -0
  35. data/litmus-instant.gemspec +39 -0
  36. metadata +194 -0
@@ -0,0 +1,88 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://<API_KEY>:@instant-api.litmus.com/v1/emails
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"plain_text":"Hej världen! Kärlek, den svenska kocken."}'
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Server:
20
+ - nginx
21
+ Date:
22
+ - Tue, 06 Oct 2015 10:40:42 GMT
23
+ Content-Type:
24
+ - application/json;charset=utf-8
25
+ Content-Length:
26
+ - '58'
27
+ Connection:
28
+ - keep-alive
29
+ Strict-Transport-Security:
30
+ - max-age=3600; includeSubdomains; preload
31
+ X-Frame-Options:
32
+ - DENY
33
+ X-Content-Type-Options:
34
+ - nosniff
35
+ body:
36
+ encoding: UTF-8
37
+ string: |-
38
+ {
39
+ "email_guid": "6c8862e2-b10d-4753-85d8-340c91c0b071"
40
+ }
41
+ http_version:
42
+ recorded_at: Tue, 06 Oct 2015 10:40:46 GMT
43
+ - request:
44
+ method: post
45
+ uri: https://instant-api.litmus.com/v1/emails/6c8862e2-b10d-4753-85d8-340c91c0b071/previews/prefetch
46
+ body:
47
+ encoding: UTF-8
48
+ string: '{"configurations":[{"client":"OL2010","images":"allowed"},{"client":"IPAD","orientation":"vertical"}]}'
49
+ headers:
50
+ Content-Type:
51
+ - application/json
52
+ Accept:
53
+ - application/json
54
+ response:
55
+ status:
56
+ code: 202
57
+ message: Accepted
58
+ headers:
59
+ Server:
60
+ - nginx
61
+ Date:
62
+ - Tue, 06 Oct 2015 10:40:43 GMT
63
+ Content-Type:
64
+ - application/json;charset=utf-8
65
+ Content-Length:
66
+ - '222'
67
+ Connection:
68
+ - keep-alive
69
+ body:
70
+ encoding: UTF-8
71
+ string: |-
72
+ {
73
+ "configurations": [
74
+ {
75
+ "orientation": "vertical",
76
+ "images": "allowed",
77
+ "client": "OL2010"
78
+ },
79
+ {
80
+ "orientation": "vertical",
81
+ "images": "allowed",
82
+ "client": "IPAD"
83
+ }
84
+ ]
85
+ }
86
+ http_version:
87
+ recorded_at: Tue, 06 Oct 2015 10:40:46 GMT
88
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,216 @@
1
+ require "litmus/instant/version"
2
+ require "httparty"
3
+ require "uri"
4
+ require "cgi"
5
+
6
+ module Litmus
7
+ module Instant
8
+ include HTTParty
9
+
10
+ base_uri "https://instant-api.litmus.com/v1"
11
+
12
+ headers "Content-Type" => "application/json"
13
+ headers "Accept" => "application/json"
14
+
15
+ class Error < StandardError; end
16
+ class ApiError < Error; end
17
+ class RequestError < ApiError; end
18
+ class AuthenticationError < ApiError; end
19
+ class ServiceError < ApiError; end
20
+ class TimeoutError < ApiError; end
21
+ class NotFound < ApiError; end
22
+ class NetworkError < Error; end
23
+
24
+ class << self
25
+ # HTTParty doesn't favour exceptions, we do, so we wrap its methods to
26
+ # give us what we want
27
+ %i{get post patch put delete move copy head options}.each do |method|
28
+ alias_method :"#{method}_without_raise", method
29
+
30
+ define_method method do |*args|
31
+ begin
32
+ response = send(:"#{method}_without_raise", *args)
33
+ rescue SocketError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
34
+ EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
35
+ Net::ProtocolError => e
36
+ raise NetworkError, e.message
37
+ rescue HTTParty::Error
38
+ raise Error, e.message
39
+ end
40
+ raise_on_failure(response)
41
+ end
42
+ end
43
+ end
44
+
45
+ # Get or set your Instant API key
46
+ # @return [String]
47
+ def self.api_key(key=nil)
48
+ if key
49
+ @key = key
50
+ self.basic_auth key, ""
51
+ end
52
+ @key
53
+ end
54
+ singleton_class.send(:alias_method, :api_key=, :api_key)
55
+
56
+ # Describe an email’s content and metadata and, in exchange, receive an
57
+ # +email_guid+ required to capture previews of it
58
+ #
59
+ # We intend these objects to be treated as lightweight. Once uploaded,
60
+ # emails can't be modified. Obtain a new +email_guid+ each time changes need
61
+ # to be reflected.
62
+ #
63
+ # The uploaded email has a limited lifespan. As a result, a new +email_guid+
64
+ # should be obtained before requesting new previews if more than a day has
65
+ # passed since the last upload.
66
+ #
67
+ # At least one of +:html_text+, +:plain_text+, +:raw_source+ must be
68
+ # provided.
69
+ #
70
+ # @param [Hash] email
71
+ # @option email [String] :html_text
72
+ # @option email [String] :plain_text
73
+ # @option email [String] :subject
74
+ # @option email [String] :from_address
75
+ # @option email [String] :from_display_name
76
+ # @option email [String] :raw_source
77
+ # This field provides an alternative approach to defining the email and
78
+ # so is only valid in the absence of all the fields above
79
+ # @option email [String] :end_user_id A unique identifier for your end
80
+ # users. When provided, we use this to partition your usage data.
81
+ # See https://litmus.com/partners/api/documentation/instant/03-identifying-end-users/
82
+ # @option email [Array<Hash>] :configurations
83
+ # An array of capture capture configuration hashes
84
+ # This allows pre-requesting previews that should be captured as soon as
85
+ # possible. This can be a useful performance optimisation.
86
+ # See +.prefetch_previews+ for further detail on format.
87
+ #
88
+ # @return [Hash] the response containing the +email_guid+ and also
89
+ # confirmation of +end_user_id+ and +configurations+ if provided
90
+ def self.create_email(email)
91
+ post("/emails", body: email.to_json)
92
+ end
93
+
94
+ # List supported email clients
95
+ # @return [Array<String>] array of email client names
96
+ def self.clients
97
+ get "/clients"
98
+ end
99
+
100
+ # List supported email client configurations
101
+ # @return [Hash] hash keyed by email client name, values are a Hash with the
102
+ # the keys +orientation_options+ and +images_options+
103
+ def self.client_configurations
104
+ get "/clients/configurations"
105
+ end
106
+
107
+ # Request a preview
108
+ #
109
+ # This triggers the capture of a preview. The method blocks until capture
110
+ # completes. The response contains URLs for each of the image sizes
111
+ # available. A further request will be needed to obtain actual image data
112
+ # from one of the provided URLs.
113
+ #
114
+ # @param email_guid [String]
115
+ # @param client [String]
116
+ # @param options [Hash]
117
+ # @option options [String] :images +allowed+ (default) or +blocked+
118
+ # @option options [String] :orientation +horizontal+ or +vertical+ (default)
119
+ #
120
+ # @return [Hash] a hash mapping the available capture sizes to their
121
+ # corresponding URLs
122
+ def self.get_preview(email_guid, client, options = {})
123
+ query = URI.encode_www_form(options)
124
+ get "/emails/#{email_guid}/previews/#{client}?#{query}"
125
+ end
126
+
127
+ # Pre-request a set of previews before download
128
+ #
129
+ # This method is provided as an optional performance enhancement, typically
130
+ # useful before embedding a set of previews within a browser, where
131
+ # connection limits might otherwise delay the start of capture of some
132
+ # previews.
133
+ #
134
+ # The method does not block while capture occurs, a response is returned
135
+ # immediately.
136
+ #
137
+ # Note that should capture failure occur for a preview, it will only be
138
+ # discovered when the preview is later requested. Request errors, for
139
+ # instance attempting to prefetch an invalid client, will result raise
140
+ # normally howver.
141
+ #
142
+ # @param email_guid [String]
143
+ # @param configurations [Array<Hash>]An array of capture capture configurations
144
+ # Each configuration Hash must have a +:client+ key, and optional
145
+ # +:orientation+ and +images+ keys
146
+ #
147
+ # @return [Hash] confirmation of the configurations being captured
148
+ def self.prefetch_previews(email_guid, configurations)
149
+ post "/emails/#{email_guid}/previews/prefetch", body: { configurations: configurations }.to_json
150
+ end
151
+
152
+ # Construct a preview image URL ready for download
153
+ #
154
+ # The generated URLs can be embedded directly within a client application,
155
+ # for instance with the +src+ tag of an HTML +img+ tag.
156
+ #
157
+ # This is also useful for downloading a capture in a single step, rather
158
+ # than calling +.get_preview+ then making a follow up request to retrieve
159
+ # the image data.
160
+ #
161
+ # @param [String] email_guid
162
+ # @param [String] client
163
+ # @param [Hash] options
164
+ # @option options [String] :capture_size +full+ (default), +thumb+ or +thumb450+
165
+ # @option options [String] :images +allowed+ (default) or +blocked+
166
+ # @option options [String] :orientation +horizontal+ or +vertical+ (default)
167
+ # @option options [Boolean] :fallback by default errors during capture
168
+ # redirect to a fallback image, setting this to +false+ will mean that
169
+ # GETs to the resulting URL will receive HTTP error responses instead
170
+ # @option options [String] :fallback_url a custom fallback image to display
171
+ # in case of errors. This must be an absolute URL and have a recognizable
172
+ # image extension. Query parameters are not supported. The image should be
173
+ # accessible publicly without the need for authentication.
174
+ #
175
+ # @return [String] the preview URL, domain sharded by the client name
176
+ def self.preview_image_url(email_guid, client, options = {})
177
+ # We'd use Ruby 2.x keyword args here, but it's more useful to preserve
178
+ # compatibility for anyone stuck with ruby < 2.x
179
+ capture_size = options.delete(:capture_size) || "full"
180
+
181
+ if options.keys.length > 0
182
+ if options[:fallback_url]
183
+ options[:fallback_url] = CGI.escape(options[:fallback_url])
184
+ end
185
+ query = URI.encode_www_form(options)
186
+ "#{sharded_base_uri(client)}/emails/#{email_guid}/previews/#{client}/#{capture_size}?#{query}"
187
+ else
188
+ "#{sharded_base_uri(client)}/emails/#{email_guid}/previews/#{client}/#{capture_size}"
189
+ end
190
+ end
191
+
192
+ private
193
+
194
+ # This avoids browser per domain connection limits
195
+ def self.sharded_base_uri(client)
196
+ base_uri.gsub("://","://#{client}.")
197
+ end
198
+
199
+ def self.raise_on_failure(response)
200
+ unless response.success?
201
+ message = response["description"] || ""
202
+
203
+ raise AuthenticationError.new(message) if response.code == 401
204
+ raise RequestError.new(message) if response.code == 400
205
+ raise NotFound.new(message) if response.code == 404
206
+ raise TimeoutError.new(message) if response.code == 504
207
+ raise ServiceError.new(message) if response.code == 500
208
+
209
+ # For all other errors
210
+ raise ApiError.new(message)
211
+ end
212
+
213
+ response
214
+ end
215
+ end
216
+ end
@@ -0,0 +1,5 @@
1
+ module Litmus
2
+ module Instant
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "litmus/instant/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "litmus-instant"
8
+ spec.version = Litmus::Instant::VERSION
9
+ spec.authors = ["Rahim Packir Saibo"]
10
+ spec.email = ["rahim@litmus.com"]
11
+
12
+ spec.summary = %q{Ruby client library for Litmus Instant API}
13
+ spec.description = %q{Ruby client library for Litmus Instant API, provides the simplest way to capture instant email previews in real clients from Ruby.}
14
+ spec.homepage = "https://github.com/litmus/instant-api-ruby"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ if spec.respond_to?(:metadata)
20
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_dependency "httparty", "~> 0.13.5"
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.10"
33
+ spec.add_development_dependency "rake", "~> 10.0"
34
+ spec.add_development_dependency "rspec"
35
+ spec.add_development_dependency "guard-rspec"
36
+ spec.add_development_dependency "webmock"
37
+ spec.add_development_dependency "vcr"
38
+ spec.add_development_dependency "rack"
39
+ end
metadata ADDED
@@ -0,0 +1,194 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: litmus-instant
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Rahim Packir Saibo
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-03-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.13.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.13.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: webmock
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: vcr
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rack
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: Ruby client library for Litmus Instant API, provides the simplest way
126
+ to capture instant email previews in real clients from Ruby.
127
+ email:
128
+ - rahim@litmus.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - ".rspec"
135
+ - ".ruby-version"
136
+ - ".travis.yml"
137
+ - Gemfile
138
+ - Guardfile
139
+ - LICENSE.txt
140
+ - README.md
141
+ - Rakefile
142
+ - bin/console
143
+ - bin/setup
144
+ - examples/.ruby-version
145
+ - examples/Gemfile
146
+ - examples/Gemfile.lock
147
+ - examples/README.md
148
+ - examples/email/test-email.html
149
+ - examples/example_batch.rb
150
+ - examples/example_simple.rb
151
+ - fixtures/vcr_cassettes/Litmus_Instant/client_configurations/returns_a_Hash_of_clients_and_their_available_options.yml
152
+ - fixtures/vcr_cassettes/Litmus_Instant/clients/returns_an_array_of_client_names.yml
153
+ - fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_invalid_email_Hash_raise_a_request_error.yml
154
+ - fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_valid_email_Hash_optional_end_user_id_is_relayed.yml
155
+ - fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_valid_email_Hash_prerequest_configurations_is_relayed.yml
156
+ - fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_valid_email_Hash_response_.yml
157
+ - fixtures/vcr_cassettes/Litmus_Instant/create_email/unauthenticated_raises_an_authentication_error.yml
158
+ - fixtures/vcr_cassettes/Litmus_Instant/get_preview/raises_NotFound_for_an_expired_email_guid.yml
159
+ - fixtures/vcr_cassettes/Litmus_Instant/get_preview/raises_RequestError_for_an_invalid_client.yml
160
+ - fixtures/vcr_cassettes/Litmus_Instant/get_preview/raises_RequestError_for_an_invalid_email_guid.yml
161
+ - fixtures/vcr_cassettes/Litmus_Instant/get_preview/returns_a_Hash_of_the_image_types.yml
162
+ - fixtures/vcr_cassettes/Litmus_Instant/get_preview/supports_optional_capture_configuration.yml
163
+ - fixtures/vcr_cassettes/Litmus_Instant/prefetch_previews/raises_RequestError_for_an_invalid_email_guid.yml
164
+ - fixtures/vcr_cassettes/Litmus_Instant/prefetch_previews/raises_RequestError_if_any_invalid_configurations_are_present.yml
165
+ - fixtures/vcr_cassettes/Litmus_Instant/prefetch_previews/responds_with_an_array_of_the_requested_configurations.yml
166
+ - lib/litmus/instant.rb
167
+ - lib/litmus/instant/version.rb
168
+ - litmus-instant.gemspec
169
+ homepage: https://github.com/litmus/instant-api-ruby
170
+ licenses:
171
+ - MIT
172
+ metadata: {}
173
+ post_install_message:
174
+ rdoc_options: []
175
+ require_paths:
176
+ - lib
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ required_rubygems_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ requirements: []
188
+ rubyforge_project:
189
+ rubygems_version: 2.4.8
190
+ signing_key:
191
+ specification_version: 4
192
+ summary: Ruby client library for Litmus Instant API
193
+ test_files: []
194
+ has_rdoc: