rightsignature 0.1.0

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