rightsignature-railstyle 1.1.9
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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/CONTRIBUTING.md +26 -0
- data/Gemfile +2 -0
- data/README.md +443 -0
- data/Rakefile +2 -0
- data/lib/rightsignature.rb +15 -0
- data/lib/rightsignature/account.rb +37 -0
- data/lib/rightsignature/connection.rb +207 -0
- data/lib/rightsignature/connection/oauth_connection.rb +109 -0
- data/lib/rightsignature/connection/token_connection.rb +36 -0
- data/lib/rightsignature/document.rb +333 -0
- data/lib/rightsignature/errors.rb +51 -0
- data/lib/rightsignature/helpers/normalizing.rb +137 -0
- data/lib/rightsignature/helpers/refine_hash_to_indifferent_access.rb +23 -0
- data/lib/rightsignature/rails_style.rb +89 -0
- data/lib/rightsignature/template.rb +299 -0
- data/lib/rightsignature/version.rb +3 -0
- data/rightsignature-api.gemspec +26 -0
- data/spec/account_spec.rb +54 -0
- data/spec/api_token_connection_spec.rb +27 -0
- data/spec/configuration_spec.rb +98 -0
- data/spec/connection_spec.rb +224 -0
- data/spec/document_spec.rb +301 -0
- data/spec/errors_spec.rb +153 -0
- data/spec/normalizing_spec.rb +85 -0
- data/spec/oauth_connnection_spec.rb +143 -0
- data/spec/rails_style_spec.rb +331 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/template_spec.rb +408 -0
- metadata +143 -0
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'xml-fu'
|
3
|
+
require 'oauth'
|
4
|
+
require 'rightsignature/errors'
|
5
|
+
require 'rightsignature/helpers/normalizing'
|
6
|
+
require 'rightsignature/helpers/refine_hash_to_indifferent_access'
|
7
|
+
require 'rightsignature/document'
|
8
|
+
require 'rightsignature/template'
|
9
|
+
require 'rightsignature/account'
|
10
|
+
require 'rightsignature/connection/oauth_connection'
|
11
|
+
require 'rightsignature/connection/token_connection'
|
12
|
+
require 'rightsignature/connection'
|
13
|
+
require 'rightsignature/rails_style'
|
14
|
+
|
15
|
+
XmlFu.config.symbol_conversion_algorithm = :none
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module RightSignature
|
2
|
+
module Account
|
3
|
+
# Return account information about API user
|
4
|
+
#
|
5
|
+
# Ex.
|
6
|
+
# @rs_connection.user_details
|
7
|
+
#
|
8
|
+
def user_details
|
9
|
+
get "/api/users/user_details.xml"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Creates a user on API user's account
|
13
|
+
# * name: User's name
|
14
|
+
# * email: User's email
|
15
|
+
#
|
16
|
+
# Ex.
|
17
|
+
# @rs_connection.add_user("John Bellingham", "john@example.com")
|
18
|
+
#
|
19
|
+
def add_user(name, email)
|
20
|
+
post "/api/users.xml", {:user => {:name => name, :email => email}}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Return account's usage report (# of documents sent)
|
24
|
+
# * <b>since</b>: ("month"/"week"/"day") only count documents sent within a certain time
|
25
|
+
# * <b>signed</b>: (true/false) only count signed document
|
26
|
+
#
|
27
|
+
# Ex. Return count of signed documents sent this month
|
28
|
+
# @rs_connection.usage_report("month", true)
|
29
|
+
#
|
30
|
+
def usage_report(since=nil, signed=nil)
|
31
|
+
options = {}
|
32
|
+
options[:since] = since if since && ["month", "week", "day"].include?(since)
|
33
|
+
options[:signed] = signed.to_s unless signed.nil?
|
34
|
+
get "/api/account/usage_report.xml", options
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
module RightSignature
|
2
|
+
class Connection
|
3
|
+
include RightSignature::Document
|
4
|
+
include RightSignature::Account
|
5
|
+
include RightSignature::Template
|
6
|
+
|
7
|
+
attr_accessor :configuration
|
8
|
+
attr_accessor :oauth_connection
|
9
|
+
attr_accessor :token_connection
|
10
|
+
|
11
|
+
# Creates new instance of RightSignature::Connection to make API calls
|
12
|
+
# * <b>creds</b>: Hash of credentials for API Token or OAuth. If both are specified, it uses API Token
|
13
|
+
# * Hash key for API Token:
|
14
|
+
# * :api_token
|
15
|
+
# * Hash keys for OAuth:
|
16
|
+
# * :consumer_key
|
17
|
+
# * :consumer_secret
|
18
|
+
# * :access_token
|
19
|
+
# * :access_secret
|
20
|
+
#
|
21
|
+
# Example for Api Token:
|
22
|
+
# @rs_connection = RightSignature::Connection.new(:api_token => "MYTOKEN")
|
23
|
+
#
|
24
|
+
# Example for OAuth:
|
25
|
+
# @rs_connection = RightSignature::Connection.new(:consumer_key => "ckey", :consumer_secret => "csecret", :access_token => "atoken", :access_secret => "asecret")
|
26
|
+
#
|
27
|
+
def initialize(creds={})
|
28
|
+
@configuration = {}
|
29
|
+
RightSignature::Connection.oauth_keys.each do |key|
|
30
|
+
@configuration[key] = creds[key].to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
RightSignature::Connection.api_token_keys.each do |key|
|
34
|
+
@configuration[key] = creds[key].to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
@token_connection = RightSignature::TokenConnection.new(*RightSignature::Connection.api_token_keys.map{|k| @configuration[k]})
|
38
|
+
@oauth_connection = RightSignature::OauthConnection.new(@configuration)
|
39
|
+
|
40
|
+
@configuration
|
41
|
+
end
|
42
|
+
|
43
|
+
# Checks if credentials are set for either API Token or for OAuth
|
44
|
+
#
|
45
|
+
def check_credentials
|
46
|
+
raise "Please set load_configuration with #{RightSignature::Connection.api_token_keys.join(',')} or #{RightSignature::Connection.oauth_keys.join(',')}" unless has_api_token? || has_oauth_credentials?
|
47
|
+
end
|
48
|
+
|
49
|
+
# Checks if API Token credentials are set. Does not validate creds with server.
|
50
|
+
#
|
51
|
+
def has_api_token?
|
52
|
+
return false if @configuration.nil?
|
53
|
+
RightSignature::Connection.api_token_keys.each do |key|
|
54
|
+
return false if @configuration[key].nil? || @configuration[key].match(/^\s*$/)
|
55
|
+
end
|
56
|
+
|
57
|
+
return true
|
58
|
+
end
|
59
|
+
|
60
|
+
# Checks if OAuth credentials are set. Does not validate creds with server.
|
61
|
+
#
|
62
|
+
def has_oauth_credentials?
|
63
|
+
return false if @configuration.nil?
|
64
|
+
RightSignature::Connection.oauth_keys.each do |key|
|
65
|
+
return false if @configuration[key].nil? || @configuration[key].match(/^\s*$/)
|
66
|
+
end
|
67
|
+
|
68
|
+
return true
|
69
|
+
end
|
70
|
+
|
71
|
+
# :nodoc:
|
72
|
+
def self.oauth_keys
|
73
|
+
[:consumer_key, :consumer_secret, :access_token, :access_secret].freeze
|
74
|
+
end
|
75
|
+
|
76
|
+
# :nodoc:
|
77
|
+
def self.api_token_keys
|
78
|
+
[:api_token].freeze
|
79
|
+
end
|
80
|
+
|
81
|
+
# :nodoc:
|
82
|
+
def site
|
83
|
+
if has_api_token?
|
84
|
+
RightSignature::TokenConnection.base_uri
|
85
|
+
else
|
86
|
+
@oauth_connection.oauth_consumer.site
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# PUT request to server
|
91
|
+
#
|
92
|
+
# Arguments:
|
93
|
+
# url: Path of API call
|
94
|
+
# body: XML body in hash format
|
95
|
+
# url: Hash of HTTP headers to include
|
96
|
+
#
|
97
|
+
# Example:
|
98
|
+
# @rs_connection.put("/api/documents.xml", {:documents=> {}}, {"User-Agent" => "My Own"})
|
99
|
+
#
|
100
|
+
def put(url, body={}, headers={})
|
101
|
+
if has_api_token?
|
102
|
+
options = {}
|
103
|
+
options[:headers] = headers
|
104
|
+
options[:body] = XmlFu.xml(body)
|
105
|
+
|
106
|
+
parse_response(@token_connection.request(:put, url, options))
|
107
|
+
else
|
108
|
+
parse_response(@oauth_connection.request(:put, url, XmlFu.xml(body), headers))
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# DELETE request to server
|
113
|
+
#
|
114
|
+
# Arguments:
|
115
|
+
# url: Path of API call
|
116
|
+
# url: Hash of HTTP headers to include
|
117
|
+
#
|
118
|
+
# Example:
|
119
|
+
# @rs_connection.delete("/api/users.xml", {"User-Agent" => "My Own"})
|
120
|
+
#
|
121
|
+
def delete(url, headers={})
|
122
|
+
if has_api_token?
|
123
|
+
options = {}
|
124
|
+
options[:headers] = headers
|
125
|
+
|
126
|
+
parse_response(@token_connection.request(:delete, url, options))
|
127
|
+
else
|
128
|
+
parse_response(@oauth_connection.request(:delete, url, headers))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# GET request to server
|
133
|
+
#
|
134
|
+
# Arguments:
|
135
|
+
# url: Path of API call
|
136
|
+
# params: Hash of URL parameters to include in request
|
137
|
+
# url: Hash of HTTP headers to include
|
138
|
+
#
|
139
|
+
# Example:
|
140
|
+
# @rs_connection.get("/api/documents.xml", {:search => "my term"}, {"User-Agent" => "My Own"})
|
141
|
+
#
|
142
|
+
def get(url, params={}, headers={})
|
143
|
+
check_credentials
|
144
|
+
|
145
|
+
if has_api_token?
|
146
|
+
options = {}
|
147
|
+
options[:headers] = headers
|
148
|
+
options[:query] = params
|
149
|
+
parse_response(@token_connection.request(:get, url, options))
|
150
|
+
else
|
151
|
+
unless params.empty?
|
152
|
+
url = "#{url}?#{params.sort.map{|param| URI.escape("#{param[0]}=#{param[1]}")}.join('&')}"
|
153
|
+
end
|
154
|
+
parse_response(@oauth_connection.request(:get, url, headers))
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# POST request to server
|
159
|
+
#
|
160
|
+
# Arguments:
|
161
|
+
# url: Path of API call
|
162
|
+
# url: Hash of HTTP headers to include
|
163
|
+
#
|
164
|
+
# Example:
|
165
|
+
# @rs_connection.post("/api/users.xml", {"User-Agent" => "My Own"})
|
166
|
+
#
|
167
|
+
def post(url, body={}, headers={})
|
168
|
+
check_credentials
|
169
|
+
|
170
|
+
if has_api_token?
|
171
|
+
options = {}
|
172
|
+
options[:headers] = headers
|
173
|
+
options[:body] = XmlFu.xml(body)
|
174
|
+
parse_response(@token_connection.request(:post, url, options))
|
175
|
+
else
|
176
|
+
parse_response(@oauth_connection.request(:post, url, XmlFu.xml(body), headers))
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Attempts to parse response from a connection and return it as a hash.
|
181
|
+
# If response isn't a success, an RightSignature::ResponseError is raised
|
182
|
+
#
|
183
|
+
# Arguments:
|
184
|
+
# url: Path of API call
|
185
|
+
# url: Hash of HTTP headers to include
|
186
|
+
#
|
187
|
+
# Example:
|
188
|
+
# @rs_connection.delete("/api/users.xml", {"User-Agent" => "My Own"})
|
189
|
+
#
|
190
|
+
def parse_response(response)
|
191
|
+
if response.is_a? Net::HTTPResponse
|
192
|
+
unless response.is_a? Net::HTTPSuccess
|
193
|
+
raise RightSignature::ResponseError.new(response)
|
194
|
+
end
|
195
|
+
|
196
|
+
MultiXml.parse(response.body)
|
197
|
+
else
|
198
|
+
unless response.success?
|
199
|
+
raise RightSignature::ResponseError.new(response)
|
200
|
+
end
|
201
|
+
|
202
|
+
response.parsed_response
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module RightSignature
|
2
|
+
class OauthConnection
|
3
|
+
attr_reader :request_token
|
4
|
+
attr_reader :consumer_key, :consumer_secret, :oauth_access_token, :oauth_access_secret
|
5
|
+
|
6
|
+
# Creates new instance of RightSignature::OauthConnection to make API calls
|
7
|
+
# * <b>creds</b>: Hash of credentials for OAuth.
|
8
|
+
# * Hash keys for OAuth:
|
9
|
+
# * :consumer_key
|
10
|
+
# * :consumer_secret
|
11
|
+
# * :access_token
|
12
|
+
# * :access_secret
|
13
|
+
#
|
14
|
+
# Example:
|
15
|
+
# @rs_oauth = RightSignature::OauthConnection.new(:consumer_key => "ckey", :consumer_secret => "csecret", :access_token => "atoken", :access_secret => "asecret")
|
16
|
+
#
|
17
|
+
def initialize(credentials={})
|
18
|
+
@consumer_key = credentials[:consumer_key]
|
19
|
+
@consumer_secret = credentials[:consumer_secret]
|
20
|
+
@oauth_access_token = credentials[:access_token]
|
21
|
+
@oauth_access_secret = credentials[:access_secret]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Oauth consumer
|
25
|
+
def oauth_consumer
|
26
|
+
check_credentials unless @consumer_key && @consumer_secret
|
27
|
+
@oauth_consumer ||= OAuth::Consumer.new(
|
28
|
+
@consumer_key,
|
29
|
+
@consumer_secret,
|
30
|
+
{
|
31
|
+
:site => "https://rightsignature.com",
|
32
|
+
:scheme => :header,
|
33
|
+
:http_method => :post,
|
34
|
+
:authorize_path =>'/oauth/authorize',
|
35
|
+
:access_token_path =>'/oauth/access_token',
|
36
|
+
:request_token_path=>'/oauth/request_token'
|
37
|
+
}
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Access token
|
42
|
+
def access_token
|
43
|
+
check_credentials
|
44
|
+
@access_token ||= OAuth::AccessToken.new(oauth_consumer, @oauth_access_token, @oauth_access_secret)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Replaces access token
|
48
|
+
# * <b>access_token</b>: access token key
|
49
|
+
# * <b>access_secret</b>: access token secret
|
50
|
+
#
|
51
|
+
def set_access_token(access_token, access_secret)
|
52
|
+
@oauth_access_token = access_token
|
53
|
+
@oauth_access_secret = access_secret
|
54
|
+
@access_token = OAuth::AccessToken.new(oauth_consumer, @oauth_access_token, @oauth_access_secret)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Uses consumer to generate a request token.
|
58
|
+
# * <b>o</b>: options hash. Use this to set the :oauth_callback
|
59
|
+
def new_request_token(o = {})
|
60
|
+
@request_token = oauth_consumer.get_request_token(o)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Sets request token.
|
64
|
+
# * <b>request_token</b>: request token key
|
65
|
+
# * <b>request_token_secret</b>: request token secret
|
66
|
+
#
|
67
|
+
def set_request_token(request_token, request_token_secret)
|
68
|
+
@request_token = OAuth::RequestToken.new(oauth_consumer, request_token, request_token_secret)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Uses request token and given OAuth verifier to generate an access token. Requires a request token to be set.
|
72
|
+
# * <b>oauth_verifier</b>: OAuth verifier
|
73
|
+
#
|
74
|
+
def generate_access_token(oauth_verifier)
|
75
|
+
raise "Please set request token with new_request_token" unless @request_token
|
76
|
+
@access_token = @request_token.get_access_token(:oauth_verifier => oauth_verifier)
|
77
|
+
@oauth_access_token = @access_token.token
|
78
|
+
@oauth_access_secret = @access_token.secret
|
79
|
+
@access_token
|
80
|
+
end
|
81
|
+
|
82
|
+
# Generates HTTP request with oauth credentials. Require access_token to be set.
|
83
|
+
# * <b>method</b>: HTTP Method. Ex. ('get'/'post'/'delete'/'put')
|
84
|
+
# * <b>options</b>: OAuth::AccessToken options to pass. Last option should be headers
|
85
|
+
#
|
86
|
+
def request(method, *options)
|
87
|
+
options.last ||= {}
|
88
|
+
options.last["Accept"] ||= "*/*"
|
89
|
+
options.last["content-type"] ||= "application/xml"
|
90
|
+
|
91
|
+
self.access_token.__send__(method, *options)
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
# Raises exception if OAuth credentials are not set.
|
96
|
+
def check_credentials
|
97
|
+
raise "Please set #{RightSignature::Connection.oauth_keys.join(', ')}" unless has_oauth_credentials?
|
98
|
+
end
|
99
|
+
|
100
|
+
# Checks if OAuth credentials are set.
|
101
|
+
def has_oauth_credentials?
|
102
|
+
[@consumer_key, @consumer_secret, @oauth_access_token, @oauth_access_secret].each do |cred|
|
103
|
+
return false if cred.nil? || cred.match(/^\s*$/)
|
104
|
+
end
|
105
|
+
|
106
|
+
true
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RightSignature
|
2
|
+
class TokenConnection
|
3
|
+
include HTTParty
|
4
|
+
base_uri 'https://rightsignature.com'
|
5
|
+
format :xml
|
6
|
+
|
7
|
+
attr_reader :api_token
|
8
|
+
|
9
|
+
# Creates new instance of RightSignature::TokenConnection to make API calls
|
10
|
+
# * <b>api_token</b>: API Token.
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# @rs_token = RightSignature::TokenConnection.new("APITOKEN")
|
14
|
+
#
|
15
|
+
def initialize(api_token)
|
16
|
+
@api_token = api_token
|
17
|
+
end
|
18
|
+
|
19
|
+
# Generates HTTP request with token credentials. Require api_token to be set.
|
20
|
+
# * <b>method</b>: HTTP Method. Ex. ('get'/'post'/'delete'/'put')
|
21
|
+
# * <b>url</b>: request path/url of request
|
22
|
+
# * <b>options</b>: HTTPary options to pass. Last option should be headers
|
23
|
+
#
|
24
|
+
def request(method, url, options)
|
25
|
+
raise "Please set api_token" if @api_token.nil? || @api_token.empty?
|
26
|
+
|
27
|
+
options[:headers] ||= {}
|
28
|
+
options[:headers]['api-token'] = @api_token
|
29
|
+
options[:headers]["Accept"] ||= "*/*"
|
30
|
+
options[:headers]["content-type"] ||= "application/xml"
|
31
|
+
self.class.__send__(method, url, options)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,333 @@
|
|
1
|
+
using RefineHashToIndifferentAccess
|
2
|
+
|
3
|
+
module RightSignature
|
4
|
+
module Document
|
5
|
+
include RightSignature::Helpers
|
6
|
+
|
7
|
+
# Lists documents
|
8
|
+
# * <b>options</b>: (optional) search filters
|
9
|
+
# * <b>:state</b> - (completed/trashed/pending) filter by state
|
10
|
+
# * <b>:page</b> - page offset
|
11
|
+
# * <b>:per_page</b> - # of entries per page to return
|
12
|
+
# * <b>:search</b> - search term filter
|
13
|
+
# * <b>:tags</b> - tags filter. Array of ["single_tag", {"tag_key" => "tag_value"}]
|
14
|
+
# * <b>:sort</> - sort documents by given attribute.
|
15
|
+
# API supports 'created', 'completed', and 'activity'
|
16
|
+
# * <b>:range</b> - ('today'/'thisweek'/'thismonth'/'alltime'/Date) return documents with a certain date range.
|
17
|
+
# * <b> :recipient_email</b> - filter document where it has a recipient with given email and involves the current OAuth user.
|
18
|
+
# * <b> :account</b> - (true/false) include all documents in current account if true.
|
19
|
+
#
|
20
|
+
# Ex.
|
21
|
+
# options = {
|
22
|
+
# :state => ['completed', 'trashed'],
|
23
|
+
# :page => 1,
|
24
|
+
# :per_page => 20,
|
25
|
+
# :search => "me",
|
26
|
+
# :tags => ["single_tag", "key" => "with_value"]
|
27
|
+
# }
|
28
|
+
#
|
29
|
+
# @rs_connection.documents_list(options)
|
30
|
+
#
|
31
|
+
def documents_list(options={})
|
32
|
+
if options[:metadata]
|
33
|
+
options[:tags] = TagsHelper.array_and_metadata_to_string_array(options[:tags], options.delete(:metadata))
|
34
|
+
elsif options[:tags]
|
35
|
+
options[:tags] = TagsHelper.mixed_array_to_string_array(options[:tags])
|
36
|
+
end
|
37
|
+
options[:state] = options[:state].join(',') if options[:state] && options[:state].is_a?(Array)
|
38
|
+
get "/api/documents.xml", options
|
39
|
+
end
|
40
|
+
|
41
|
+
# Gets details for a document
|
42
|
+
# * <b>guids</b>: Array of document GUIDs
|
43
|
+
#
|
44
|
+
# Ex. Get details for document GUID123
|
45
|
+
# @rs_connection.document_details("GUID123")
|
46
|
+
#
|
47
|
+
def document_details(guid)
|
48
|
+
get "/api/documents/#{guid}.xml"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Gets details for multiple documents.
|
52
|
+
# * <b>guids</b>: Array of document GUIDs
|
53
|
+
#
|
54
|
+
# Ex. Get details for documents GUID123 and GUID345
|
55
|
+
# @rs_connection.documents_batch_details(["GUID123","GUID345"])
|
56
|
+
#
|
57
|
+
def documents_batch_details(guids)
|
58
|
+
get "/api/documents/#{guids.join(',')}/batch_details.xml"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Sends a reminder for a document
|
62
|
+
# * <b>guid</b>: Document GUID
|
63
|
+
#
|
64
|
+
# Ex. Sends reminder for document GUID123
|
65
|
+
# @rs_connection.send_reminder("GUID123")
|
66
|
+
#
|
67
|
+
def send_reminder(guid)
|
68
|
+
post "/api/documents/#{guid}/send_reminders.xml", {}
|
69
|
+
end
|
70
|
+
|
71
|
+
# Extends a document's expiration date by 7 days
|
72
|
+
# * <b>guid</b>: Document GUID
|
73
|
+
#
|
74
|
+
# Ex. Extend expiration for document GUID123 by 7 days
|
75
|
+
# @rs_connection.trash_document("GUID123")
|
76
|
+
#
|
77
|
+
def trash_document(guid)
|
78
|
+
post "/api/documents/#{guid}/trash.xml", {}
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
# Extends a document's expiration date by 7 days
|
83
|
+
# * <b>guid</b>: Document GUID
|
84
|
+
#
|
85
|
+
# Ex. Extend expiration for document GUID123 by 7 days
|
86
|
+
# @rs_connection.extend_document_expiration("GUID123")
|
87
|
+
#
|
88
|
+
def extend_document_expiration(guid)
|
89
|
+
post "/api/documents/#{guid}/extend_expiration.xml", {}
|
90
|
+
end
|
91
|
+
|
92
|
+
# <b>REPLACE</b> the tags on a document
|
93
|
+
# tags are an array of 'tag_name' or {'tag_name' => 'value'}
|
94
|
+
#
|
95
|
+
# Ex. Replaces document GUID123 with tags "single_tag", "hello:bye"
|
96
|
+
# @rs_connection.update_document_tags("GUID123", ["single_tag", {"hello" => "bye"}])
|
97
|
+
def update_document_tags(guid, tags)
|
98
|
+
post "/api/documents/#{guid}/update_tags.xml", { :tags => TagsHelper.array_to_xml_hash(tags) }
|
99
|
+
end
|
100
|
+
|
101
|
+
# Creates a document from a raw data
|
102
|
+
# * <b>file</b>: file binary. Ex. File.read('myfile.pdf')
|
103
|
+
# * <b>filename</b>: original filename
|
104
|
+
# * <b>subject</b>: subject of the document that'll appear in email
|
105
|
+
# * <b>recipients</b>: Recipients of the document, should be an array of hashes with :name, :email, and :role ('cc' or 'signer').
|
106
|
+
# One of the recipients requires <b>:is_sender</b> (true/false) to reference the API User and won't need to supply :name and :email
|
107
|
+
# Ex. CC to support@rightsignature.com, with sender and john@rightsignature.com as a signer
|
108
|
+
# [
|
109
|
+
# {:name => "RightSignature", :email => "support@rightsignature.com", :role => 'cc'},
|
110
|
+
# {:name => "John Bellingham", :email => "john@rightsignature.com", :role => 'signer'},
|
111
|
+
# {'is_sender' => true, :role => 'signer'},
|
112
|
+
# ]
|
113
|
+
# * <b>options</b>: other optional values
|
114
|
+
# - <b>description</b>: document description that'll appear in the email
|
115
|
+
# - <b>action</b>: 'send' or 'redirect'. Redirect will return a token that will allow another person to send the document under API user's account
|
116
|
+
# - <b>expires_in</b>: number of days before expiring the document. API only allows 2,5,15, or 30.
|
117
|
+
# - <b>tags</b>: document tags, an array of string or hashes 'single_tag' (for simple tag) or {'tag_name' => 'tag_value'} (for tuples pairs)
|
118
|
+
# Ex. ['sent_from_api', {"user_id" => "32"}]
|
119
|
+
# - <b>callback_location</b>: A URI encoded URL that specifies the location for API to POST a callback notification to when the document has been created and signed.
|
120
|
+
# Ex. "http://yoursite/callback"
|
121
|
+
# - <b>use_text_tags</b>: Document has special Text Tags that RightSignature parse. true or false.
|
122
|
+
# More info: https://rightsignature.com/apidocs/text_tags
|
123
|
+
def send_document_from_data(file_data, filename, subject, recipients, options={})
|
124
|
+
send_document(subject, recipients, {:type => "base64", :filename => filename, :value => Base64::encode64(file_data)}, options)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Creates a document from a File or path to file
|
128
|
+
# * <b>file</b>: Path to file or File object
|
129
|
+
# * <b>subject</b>: subject of the document that'll appear in email
|
130
|
+
# * <b>recipients</b>: Recipients of the document, should be an array of hashes with :name, :email, and :role ('cc' or 'signer').
|
131
|
+
# One of the recipients requires <b>:is_sender</b> (true/false) to reference the API User and won't need to supply :name and :email
|
132
|
+
# Ex. CC to support@rightsignature.com, with sender and john@rightsignature.com as a signer
|
133
|
+
# [
|
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
|
+
# * <b>options</b>: other optional values
|
139
|
+
# - <b>description</b>: document description that'll appear in the email
|
140
|
+
# - <b>action</b>: 'send' or 'redirect'. Redirect will return a token that will allow another person to send the document under API user's account
|
141
|
+
# - <b>expires_in</b>: number of days before expiring the document. API only allows 2,5,15, or 30.
|
142
|
+
# - <b>tags</b>: document tags, an array of string or hashes 'single_tag' (for simple tag) or {'tag_name' => 'tag_value'} (for tuples pairs)
|
143
|
+
# Ex. ['sent_from_api', {"user_id" => "32"}]
|
144
|
+
# - <b>callback_location</b>: A URI encoded URL that specifies the location for API to POST a callback notification to when the document has been created and signed.
|
145
|
+
# Ex. "http://yoursite/callback"
|
146
|
+
# - <b>use_text_tags</b>: Document has special Text Tags that RightSignature parse. true or false.
|
147
|
+
# More info: https://rightsignature.com/apidocs/text_tags
|
148
|
+
#
|
149
|
+
# Example:
|
150
|
+
# recipients = [
|
151
|
+
# {:name => "RightSignature", :email => "support@rightsignature.com", :role => 'cc'},
|
152
|
+
# {:name => "John Bellingham", :email => "john@rightsignature.com", :role => 'signer'},
|
153
|
+
# {'is_sender' => true, :role => 'signer'}
|
154
|
+
# ]
|
155
|
+
# options={
|
156
|
+
# :tags => [{:tag => {:name => 'sent_from_api'}}, {:tag => {:name => 'user_id', :value => '12345'}}],
|
157
|
+
# :expires_in => '5 days',
|
158
|
+
# :action => "redirect",
|
159
|
+
# 'callback_location' => "http://example.com/doc_callback",
|
160
|
+
# 'use_text_tags' => false
|
161
|
+
# }
|
162
|
+
# @rs_connection.send_document_from_file("here/is/myfile.pdf", 'My Subject', recipients, options)
|
163
|
+
#
|
164
|
+
def send_document_from_file(file, subject, recipients, options={})
|
165
|
+
send_document(subject, recipients, {:type => "base64", :filename => File.basename(file), :value => Base64::encode64(File.read(file)) }, options)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Creates a document from URL
|
169
|
+
# * <b>url</b>: URL to file
|
170
|
+
# * <b>subject</b>: subject of the document that'll appear in email
|
171
|
+
# * <b>recipients</b>: Recipients of the document, should be an array of hashes with :name, :email, and :role ('cc' or 'signer').
|
172
|
+
# One of the recipients requires <b>:is_sender</b> (true/false) to reference the API User and won't need to supply :name and :email
|
173
|
+
# Ex. CC to support@rightsignature.com, with sender and john@rightsignature.com as a signer
|
174
|
+
# [
|
175
|
+
# {:name => "RightSignature", :email => "support@rightsignature.com", :role => 'cc'},
|
176
|
+
# {:name => "John Bellingham", :email => "john@rightsignature.com", :role => 'signer'},
|
177
|
+
# {'is_sender' => true, :role => 'signer'},
|
178
|
+
# ]
|
179
|
+
# * <b>options</b>: other optional values
|
180
|
+
# - <b>description</b>: document description that'll appear in the email
|
181
|
+
# - <b>action</b>: 'send' or 'redirect'. Redirect will return a token that will allow another person to send the document under API user's account
|
182
|
+
# - <b>expires_in</b>: number of days before expiring the document. API only allows 2,5,15, or 30.
|
183
|
+
# - <b>tags</b>: document tags, an array of string or hashes 'single_tag' (for simple tag) or {'tag_name' => 'tag_value'} (for tuples pairs)
|
184
|
+
# Ex. ['sent_from_api', {"user_id" => "32"}]
|
185
|
+
# - <b>callback_location</b>: A URI encoded URL that specifies the location for API to POST a callback notification to when the document has been created and signed.
|
186
|
+
# Ex. "http://yoursite/callback"
|
187
|
+
# - <b>use_text_tags</b>: Document has special Text Tags that RightSignature parse. true or false.
|
188
|
+
# More info: https://rightsignature.com/apidocs/text_tags
|
189
|
+
#
|
190
|
+
# Example:
|
191
|
+
# recipients = [
|
192
|
+
# {:name => "RightSignature", :email => "support@rightsignature.com", :role => 'cc'},
|
193
|
+
# {:name => "John Bellingham", :email => "john@rightsignature.com", :role => 'signer'},
|
194
|
+
# {'is_sender' => true, :role => 'signer'}
|
195
|
+
# ]
|
196
|
+
# options={
|
197
|
+
# :tags => [{:tag => {:name => 'sent_from_api'}}, {:tag => {:name => 'user_id', :value => '12345'}}],
|
198
|
+
# :expires_in => '5 days',
|
199
|
+
# :action => "redirect",
|
200
|
+
# 'callback_location' => "http://example.com/doc_callback",
|
201
|
+
# 'use_text_tags' => false
|
202
|
+
# }
|
203
|
+
# @rs_connection.send_document_from_url("http://myfile/here", 'My Subject', recipients, options)
|
204
|
+
#
|
205
|
+
def send_document_from_url(url, subject, recipients, options={})
|
206
|
+
send_document(subject, recipients, {:type => "url", :filename => File.basename(url), :value => url }, options)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Creates a document from a base64 encoded file or publicly available URL
|
210
|
+
# * <b>document_data</b>: hash of document source :type ('base64' or 'url'), :filename to be used, :value of source (url or base64 encoded binary)
|
211
|
+
# * <b>subject</b>: subject of the document that'll appear in email
|
212
|
+
# * <b>recipients</b>: Recipients of the document, should be an array of hashes with :name, :email, and :role ('cc' or 'signer').
|
213
|
+
# One of the recipients requires <b>:is_sender</b> (true/false) to reference the API User and won't need to supply :name and :email
|
214
|
+
# Ex. CC to support@rightsignature.com, with sender and john@rightsignature.com as a signer
|
215
|
+
# [
|
216
|
+
# {:name => "RightSignature", :email => "support@rightsignature.com", :role => 'cc'},
|
217
|
+
# {:name => "John Bellingham", :email => "john@rightsignature.com", :role => 'signer'},
|
218
|
+
# {'is_sender' => true, :role => 'signer'},
|
219
|
+
# ]
|
220
|
+
# * options: other optional values
|
221
|
+
# - <b>description</b>: document description that'll appear in the email
|
222
|
+
# - <b>action</b>: 'send' or 'redirect'. Redirect will return a token that will allow another person to send the document under API user's account
|
223
|
+
# - <b>expires_in</b>: number of days before expiring the document. API only allows 2,5,15, or 30.
|
224
|
+
# - <b>tags</b>: document tags, an array of string or hashes 'single_tag' (for simple tag) or {'tag_name' => 'tag_value'} (for tuples pairs)
|
225
|
+
# Ex. ['sent_from_api', {"user_id" => "32"}]
|
226
|
+
# - <b>callback_location</b>: A URI encoded URL that specifies the location for API to POST a callback notification to when the document has been created and signed.
|
227
|
+
# Ex. "http://yoursite/callback"
|
228
|
+
# - <b>use_text_tags</b>: Document has special Text Tags that RightSignature parse. true or false.
|
229
|
+
# More info: https://rightsignature.com/apidocs/text_tags
|
230
|
+
# Ex.
|
231
|
+
# recipients = [
|
232
|
+
# {:name => "RightSignature", :email => "support@rightsignature.com", :role => 'cc'},
|
233
|
+
# {:name => "John Bellingham", :email => "john@rightsignature.com", :role => 'signer'},
|
234
|
+
# {'is_sender' => true, :role => 'signer'},
|
235
|
+
# ]
|
236
|
+
# document_data = {:type => 'base64', :filename => "originalfile.pdf", :value => Base64.encode64(File.read('myfile.pdf','r'))}
|
237
|
+
# options = {
|
238
|
+
# :tags => ['sent_from_api', 'user_id' => '12345'],
|
239
|
+
# :expires_in => '5 days',
|
240
|
+
# :action => "redirect",
|
241
|
+
# 'callback_location' => "http://example.com/doc_callback",
|
242
|
+
# 'use_text_tags' => false
|
243
|
+
# }
|
244
|
+
# @rs_connection.send_document( "My Subject", recipients, document_data, options)
|
245
|
+
#
|
246
|
+
def send_document(subject, recipients, document_data, options={})
|
247
|
+
document_hash = {:document => {
|
248
|
+
:subject => subject,
|
249
|
+
:action => "send",
|
250
|
+
:document_data => document_data
|
251
|
+
}}
|
252
|
+
|
253
|
+
document_hash[:document][:recipients] = []
|
254
|
+
recipients.each do |recipient_hash|
|
255
|
+
document_hash[:document][:recipients] << { :recipient => recipient_hash}
|
256
|
+
end
|
257
|
+
|
258
|
+
document_hash[:document].merge!(options)
|
259
|
+
post "/api/documents.xml", document_hash
|
260
|
+
end
|
261
|
+
|
262
|
+
# Prefills a document from a base64 encoded file or publicly available URL and returns a url that allows someone to send as the API User
|
263
|
+
# * <b>document_data</b>: hash of document source :type ('base64' or 'url'), :filename to be used, :value of source (url or base64 encoded binary)
|
264
|
+
# * <b>subject</b>: subject of the document that'll appear in email
|
265
|
+
# * <b>recipients</b>: Recipients of the document, should be an array of hashes with :name, :email, and :role ('cc' or 'signer').
|
266
|
+
# One of the recipients requires <b>:is_sender</b> (true/false) to reference the API User and won't need to supply :name and :email
|
267
|
+
# Ex. CC to support@rightsignature.com, with sender and john@rightsignature.com as a signer
|
268
|
+
# [
|
269
|
+
# {:name => "RightSignature", :email => "support@rightsignature.com", :role => 'cc'},
|
270
|
+
# {:name => "John Bellingham", :email => "john@rightsignature.com", :role => 'signer'},
|
271
|
+
# {'is_sender' => true, :role => 'signer'},
|
272
|
+
# ]
|
273
|
+
# * <b>options</b>: other optional values
|
274
|
+
# - <b>description</b>: document description that'll appear in the email
|
275
|
+
# - <b>action</b>: 'send' or 'redirect'. Redirect will return a token that will allow another person to send the document under API user's account
|
276
|
+
# - <b>expires_in</b>: number of days before expiring the document. API only allows 2,5,15, or 30.
|
277
|
+
# - <b>tags</b>: document tags, an array of string or hashes 'single_tag' (for simple tag) or {'tag_name' => 'tag_value'} (for tuples pairs)
|
278
|
+
# Ex. ['sent_from_api', {"user_id" => "32"}]
|
279
|
+
# - <b>callback_location</b>: A URI encoded URL that specifies the location for API to POST a callback notification to when the document has been created and signed.
|
280
|
+
# Ex. "http://yoursite/callback"
|
281
|
+
# - <b>use_text_tags</b>: Document has special Text Tags that RightSignature parse. true or false.
|
282
|
+
# More info: https://rightsignature.com/apidocs/text_tags
|
283
|
+
# Ex.
|
284
|
+
# recipients = [
|
285
|
+
# {:name => "RightSignature", :email => "support@rightsignature.com", :role => 'cc'},
|
286
|
+
# {:name => "John Bellingham", :email => "john@rightsignature.com", :role => 'signer'},
|
287
|
+
# {'is_sender' => true, :role => 'signer'},
|
288
|
+
# ]
|
289
|
+
# document_data = {:type => 'base64', :filename => "originalfile.pdf", :value => Base64.encode64(File.read('myfile.pdf','r'))}
|
290
|
+
# options = {
|
291
|
+
# :tags => ['sent_from_api', 'user_id' => '12345'],
|
292
|
+
# :expires_in => '5 days',
|
293
|
+
# :action => "redirect",
|
294
|
+
# 'callback_location' => "http://example.com/doc_callback",
|
295
|
+
# 'use_text_tags' => false
|
296
|
+
# }
|
297
|
+
# @rs_connection.generate_document_redirect_url( "My Subject", recipients, document_data, options)
|
298
|
+
#
|
299
|
+
def generate_document_redirect_url(subject, recipients, document_data, options={})
|
300
|
+
options[:action] = "redirect"
|
301
|
+
response = send_document(subject, recipients, document_data, options)
|
302
|
+
|
303
|
+
"#{site}/builder/new?rt=#{response['document']['redirect_token']}"
|
304
|
+
end
|
305
|
+
|
306
|
+
# Generates signer links for a Document with signers with email of "noemail@rightsignature.com"
|
307
|
+
# * <b>guid</b>: Document GUID
|
308
|
+
# * <b>redirect_location</b>: (Optional) URL to redirect each signer after it is completed
|
309
|
+
#
|
310
|
+
# Ex. Generate signer links for document GUID123 that redirects users to http://mysite/done_signing after signing
|
311
|
+
# @rs_connection.get_document_signer_links_for("GUID123", "http://mysite/done_signing")
|
312
|
+
#
|
313
|
+
# Note that ONLY recipients with an email of "noemail@rightsignature.com" will have a signer link
|
314
|
+
def get_document_signer_links_for(guid, redirect_location = nil)
|
315
|
+
params = {}
|
316
|
+
params[:redirect_location] = URI.encode(redirect_location) if redirect_location
|
317
|
+
response = get "/api/documents/#{guid}/signer_links.xml", params
|
318
|
+
|
319
|
+
signer_links = []
|
320
|
+
|
321
|
+
if response["document"]["signer_links"] && response["document"]["signer_links"]["signer_link"].is_a?(Array)
|
322
|
+
response["document"]["signer_links"]["signer_link"].each do |signer_link|
|
323
|
+
signer_links << {"name" => signer_link["name"], "url" => "#{site}/signatures/embedded?rt=#{signer_link["signer_token"]}"}
|
324
|
+
end
|
325
|
+
elsif response["document"]["signer_links"]
|
326
|
+
signer_link = response["document"]["signer_links"]["signer_link"]
|
327
|
+
signer_links << {"name" => signer_link["name"], "url" => "#{site}/signatures/embedded?rt=#{signer_link["signer_token"]}"}
|
328
|
+
end
|
329
|
+
signer_links
|
330
|
+
end
|
331
|
+
|
332
|
+
end
|
333
|
+
end
|