rightsignature 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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ .rbenv-version
3
+ .rvmrc
4
+ *.swp
5
+ *.swo
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rightsignature (0.1.0)
5
+ bundler (>= 1.0.0)
6
+ httparty (>= 0.9.0)
7
+ oauth (= 0.4.3)
8
+ xml-fu (>= 0.1.7)
9
+
10
+ GEM
11
+ remote: http://rubygems.org/
12
+ specs:
13
+ builder (3.1.3)
14
+ diff-lcs (1.1.3)
15
+ httparty (0.9.0)
16
+ multi_json (~> 1.0)
17
+ multi_xml
18
+ multi_json (1.3.6)
19
+ multi_xml (0.5.1)
20
+ oauth (0.4.3)
21
+ rspec (2.11.0)
22
+ rspec-core (~> 2.11.0)
23
+ rspec-expectations (~> 2.11.0)
24
+ rspec-mocks (~> 2.11.0)
25
+ rspec-core (2.11.1)
26
+ rspec-expectations (2.11.3)
27
+ diff-lcs (~> 1.1.3)
28
+ rspec-mocks (2.11.2)
29
+ xml-fu (0.1.7)
30
+ builder (>= 2.1.2)
31
+
32
+ PLATFORMS
33
+ ruby
34
+
35
+ DEPENDENCIES
36
+ bundler (>= 1.0.0)
37
+ rightsignature!
38
+ rspec (>= 2.11.0)
data/README.md ADDED
@@ -0,0 +1,317 @@
1
+ RightSignature API
2
+ ==================
3
+ This gem is a wrapper to RightSignature's API for both OAuth authentication and Token authentication
4
+
5
+ Setup
6
+ -----
7
+ After getting an API key from RightSignature, you can use the Secure Token or generate an Access Token with the OAuth key and secret using RightSignature::load_configuration.
8
+
9
+ #####Using Token authentication
10
+ ```
11
+ RightSignature::load_configuration(:api_token => YOUR_TOKEN)
12
+ ```
13
+
14
+ #####Using OAuth authentication
15
+ ```
16
+ RightSignature::load_configuration(:consumer_key => "Consumer123", :consumer_secret => "Secret098", :access_token => "AccessToken098", :access_secret => "AccessSecret123")
17
+ ```
18
+ Note: if the both OAuth credentials and api_token are set, the default action is to use Token Authentication.
19
+
20
+
21
+ After loading the configuration, you can use wrappers in RightSignature::Document or RightSignature::Template to call the API. Or use RightSignature::Connection for a more custom call.
22
+
23
+ Documents
24
+ ---------
25
+ API calls involving documents are wrapped in the RightSignature::Document class.
26
+
27
+ #####Listing Document
28
+ For showing all documents
29
+ ```
30
+ RightSignature::Document.list
31
+ ```
32
+
33
+ For showing page 1 of completed and trashed documents, with 20 per page, matching search term 'me', with tag "single_tag" and tag "key" with value of "with_value"
34
+ ```
35
+ options = {
36
+ :state => ['completed', 'trashed'],
37
+ :page => 1,
38
+ :per_page => 20,
39
+ :search => "me",
40
+ :tags => ["single_tag", "key" => "with_value"]
41
+ }
42
+ RightSignature::Document.list(options)
43
+ ```
44
+ Optional Options:
45
+ * page: page number
46
+ * per_page: number of documents to return per page.
47
+ API only supports 10, 20, 30, 40, or 50. Default is 10.
48
+ * tags: filter documents with given tags. Tags are an array of strings (single tag) and hashes (tag_name => tag_value).
49
+ Ex. ["single_tag",{"tag_key" => "tag_value"}] would filter documents with 'single_tag' and the name/value of 'tag_key' with value 'tag_value'.
50
+ * search: filter documents with given term.
51
+ * state: An array of document states to filter documents by.
52
+ API supports 'pending', 'completed', 'trash', and 'pending'.
53
+ * sort: sort documents by given attribute.
54
+ API supports 'created', 'completed', and 'activity'
55
+ * range: return documents with a certain date range.
56
+ API only supports 'today', 'thisweek', 'thismonth', 'alltime', or a Date
57
+ * recipient_email: filter document where it has a recipient with given email and involves the current OAuth user.
58
+ * account: include all documents in current account if true. Should be true or false
59
+ Only available for account admins and owners.
60
+
61
+ #####Document Details
62
+ ```
63
+ RightSignature::Document.details(guid)
64
+ ```
65
+
66
+ #####Document Details for Multiple documents
67
+ ```
68
+ RightSignature::Document.batch_details(guids)
69
+ ```
70
+ * guids: Array of document GUIDs
71
+
72
+ #####Send Reminder
73
+ ```
74
+ RightSignature::Document.resend_reminder(guid)
75
+ ```
76
+
77
+ #####Trash Document
78
+ ```
79
+ RightSignature::Document.trash(guid)
80
+ ```
81
+
82
+ #####Extend Expiration of Document by 7 days
83
+ ```
84
+ RightSignature::Document.extend_expiration(guid)
85
+ ```
86
+
87
+ #####Replace Tags on Document
88
+ ```
89
+ tags=['sent_from_api', {'user_id' => '12345'}]
90
+ RightSignature::Document.update_tags(guid, tags)
91
+ ```
92
+ * guid
93
+ * tags: An array of 'tag_name' or {'tag_name' => 'tag_value'}
94
+
95
+ #####Sending New Documents
96
+ From file:
97
+ ```
98
+ recipients = [
99
+ {:name => "RightSignature", :email => "support@rightsignature.com", :role => 'cc'},
100
+ {:name => "John Bellingham", :email => "john@rightsignature.com", :role => 'signer'},
101
+ {'is_sender' => true, :role => 'signer'}
102
+ ]
103
+ options={
104
+ :tags => [{:tag => {:name => 'sent_from_api'}}, {:tag => {:name => 'user_id', :value => '12345'}}],
105
+ :expires_in => '5 days',
106
+ :action => "redirect",
107
+ 'callback_location' => "http://example.com/doc_callback",
108
+ 'use_text_tags' => false
109
+ }
110
+
111
+ RightSignature::Document.send_document_from_file("here/is/myfile.pdf", 'My Subject', recipients, options)
112
+ ```
113
+ Or
114
+ ```
115
+ RightSignature::Document.send_document_from_file(File.open("here/is/myfile.pdf", 'r'), 'My Subject', recipients)
116
+ ```
117
+ * subject: Document subject
118
+ * recipients: Recipients of the document, should be an array of hashes with :name, :email, and :role ('cc' or 'signer').
119
+ An optional :is_sender => true can be used to reference the API User and won't need to supply :name and :email. Ex. {:is_sender => true, :role => "cc"}
120
+ * Optional options:
121
+ * description: document description that'll appear in the email
122
+ * action: 'send' or 'redirect'. Redirect will prefill the document and generate a redirect token that can be used on for someone to send document under API user's account.
123
+ * expires_in: number of days before expiring the document. API only allows 2,5,15, or 30.
124
+ * tags: document tags, an array of string or hashes 'single_tag' (for simple tag) or {'tag_name' => 'tag_value'} (for tuples pairs)
125
+ Ex. ['sent_from_api', {"user_id" => "32"}]
126
+ * callback_url: A URI encoded URL that specifies the location for API to POST a callback notification to when the document has been created and signed.
127
+ Ex. "http://yoursite/callback"
128
+ * use_text_tags: Parse document for special Text Tags. true or false.
129
+ More info: https://rightsignature.com/apidocs/text_tags
130
+
131
+ From raw data:
132
+ ```
133
+ recipients = [
134
+ {:name => "RightSignature", :email => "support@rightsignature.com", :role => 'cc'},
135
+ {:name => "John Bellingham", :email => "john@rightsignature.com", :role => 'signer'},
136
+ {'is_sender' => true, :role => 'signer'}
137
+ ]
138
+ raw_data = File.read("here/is/myfile.pdf")
139
+ filename = "Desired Filename.pdf"
140
+ RightSignature::Document.send_document_from_file(raw_data, filename, 'My Subject', recipients)
141
+ ```
142
+
143
+
144
+ Templates
145
+ ---------
146
+ API calls involving documents are wrapped in the RightSignature::Template class.
147
+
148
+ #####Listing Templates
149
+ ```
150
+ RightSignature::Template.list(options={})
151
+ ```
152
+ Optional Options:
153
+ * page: page number
154
+ * per_page: number of documents to return per page.
155
+ API only supports 10, 20, 30, 40, or 50. Default is 10.
156
+ * tags: filter documents with given tags. Tags are an array of strings, name and value in a name/value tag should be separated by colon (:).
157
+ Ex. ["single_tag","tag_key:tag_value"] would filter documents with 'single_tag' and the name/value of 'tag_key' with value 'tag_value'.
158
+ * search: filter documents with given term.
159
+
160
+ #####Template Details
161
+ ```
162
+ RightSignature::Template.details(guid)
163
+ ```
164
+
165
+ #####Prepackage and Send template
166
+ Most common use of API, clones a template and sends it for signature.
167
+ ```
168
+ RightSignature::Template.prepackage_and_send(guid, subject, roles)
169
+ ```
170
+ Optional options:
171
+ * description: document description that'll appear in the email
172
+ * merge_fields: document merge fields, should be an array of merge_field_values in a hash with the merge_field_name.
173
+ Ex. [{"Salary" => "$1,000,000"}]
174
+ * expires_in: number of days before expiring the document. API only allows 2,5,15, or 30.
175
+ * tags: document tags, an array of string or hashes 'single_tag' (for simple tag) or {'tag_name' => 'tag_value'} (for tuples pairs)
176
+ Ex. ['sent_from_api', {"user_id" => "32"}]
177
+ * callback_url: A URI encoded URL that specifies the location for API to POST a callback notification to when the document has been created and signed.
178
+ Ex. "http://yoursite/callback"
179
+
180
+ #####Template Prepacking
181
+ For cloning a Template before sending it.
182
+ ```
183
+ RightSignature::Template.prepackage(guid)
184
+ ```
185
+
186
+ #####Template Prefilling
187
+ After prepacking, the new template can be updated with prefill data. This won't send out the template as a document.
188
+ ```
189
+ RightSignature::Template.prefill(guid, subject, roles)
190
+ ```
191
+
192
+ Optional options:
193
+ * description: document description that'll appear in the email
194
+ * merge_fields: document merge fields, should be an array of merge_field_values in a hash with the merge_field_name.
195
+ Ex. [{"Salary" => "$1,000,000"}]
196
+ * expires_in: number of days before expiring the document. API only allows 2,5,15, or 30.
197
+ * tags: document tags, an array of string or hashes 'single_tag' (for simple tag) or {'tag_name' => 'tag_value'} (for tuples pairs)
198
+ Ex. ['sent_from_api', {"user_id" => "32"}]
199
+ * callback_url: A URI encoded URL that specifies the location for API to POST a callback notification to when the document has been created and signed.
200
+ Ex. "http://yoursite/callback"
201
+ ```
202
+ options = {
203
+ :description => "Please read over the handbook and sign it.",
204
+ :merge_fields => [
205
+ { "Department" => "Fun and games" },
206
+ { "Salary" => "$1,000,000" }
207
+ ],
208
+ :expires_in => 5,
209
+ :tags => [
210
+ {:name => 'sent_from_api'},
211
+ {:name => 'user_id', :value => '32'}
212
+ ],
213
+ :callback_url => "http://yoursite/callback"
214
+ }
215
+ RightSignature::Template.prefill(guid, subject, roles, options)
216
+ ```
217
+
218
+
219
+ #####Template Sending
220
+ Send template as a document for signing. Same options as prefill.
221
+ ```
222
+ RightSignature::Template.send_template(guid, subject, roles)
223
+ ```
224
+
225
+ Optional options:
226
+ * description: document description that'll appear in the email
227
+ * merge_fields: document merge fields, should be an array of merge_field_values in a hash with the merge_field_name.
228
+ Ex. [{"Salary" => "$1,000,000"}]
229
+ * expires_in: number of days before expiring the document. API only allows 2,5,15, or 30.
230
+ * tags: document tags, an array of string or hashes 'single_tag' (for simple tag) or {'tag_name' => 'tag_value'} (for tuples pairs)
231
+ Ex. ['sent_from_api', {"user_id" => "32"}]
232
+ * callback_url: A URI encoded URL that specifies the location for API to POST a callback notification to when the document has been created and signed.
233
+ Ex. "http://yoursite/callback"
234
+ ```
235
+ options = {
236
+ :description => "Please read over the handbook and sign it.",
237
+ :merge_fields => [
238
+ { "Department" => "Fun and games" },
239
+ { "Salary" => "$1,000,000" }
240
+ ],
241
+ :expires_in => 5,
242
+ :tags => [
243
+ {:name => 'sent_from_api'},
244
+ {:name => 'user_id', :value => '32'}
245
+ ],
246
+ :callback_url => "http://yoursite/callback"
247
+ }
248
+ RightSignature::Template.send_template(guid, subject, roles, options)
249
+ ```
250
+
251
+ #####Create New Template Link
252
+ Generate a url that let's someone upload and create a template under OAuth user's account.
253
+ ```
254
+ RightSignature::Template.generate_build_url
255
+ ```
256
+
257
+ You can also add restrictions to what the person can do:
258
+ * callback_location: URI encoded URL that specifies the location we will POST a callback notification to when the template has been created.
259
+ * redirect_location: A URI encoded URL that specifies the location we will redirect the user to, after they have created a template.
260
+ * tags: tags to add to the template. an array of strings (for simple tag) or hashes like {'tag_name' => 'tag_value'} (for tuples pairs)
261
+ Ex. ['created_from_api', {"user_id" => "123"}]
262
+ * acceptabled_role_names: The user creating the Template will be forced to select one of the values provided.
263
+ There will be no free-form name entry when adding roles to the Template. An array of strings.
264
+ Ex. ["Employee", "Employeer"]
265
+ * acceptable_merge_field_names: The user creating the Template will be forced to select one of the values provided.
266
+ There will be no free-form name entry when adding merge fields to the Template.
267
+ Ex. ["Location", "Tax ID", "Company Name"]
268
+ ```
269
+ options = {
270
+ :acceptable_merge_field_names =>
271
+ [
272
+ {:name => "Site ID"},
273
+ {:name => "Starting City"}
274
+ ],
275
+ :acceptabled_role_names =>
276
+ [
277
+ {:name => "Http Monster"},
278
+ {:name => "Party Monster"}
279
+ ],
280
+ :callback_location => "http://example.com/done_signing",
281
+ :redirect_location => "http://example.com/come_back_here"
282
+ }
283
+ RightSignature::Template.generate_build_url(options)
284
+ ```
285
+
286
+
287
+ Custom API calls using RightSignature::Connection
288
+ -------------------------------------------------
289
+
290
+ In case there are new API paths, RightSignature::Connection allows a specific path to be specified.
291
+ #####Ex. GET https://rightsignature.com/api/documents.xml
292
+ ```
293
+ RightSignature::Connection.get('/api/documents.xml', {:my => 'params'}, {'custom_header' => 'headerValue'})
294
+ ```
295
+
296
+ #####Ex. POST https://rightsignature.com/api/documents.xml
297
+ ```
298
+ request_hash= {
299
+ :document => {
300
+ :subject => "Your Form",
301
+ 'document_data' => {:type => 'url', :value => 'http://localhost:3000/sub.pdf' }
302
+ }
303
+ }
304
+ RightSignature::Connection.post('/api/documents.xml', request_hash, {'custom_header' => 'headerValue'})
305
+ ```
306
+
307
+ Development Notes
308
+ -----------------
309
+ To load in irb from project root:
310
+ ```
311
+ $:.push File.expand_path("../lib", __FILE__); require "rightsignature"; RightSignature::load_configuration(MY_KEYS)
312
+ ```
313
+
314
+ TODO:
315
+ -----
316
+ * Gemify me
317
+ * Have a way for to generate an OAuth Access Token from RightSignature
@@ -0,0 +1,62 @@
1
+ require 'httparty'
2
+ require 'xml-fu'
3
+ require 'oauth'
4
+ require 'rightsignature/errors'
5
+ require 'rightsignature/helpers/normalizing'
6
+ require 'rightsignature/document'
7
+ require 'rightsignature/template'
8
+ require 'rightsignature/connection/oauth_connection'
9
+ require 'rightsignature/connection/token_connection'
10
+ require 'rightsignature/connection'
11
+
12
+ XmlFu::Node.symbol_conversion_algorithm = :none
13
+
14
+ module RightSignature
15
+ class <<self
16
+ attr_accessor :configuration
17
+
18
+ def load_configuration(creds={})
19
+ @configuration = {}
20
+ oauth_keys.each do |key|
21
+ @configuration[key] = creds[key].to_s
22
+ end
23
+
24
+ api_token_keys.each do |key|
25
+ @configuration[key] = creds[key].to_s
26
+ end
27
+
28
+ @configuration
29
+ end
30
+
31
+ def check_credentials
32
+ raise "Please set load_configuration with #{api_token_keys.join(',')} or #{oauth_keys.join(',')}" unless has_api_token? || has_oauth_credentials?
33
+ end
34
+
35
+ def has_api_token?
36
+ return false if @configuration.nil?
37
+ api_token_keys.each do |key|
38
+ return false if @configuration[key].nil? || @configuration[key].match(/^\s*$/)
39
+ end
40
+
41
+ return true
42
+ end
43
+
44
+ def has_oauth_credentials?
45
+ return false if @configuration.nil?
46
+ oauth_keys.each do |key|
47
+ return false if @configuration[key].nil? || @configuration[key].match(/^\s*$/)
48
+ end
49
+
50
+ return true
51
+ end
52
+
53
+ private
54
+ def oauth_keys
55
+ [:consumer_key, :consumer_secret, :access_token, :access_secret].freeze
56
+ end
57
+
58
+ def api_token_keys
59
+ [:api_token].freeze
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,58 @@
1
+ module RightSignature
2
+ class Connection
3
+ class << self
4
+ def site
5
+ if RightSignature::has_api_token?
6
+ RightSignature::TokenConnection.base_uri
7
+ else
8
+ RightSignature::OauthConnection.oauth_consumer.site
9
+ end
10
+ end
11
+
12
+ def get(url, params={}, headers={})
13
+ RightSignature::check_credentials
14
+
15
+ if RightSignature::has_api_token?
16
+ options = {}
17
+ options[:headers] = headers
18
+ options[:query] = params
19
+ RightSignature::TokenConnection.request(:get, url, options).parsed_response
20
+ else
21
+ unless params.empty?
22
+ url = "#{url}?#{params.sort.map{|param| URI.escape("#{param[0]}=#{param[1]}")}.join('&')}"
23
+ end
24
+ res = RightSignature::OauthConnection.request(:get, url, headers)
25
+ MultiXml.parse(res.body)
26
+ end
27
+ end
28
+
29
+ def post(url, body={}, headers={})
30
+ RightSignature::check_credentials
31
+
32
+ if RightSignature::has_api_token?
33
+ options = {}
34
+ options[:headers] = headers
35
+ options[:body] = XmlFu.xml(body)
36
+ res = RightSignature::TokenConnection.request(:post, url, options)
37
+
38
+ unless res.success?
39
+ puts res.body
40
+ raise RightSignature::ResponseError.new(res)
41
+ end
42
+
43
+ res.parsed_response
44
+ else
45
+ res = RightSignature::OauthConnection.request(:post, url, XmlFu.xml(body), headers)
46
+
47
+ unless res.is_a? Net::HTTPSuccess
48
+ puts res.body
49
+ raise RightSignature::ResponseError.new(res)
50
+ end
51
+
52
+ MultiXml.parse(res.body)
53
+ end
54
+ end
55
+ end
56
+
57
+ end
58
+ end