rightsignature-railstyle 1.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -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