From 20620bcff411e686303a5c23f62b4687a3f9e1de Mon Sep 17 00:00:00 2001 From: MattKingDS <43220771+MattKingDS@users.noreply.github.com> Date: Fri, 18 Oct 2019 09:35:56 -0700 Subject: [PATCH 1/2] Updating for new GA Client Libraries --- .DS_Store | Bin 0 -> 6148 bytes Gemfile | 2 +- Gemfile.lock | 209 +++++++++--------- README.md | 48 ++-- app/.DS_Store | Bin 0 -> 6148 bytes app/controllers/.DS_Store | Bin 0 -> 6148 bytes .../eg015_get_envelope_tab_data_controller.rb | 53 +++++ .../eg016_set_envelope_tab_data_controller.rb | 181 +++++++++++++++ ...g017_set_template_tab_values_controller.rb | 160 ++++++++++++++ ...t_envelope_custom_field_data_controller.rb | 53 +++++ app/views/.DS_Store | Bin 0 -> 6148 bytes app/views/ds_common/index.html.erb | 29 ++- .../eg015_get_envelope_tab_data/.DS_Store | Bin 0 -> 6148 bytes .../eg015_get_envelope_tab_data/get.html.erb | 36 +++ .../eg016_set_envelope_tab_data/get.html.erb | 39 ++++ .../eg017_set_template_tab_values/.DS_Store | Bin 0 -> 6148 bytes .../get.html.erb | 59 +++++ .../get.html.erb | 39 ++++ config/application.rb | 2 +- config/routes.rb | 12 + data/World_Wide_Corp_salary.docx | Bin 0 -> 29934 bytes 21 files changed, 789 insertions(+), 133 deletions(-) create mode 100644 .DS_Store create mode 100644 app/.DS_Store create mode 100644 app/controllers/.DS_Store create mode 100644 app/controllers/eg015_get_envelope_tab_data_controller.rb create mode 100644 app/controllers/eg016_set_envelope_tab_data_controller.rb create mode 100644 app/controllers/eg017_set_template_tab_values_controller.rb create mode 100644 app/controllers/eg018_get_envelope_custom_field_data_controller.rb create mode 100644 app/views/.DS_Store create mode 100644 app/views/eg015_get_envelope_tab_data/.DS_Store create mode 100644 app/views/eg015_get_envelope_tab_data/get.html.erb create mode 100644 app/views/eg016_set_envelope_tab_data/get.html.erb create mode 100644 app/views/eg017_set_template_tab_values/.DS_Store create mode 100644 app/views/eg017_set_template_tab_values/get.html.erb create mode 100644 app/views/eg018_get_envelope_custom_field_data/get.html.erb create mode 100644 data/World_Wide_Corp_salary.docx diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c52c2f2476f614466660c884d5c219e2025bd6c0 GIT binary patch literal 6148 zcmeH~&ui2`6vy9m*LIRcjUZUT!+?mFJ?yg9^->7iRuBZm6npT;HZidqh?%gP?PAw0 zp?`pP>(w9shkEfZ(0|0cZ+|e9006}%v}$Ab z2NUa}&DoNksiG2bjX@S9JiyWSAe)Oe6NZ2x@V^ld?`{Qr$RGS|YE%2X{mkp}k(c}VaM1DlPsHe(@>a5kibD9yo zdh_n1=fk77$L~LU{Pg+DSD6JRrb}vE_TSK(0dfjf8EBjZBA{OyT3eu+OeuzdA#gSX z#P@+=6Y6R$l*&&BcJc^-Dt;rRp)bx7B8O>pwH8Wo1&ydwRFz8f5re37oM$@D)mkW3 z=|J@1gXlXGeL^Af?s$DB!-2R;O>YPo0<#1vYUqglf9vn(|JfunG6W2Pg(5(zo8D#z zOVWGmTybKrW!QGH2@`RJQkjCC-j1asw&GQ6(r}Fl2i4VDD8(5x^CKWJn9dORrv!cj DEtsQ8 literal 0 HcmV?d00001 diff --git a/Gemfile b/Gemfile index 9a36598..96ecd20 100644 --- a/Gemfile +++ b/Gemfile @@ -61,4 +61,4 @@ end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] gem 'omniauth-oauth2' -gem 'docusign_esign' +gem 'docusign_esign', '=2.1.0' diff --git a/Gemfile.lock b/Gemfile.lock index 3182d6c..00486fb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,68 +1,67 @@ GEM remote: https://rubygems.org/ specs: - actioncable (5.2.1) - actionpack (= 5.2.1) + actioncable (5.2.3) + actionpack (= 5.2.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.1) - actionpack (= 5.2.1) - actionview (= 5.2.1) - activejob (= 5.2.1) + actionmailer (5.2.3) + actionpack (= 5.2.3) + actionview (= 5.2.3) + activejob (= 5.2.3) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.2.1) - actionview (= 5.2.1) - activesupport (= 5.2.1) + actionpack (5.2.3) + actionview (= 5.2.3) + activesupport (= 5.2.3) rack (~> 2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.1) - activesupport (= 5.2.1) + actionview (5.2.3) + activesupport (= 5.2.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.2.1) - activesupport (= 5.2.1) + activejob (5.2.3) + activesupport (= 5.2.3) globalid (>= 0.3.6) - activemodel (5.2.1) - activesupport (= 5.2.1) - activerecord (5.2.1) - activemodel (= 5.2.1) - activesupport (= 5.2.1) + activemodel (5.2.3) + activesupport (= 5.2.3) + activerecord (5.2.3) + activemodel (= 5.2.3) + activesupport (= 5.2.3) arel (>= 9.0) - activestorage (5.2.1) - actionpack (= 5.2.1) - activerecord (= 5.2.1) + activestorage (5.2.3) + actionpack (= 5.2.3) + activerecord (= 5.2.3) marcel (~> 0.3.1) - activesupport (5.2.1) + activesupport (5.2.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.5.2) - public_suffix (>= 2.0.2, < 4.0) - archive-zip (0.11.0) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + archive-zip (0.12.0) io-like (~> 0.3.0) arel (9.0.0) - bindex (0.5.0) - bootsnap (1.3.2) + bindex (0.8.1) + bootsnap (1.4.5) msgpack (~> 1.0) builder (3.2.3) - byebug (10.0.2) - capybara (3.11.1) + byebug (11.0.1) + capybara (3.29.0) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) - regexp_parser (~> 1.2) + regexp_parser (~> 1.5) xpath (~> 3.2) - childprocess (0.9.0) - ffi (~> 1.0, >= 1.0.11) - chromedriver-helper (2.1.0) + childprocess (3.0.0) + chromedriver-helper (2.1.1) archive-zip (~> 0.10) nokogiri (~> 1.8) coffee-rails (4.2.2) @@ -72,35 +71,34 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.1.3) - crass (1.0.4) - docusign_esign (1.0.0) - json (~> 1.8, >= 1.8.3) - jwt (~> 2.0, >= 2.0.0) + concurrent-ruby (1.1.5) + crass (1.0.5) + docusign_esign (3.0.0) + json (~> 2.1, >= 2.1.0) + jwt (~> 1.0, >= 1.5.2) typhoeus (~> 1.0, >= 1.0.1) - erubi (1.7.1) - ethon (0.11.0) + erubi (1.9.0) + ethon (0.12.0) ffi (>= 1.3.0) execjs (2.7.0) - faraday (0.15.3) + faraday (0.17.0) multipart-post (>= 1.2, < 3) - ffi (1.9.25) - globalid (0.4.1) + ffi (1.11.1) + globalid (0.4.2) activesupport (>= 4.2.0) - hashie (3.5.7) - i18n (1.1.1) + hashie (3.6.0) + i18n (1.7.0) concurrent-ruby (~> 1.0) io-like (0.3.0) - jbuilder (2.8.0) + jbuilder (2.9.1) activesupport (>= 4.2.0) - multi_json (>= 1.2) - json (1.8.6) - jwt (2.1.0) + json (2.2.0) + jwt (1.5.6) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) - loofah (2.2.3) + loofah (2.3.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) @@ -108,81 +106,80 @@ GEM marcel (0.3.3) mimemagic (~> 0.3.2) method_source (0.9.2) - mimemagic (0.3.2) - mini_mime (1.0.1) - mini_portile2 (2.3.0) - minitest (5.11.3) - msgpack (1.2.4) - multi_json (1.13.1) + mimemagic (0.3.3) + mini_mime (1.0.2) + mini_portile2 (2.4.0) + minitest (5.12.2) + msgpack (1.3.1) + multi_json (1.14.1) multi_xml (0.6.0) - multipart-post (2.0.0) - nio4r (2.3.1) - nokogiri (1.8.5) - mini_portile2 (~> 2.3.0) - oauth2 (1.4.1) - faraday (>= 0.8, < 0.16.0) + multipart-post (2.1.1) + nio4r (2.5.2) + nokogiri (1.10.4) + mini_portile2 (~> 2.4.0) + oauth2 (1.4.2) + faraday (>= 0.8, < 2.0) jwt (>= 1.0, < 3.0) multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - omniauth (1.8.1) - hashie (>= 3.4.6, < 3.6.0) + omniauth (1.9.0) + hashie (>= 3.4.6, < 3.7.0) rack (>= 1.6.2, < 3) - omniauth-oauth2 (1.5.0) + omniauth-oauth2 (1.6.0) oauth2 (~> 1.1) - omniauth (~> 1.2) - public_suffix (3.0.3) - puma (3.12.0) - rack (2.0.6) + omniauth (~> 1.9) + public_suffix (4.0.1) + puma (3.12.1) + rack (2.0.7) rack-test (1.1.0) rack (>= 1.0, < 3) - rails (5.2.1) - actioncable (= 5.2.1) - actionmailer (= 5.2.1) - actionpack (= 5.2.1) - actionview (= 5.2.1) - activejob (= 5.2.1) - activemodel (= 5.2.1) - activerecord (= 5.2.1) - activestorage (= 5.2.1) - activesupport (= 5.2.1) + rails (5.2.3) + actioncable (= 5.2.3) + actionmailer (= 5.2.3) + actionpack (= 5.2.3) + actionview (= 5.2.3) + activejob (= 5.2.3) + activemodel (= 5.2.3) + activerecord (= 5.2.3) + activestorage (= 5.2.3) + activesupport (= 5.2.3) bundler (>= 1.3.0) - railties (= 5.2.1) + railties (= 5.2.3) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.0.4) - loofah (~> 2.2, >= 2.2.2) - railties (5.2.1) - actionpack (= 5.2.1) - activesupport (= 5.2.1) + rails-html-sanitizer (1.3.0) + loofah (~> 2.3) + railties (5.2.3) + actionpack (= 5.2.3) + activesupport (= 5.2.3) method_source rake (>= 0.8.7) thor (>= 0.19.0, < 2.0) - rake (12.3.1) + rake (13.0.0) rb-fsevent (0.10.3) - rb-inotify (0.9.10) - ffi (>= 0.5.0, < 2) - regexp_parser (1.3.0) + rb-inotify (0.10.0) + ffi (~> 1.0) + regexp_parser (1.6.0) ruby_dep (1.5.0) - rubyzip (1.2.2) - sass (3.7.2) + rubyzip (2.0.0) + sass (3.7.4) sass-listen (~> 4.0.0) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - sass-rails (5.0.7) - railties (>= 4.0.0, < 6) + sass-rails (5.1.0) + railties (>= 5.2.0) sass (~> 3.1) sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - selenium-webdriver (3.141.0) - childprocess (~> 0.5) - rubyzip (~> 1.2, >= 1.2.2) - spring (2.0.2) - activesupport (>= 4.2) + selenium-webdriver (3.142.6) + childprocess (>= 0.5, < 4.0) + rubyzip (>= 1.2.2) + spring (2.1.0) spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) spring (>= 1.2, < 3.0) @@ -193,27 +190,27 @@ GEM actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - sqlite3 (1.3.13) + sqlite3 (1.4.1) thor (0.20.3) thread_safe (0.3.6) - tilt (2.0.8) - turbolinks (5.2.0) + tilt (2.0.10) + turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) typhoeus (1.3.1) ethon (>= 0.9.0) tzinfo (1.2.5) thread_safe (~> 0.1) - uglifier (4.1.20) + uglifier (4.2.0) execjs (>= 0.3.0, < 3) web-console (3.7.0) actionview (>= 5.0) activemodel (>= 5.0) bindex (>= 0.4.0) railties (>= 5.0) - websocket-driver (0.7.0) + websocket-driver (0.7.1) websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.3) + websocket-extensions (0.1.4) xpath (3.2.0) nokogiri (~> 1.8) @@ -226,7 +223,7 @@ DEPENDENCIES capybara (>= 2.15) chromedriver-helper coffee-rails (~> 4.2) - docusign_esign + docusign_esign (>= 3.0) jbuilder (~> 2.5) listen (>= 3.0.5, < 3.2) omniauth-oauth2 @@ -246,4 +243,4 @@ RUBY VERSION ruby 2.5.3p105 BUNDLED WITH - 1.17.1 + 1.17.2 diff --git a/README.md b/README.md index 5c3c721..20632f0 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This repo is a Ruby on Rails application that demonstrates: The [OmniAuth](https://github.com/omniauth/omniauth) library is used for authentication. This example includes a DocuSign OAuth2 - [strategy](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/lib/docusign.rb) + [strategy](./lib/docusign.rb) for the OAuth package. The DocuSign strategy: * Uses the Authorization Code Grant flow to obtain an access token. @@ -22,75 +22,77 @@ This repo is a Ruby on Rails application that demonstrates: account id, account name, and base path. In this example, OmniAuth is called from - [session_controller.rb](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/session_controller.rb). + [session_controller.rb](./app/controllers/session_controller.rb). OmniAuth is additionally configured and referenced in other files; search the project for "omni" for a complete list. ### Example Workflows This launcher includes code examples for the following workflows: 1. **Embedded Signing Ceremony.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg001_embedded_signing_controller.rb) + [Source.](./app/controllers/eg001_embedded_signing_controller.rb) This example sends an envelope, and then uses an embedded signing ceremony for the first signer. With embedded signing, the DocuSign signing ceremony is initiated from your website. 1. **Send an envelope with a remote (email) signer and cc recipient.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg002_signing_via_email_controller.rb) + [Source.](./app/controllers/eg002_signing_via_email_controller.rb) The envelope includes a pdf, Word, and HTML document. Anchor text ([AutoPlace](https://support.docusign.com/en/guides/AutoPlace-New-DocuSign-Experience)) is used to position the signing fields in the documents. 1. **List envelopes in the user's account.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg003_list_envelopes_controller.rb) + [Source.](./app/controllers/eg003_list_envelopes_controller.rb) The envelopes' current status is included. 1. **Get an envelope's basic information.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg004_envelope_info_controller.rb) + [Source.](./app/controllers/eg004_envelope_info_controller.rb) The example lists the basic information about an envelope, including its overall status. 1. **List an envelope's recipients** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg005_envelope_recipients_controller.rb) + [Source.](./app/controllers/eg005_envelope_recipients_controller.rb) Includes current recipient status. 1. **List an envelope's documents.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg006_envelope_docs_controller.rb) + [Source.](./app/controllers/eg006_envelope_docs_controller.rb) 1. **Download an envelope's documents.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg007_envelope_get_doc_controller.rb) + [Source.](./app/controllers/eg007_envelope_get_doc_controller.rb) The example can download individual documents, the documents concatenated together, or a zip file of the documents. 1. **Programmatically create a template.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg008_create_template_controller.rb) + [Source.](./app/controllers/eg008_create_template_controller.rb) 1. **Send an envelope using a template.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg009_use_template_controller.rb) + [Source.](./app/controllers/eg009_use_template_controller.rb) 1. **Send an envelope and upload its documents with multpart binary transfer.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg010_send_binary_docs_controller.rb) + [Source.](./app/controllers/eg010_send_binary_docs_controller.rb) Binary transfer is 33% more efficient than using Base64 encoding. 1. **Embedded sending.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg011_embedded_sending_controller.rb) + [Source.](./app/controllers/eg011_embedded_sending_controller.rb) Embeds the DocuSign web tool (NDSE) in your web app to finalize or update the envelope and documents before they are sent. 1. **Embedded DocuSign web tool (NDSE).** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg012_embedded_console_controller.rb) + [Source.](./app/controllers/eg012_embedded_console_controller.rb) 1. **Embedded Signing Ceremony from a template with an added document.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg013_add_doc_to_template_controller.rb) + [Source.](./app/controllers/eg013_add_doc_to_template_controller.rb) This example sends an envelope based on a template. In addition to the template's document(s), the example adds an additional document to the envelope by using the [Composite Templates](https://developers.docusign.com/esign-rest-api/guides/features/templates#composite-templates) feature. 1. **Payments example: an order form, with online payment by credit card.** - [Source.](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/app/controllers/eg014_collect_payment_controller.rb) + [Source.](./app/controllers/eg014_collect_payment_controller.rb) + - + [Source.](./app/controllers/EG018EnvelopeCustomFieldData_controller.rb) + + + ## Installation @@ -140,7 +142,7 @@ To use the payments example, create a test payments gateway for your developer sandbox account. See the -[PAYMENTS_INSTALLATION.md](https://github.com/docusign/eg-03-ruby-auth-code-grant/blob/master/PAYMENTS_INSTALLATION.md) +[PAYMENTS_INSTALLATION.md](./PAYMENTS_INSTALLATION.md) file for instructions. Then add the payment gateway account id to the **config/application.rb** file. diff --git a/app/.DS_Store b/app/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..eb00aa15c3d27ec0805754d716a4fd514252bc87 GIT binary patch literal 6148 zcmeHK&2G~`5T0#Qx=B@$15$h3OK(9+M1SB=$x6$C8+sF)0xfBfxIh){STo;vcV?~mq}}xpkr+-!1EMYwNho8h19OY;JnM`sxseu7 zm^E_Jl;RmvJ`?Q+JOiGAyT$@x^DNcb8$@vS3SCixbF8B4JbeA%JZ#qWU}vYN z1}OedL~x;yxkP-%Oy-;7DXTUS?*9`FaprDL_!^WaHI$%r- z0Oa2YBk;MG;2h;JaM)PH3`E#epiLF7#Sk_flyG2++<+czIOTke>%VaznSFUJOiGAge82BsMJEInNp&A#VD(Jocz9x~BuZUOl zGN+w9F@G8Hl-@PR>sG`CM_-s-h#9qWTyZ2|$@%#&^1NuG-q6eEKVvh`F(b{%LB+et z@q}mE1@gQNuJ_?7w0krLjDcM2|$$3 z$SCYfEg?2OVV1B~zRd+89fgta0^DE1)`X|To^*eL@a!T*+i literal 0 HcmV?d00001 diff --git a/app/controllers/eg015_get_envelope_tab_data_controller.rb b/app/controllers/eg015_get_envelope_tab_data_controller.rb new file mode 100644 index 0000000..851f68f --- /dev/null +++ b/app/controllers/eg015_get_envelope_tab_data_controller.rb @@ -0,0 +1,53 @@ +class Eg015GetEnvelopeTabDataController < EgController + skip_before_action :verify_authenticity_token + def eg_name + 'eg015' + end + def get_file_name + File.basename __FILE__ + end + + def create + minimum_buffer_min = 3 + envelope_id = session[:envelope_id]? session[:envelope_id] : nil + token_ok = check_token(minimum_buffer_min) + if token_ok + # Call the worker method + access_token = session['ds_access_token'] + base_url = session['ds_base_path'] + account_id = session['ds_account_id'] + + results = worker access_token, base_url, account_id, envelope_id + @h1 = 'List envelopes results' + @message = 'Results from the Envelopes::listStatusChanges method:' + @json = results.to_json.to_json + render 'ds_common/example_done' + else + flash[:messages] = 'Sorry, you need to re-authenticate.' + # We could store the parameters of the requested operation + # so it could be restarted automatically. + # But since it should be rare to have a token issue here, + # we'll make the user re-enter the form data after + # authentication. + redirect_to '/ds/mustAuthenticate' + end + end + + # ***DS.snippet.0.start + def worker (access_token, base_url, account_id, envelope_id) + configuration = DocuSign_eSign::Configuration.new + configuration.host = base_url + api_client = DocuSign_eSign::ApiClient.new configuration + api_client.default_headers['Authorization'] = 'Bearer ' + access_token + envelope_api = DocuSign_eSign::EnvelopesApi.new api_client + + # Step 1. List the envelope form data + # The Envelopes::getEnvelopeFormData method has many options + # See https://developers.docusign.com/esign-rest-api/reference/Envelopes/EnvelopeFormData/get + # The get form data call requires an account ID and an envelope ID + + # Exceptions will be caught by the calling function + results = envelope_api.get_form_data account_id, envelope_id + end + # ***DS.snippet.0.end +end \ No newline at end of file diff --git a/app/controllers/eg016_set_envelope_tab_data_controller.rb b/app/controllers/eg016_set_envelope_tab_data_controller.rb new file mode 100644 index 0000000..401abaf --- /dev/null +++ b/app/controllers/eg016_set_envelope_tab_data_controller.rb @@ -0,0 +1,181 @@ +class Eg016SetEnvelopeTabDataController < EgController + skip_before_action :verify_authenticity_token + def eg_name + 'eg016' + end + def get_file_name + File.basename __FILE__ + end + + def create + minimum_buffer_min = 10 + token_ok = check_token(minimum_buffer_min) + if !token_ok + flash[:messages] = 'Sorry, you need to re-authenticate.' + # We could store the parameters of the requested operation so it could be restarted + # automatically. But since it should be rare to have a token issue here, + # we'll make the user re-enter the form data after authentication + redirect_to '/ds/mustAuthenticate' + end + + # Validation: Delete any non-usual characters + signer_email = request.params[:signerEmail].gsub(/([^\w \-\@\.\,])+/, '') + signer_name = request.params[:signerName].gsub(/([^\w \-\@\.\,])+/, '') + access_token = session['ds_access_token'] + base_url = session['ds_base_path'] + account_id = session['ds_account_id'] + + redirect_url = worker access_token, base_url, account_id, signer_email, signer_name + redirect_to redirect_url + end + + # ***DS.snippet.0.start + def worker (access_token, base_url, account_id, signer_email, signer_name) + ds_ping_url = 'http://localhost:3000/' + ds_return_url = "#{Rails.application.config.app_url}/ds_common-return" + signer_client_id = 1000 + pdf_filename = 'World_Wide_Corp_salary.docx' + + # Step 1. Create the envelope definition + envelope = make_envelope(signer_email, signer_name, signer_client_id, pdf_filename); + + # Step 2. Call DocuSign to create the envelope + configuration = DocuSign_eSign::Configuration.new + configuration.host = base_url + api_client = DocuSign_eSign::ApiClient.new configuration + api_client.default_headers['Authorization'] = "Bearer " + access_token + envelope_api = DocuSign_eSign::EnvelopesApi.new api_client + + results = envelope_api.create_envelope account_id, envelope + envelope_id = results.envelope_id + # Save for future use within the example launcher + session[:envelope_id] = envelope_id + + # Step 3. Create the recipient view, the Signing Ceremony + view_request = make_recipient_view_request( + signer_email, signer_name, signer_client_id, ds_return_url, ds_ping_url) + + # Call the CreateRecipientView API + results = envelope_api.create_recipient_view account_id, envelope_id, view_request + + # Step 4. Redirect the user to the Signing Ceremony + # Don't use an iframe! + # State can be stored/recovered using the framework's session or a + # query parameter on the return URL (see the makeRecipientViewRequest method) + # redirect to results.url + results.url + end + + def make_recipient_view_request(signer_email, signer_name, signer_client_id, + ds_return_url, ds_ping_url) + view_request = DocuSign_eSign::RecipientViewRequest.new + # Set the URL where you want the recipient to go once they are done signing; this + # should typically be a callback route somewhere in your app. The query parameter + # is included as an example of how to save/recover state information during the redirect + # to the DocuSign signing ceremony. It's usually better to use the session mechanism + # of your web framework. Query parameters can be changed/spoofed very easily + view_request.return_url = ds_return_url + '?state=123' + + # How has your app authenticated the user? In addition to your app's authentication, + # you can include authenticate steps from DocuSign; e.g., SMS authentication + view_request.authentication_method = 'none' + + # Recipient information must match embedded recipient info we used to create the envelope + view_request.email = signer_email + view_request.user_name = signer_name + view_request.client_user_id = signer_client_id + + # DocuSign recommends that you redirect to DocuSign for the signing ceremony. There are + # multiple ways to save state. To maintain your application's session, use the pingUrl + # parameter. It causes the DocuSign Signing Ceremony web page (not the DocuSign server) + # to send pings via AJAX to your app + view_request.ping_frequency = '600' # seconds + # NOTE: The pings will only be sent if the pingUrl is an HTTPS address + view_request.ping_url = ds_ping_url # optional setting + + view_request + end + + def make_envelope(signer_email, signer_name, signer_client_id, pdf_filename) + envelope_definition = DocuSign_eSign::EnvelopeDefinition.new + envelope_definition.email_subject = 'Please sign this document sent from Ruby SDK' + + doc1 = DocuSign_eSign::Document.new + doc1.document_base64 = Base64.encode64(File.binread(File.join('data', pdf_filename))) + doc1.name = 'Lorem Ipsum' + doc1.file_extension = 'docx' + doc1.document_id = '1' + + # The order in the docs array determines the order in the envelope + envelope_definition.documents = [doc1] + # Create a signer recipient to sign the document, identified by name and email + # We're setting the parameters via the object creation + signer1 = DocuSign_eSign::Signer.new ({ + email: signer_email, name: signer_name, + clientUserId: signer_client_id, recipientId: 1 + }) + salary = '$123,000' + + sign_here1 = DocuSign_eSign::SignHere.new + sign_here1.anchor_string = '/sn1/' + sign_here1.anchor_units = 'pixels' + sign_here1.anchor_x_offset = '20' + sign_here1.anchor_y_offset = '10' + + text_legal = DocuSign_eSign::Text.new + text_legal.anchor_string = '/legal/' + text_legal.anchor_units = 'pixels' + text_legal.anchor_y_offset = '-9' + text_legal.anchor_x_offset = '5' + text_legal.font = 'Helvetica' + text_legal.font_size = 'size11' + text_legal.bold = 'true' + text_legal.value = signer_name + text_legal.locked = 'false' + text_legal.tab_id = 'legal_name' + text_legal.tab_label = 'Legal name' + + text_familiar = DocuSign_eSign::Text.new + text_familiar.anchor_string = '/familiar/' + text_familiar.anchor_units = 'pixels' + text_familiar.anchor_y_offset = '-9' + text_familiar.anchor_y_offset = '5' + text_familiar.font = 'Helvetica' + text_familiar.font_size = 'size11' + text_familiar.bold = 'true' + text_familiar.value = signer_name + text_familiar.locked = 'false' + text_familiar.tab_id = 'familiar_name' + text_familiar.tab_label = 'Familiar name' + + text_salary = DocuSign_eSign::Text.new + text_salary.anchor_string = '/salary/' + text_salary.anchor_units = 'pixels' + text_salary.anchor_y_offset = '-9' + text_salary.anchor_y_offset = '5' + text_salary.font = 'Helvetica' + text_salary.font_size = 'size11' + text_salary.bold = 'true' + text_salary.value = salary + text_salary.locked = 'true' + text_salary.tab_id = 'salary' + text_salary.tab_label = 'Salary' + + # Tabs are set per recipient / signer + tabs = DocuSign_eSign::Tabs.new + tabs.sign_here_tabs = [sign_here1] + tabs.text_tabs = [text_legal, text_familiar, text_salary] + + signer1.tabs = tabs + # Add the recipients to the envelope object + recipients = DocuSign_eSign::Recipients.new + recipients.signers = [signer1] + + envelope_definition.recipients = recipients + # Request that the envelope be sent by setting |status| to "sent". + # To request that the envelope be created as a draft, set to "created" + envelope_definition.status = 'sent' + envelope_definition + end + # ***DS.snippet.0.end +end \ No newline at end of file diff --git a/app/controllers/eg017_set_template_tab_values_controller.rb b/app/controllers/eg017_set_template_tab_values_controller.rb new file mode 100644 index 0000000..71a4937 --- /dev/null +++ b/app/controllers/eg017_set_template_tab_values_controller.rb @@ -0,0 +1,160 @@ +class Eg017SetTemplateTabValuesController < EgController + skip_before_action :verify_authenticity_token + def eg_name + "eg017" + end + def get_file_name + File.basename __FILE__ + end + + def create + minimum_buffer_min = 3 + template_id = session[:template_id]? session[:template_id] : nil + token_ok = check_token(minimum_buffer_min) + + if token_ok && template_id + # 2. Call the worker method + # More data validation would be a good idea here + # Strip anything other than characters listed + envelope_args = { + :signer_email => request.params['signerEmail'], + :signer_name => request.params['signerName'], + :cc_email => request.params['ccEmail'], + :cc_name => request.params['ccName'], + :template_id => template_id + } + + args = { + :account_id => session['ds_account_id'], + :base_path => session['ds_base_path'], + :access_token => session['ds_access_token'], + :envelope_args => envelope_args + } + + begin + results = worker args + # results is an object that implements ArrayAccess. Convert to a regular array: + @title = 'Envelope sent' + @h1 = 'Envelope sent' + @message = "The envelope has been created and sent!
Envelope ID #{results["envelope_id"]}." + render 'ds_common/example_done' + rescue DocuSign_eSign::ApiError => e + error = JSON.parse e.response_body + @error_code = error['errorCode'] + @error_message = error['message'] + render "ds_common/error" + end + elsif !token_ok + flash[:messages] = 'Sorry, you need to re-authenticate.' + # We could store the parameters of the requested operation + # so it could be restarted automatically. + # But since it should be rare to have a token issue here, + # we'll make the user re-enter the form data after + # authentication. + redirect_to '/ds/mustAuthenticate' + elsif !template_id + @title = 'Use a template to send an envelope' + @template_ok = false + end + end + + # ***DS.snippet.0.start + def worker(args) + envelope_args = args[:envelope_args] + # 1. Create the envelope request object + envelope_definition = make_envelope(envelope_args) + # 2. call Envelopes::create API method + # Exceptions will be caught by the calling function + configuration = DocuSign_eSign::Configuration.new + configuration.host = args[:base_path] + api_client = DocuSign_eSign::ApiClient.new configuration + api_client.default_headers["Authorization"] = "Bearer #{args[:access_token]}" + envelope_api = DocuSign_eSign::EnvelopesApi.new(api_client) + results = envelope_api.create_envelope args[:account_id], envelope_definition + envelope_id = results.envelope_id + {'envelope_id' => envelope_id} + end + + def make_envelope(args) + # create the envelope definition with the template_id + envelope_definition = DocuSign_eSign::EnvelopeDefinition.new({ + :status => 'sent', + :templateId => args[:template_id] + }) + # Create the template role elements to connect the signer and cc recipients + # to the template + signer = DocuSign_eSign::TemplateRole.new({ + :email => args[:signer_email], + :name => args[:signer_name], + :roleName => 'signer' + }) + # Create a cc template role. + cc = DocuSign_eSign::TemplateRole.new({ + :email => args[:cc_email], + :name => args[:cc_name], + :roleName => 'cc' + }) + # Set values for the fields in the template + + #List item + list1 = DocuSign_eSign::List.new + list1.value = 'Green' + list1.document_id = '1' + list1.page_number = '1' + list1.tab_label = 'list' + + #Checkboxes + check1 = DocuSign_eSign::Checkbox.new + check1.tab_label = 'ckAuthorization' + check1.selected = 'true' + + check3 = DocuSign_eSign::Checkbox.new + check3.tab_label = 'ckAgreement' + check3.selected = 'true' + + radioGroup = DocuSign_eSign::RadioGroup.new + radioGroup.group_name = 'radio1' + radio = DocuSign_eSign::Radio.new + radio.value = 'white' + radio.selected = 'true' + radioGroup.radios = [radio] + + text = DocuSign_eSign::Text.new + text.tab_label = 'text' + text.value = 'Jabberwocky!' + + #We can also add a new tab (field) to the ones already in the template: + textExtra = DocuSign_eSign::Text.new + textExtra.document_id = '1' + textExtra.page_number = '1' + textExtra.x_position = '280' + textExtra.y_position = '172' + textExtra.font = 'helvetica' + textExtra.font_size = 'size14' + textExtra.tab_label = 'added text field' + textExtra.height = '23' + textExtra.width = '84' + textExtra.required = 'false' + textExtra.bold = 'true' + textExtra.value = args[:signer_name] + textExtra.locked = 'false' + textExtra.tab_id = 'name' + + + #Pull together the existing and new tabs in a Tabs object: + tabs = DocuSign_eSign::Tabs.new + tabs.list_tabs = [list1] + tabs.checkbox_tabs = [check1, check3] + tabs.radio_group_tabs = [radioGroup] + tabs.text_tabs = [text, textExtra] + + signer.tabs = tabs + + + + # Add the TemplateRole objects to the envelope object + envelope_definition.template_roles = [signer, cc] + envelope_definition + end + # ***DS.snippet.0.end +end \ No newline at end of file diff --git a/app/controllers/eg018_get_envelope_custom_field_data_controller.rb b/app/controllers/eg018_get_envelope_custom_field_data_controller.rb new file mode 100644 index 0000000..5d953cb --- /dev/null +++ b/app/controllers/eg018_get_envelope_custom_field_data_controller.rb @@ -0,0 +1,53 @@ +class Eg018GetEnvelopeCustomFieldDataController < EgController + skip_before_action :verify_authenticity_token + def eg_name + 'eg018' + end + def get_file_name + File.basename __FILE__ + end + + def create + minimum_buffer_min = 3 + envelope_id = session[:envelope_id]? session[:envelope_id] : nil + token_ok = check_token(minimum_buffer_min) + if token_ok + # Call the worker method + access_token = session['ds_access_token'] + base_url = session['ds_base_path'] + account_id = session['ds_account_id'] + + results = worker access_token, base_url, account_id, envelope_id + @h1 = 'List envelopes results' + @message = 'Results from the Envelopes::listStatusChanges method:' + @json = results.to_json.to_json + render 'ds_common/example_done' + else + flash[:messages] = 'Sorry, you need to re-authenticate.' + # We could store the parameters of the requested operation + # so it could be restarted automatically. + # But since it should be rare to have a token issue here, + # we'll make the user re-enter the form data after + # authentication. + redirect_to '/ds/mustAuthenticate' + end + end + + # ***DS.snippet.0.start + def worker (access_token, base_url, account_id, envelope_id) + configuration = DocuSign_eSign::Configuration.new + configuration.host = base_url + api_client = DocuSign_eSign::ApiClient.new configuration + api_client.default_headers['Authorization'] = 'Bearer ' + access_token + envelope_api = DocuSign_eSign::EnvelopesApi.new api_client + + # Step 1. List the envelope custom fields + # The Envelopes::getEnvelopeFormData method has many options + # See https://developers.docusign.com/esign-rest-api/reference/Envelopes/EnvelopeFormData/get + # The get custom fields call requires an account ID and an envelope ID + + # Exceptions will be caught by the calling function + results = envelope_api.list_custom_fields account_id, envelope_id + end + # ***DS.snippet.0.end +end diff --git a/app/views/.DS_Store b/app/views/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d4a0fa470f59959ca1974fb7586a6e34f187a60b GIT binary patch literal 6148 zcmeH~(QeZ)6o!wtvZY0cUQBEVA^C>8A~lSzaDfzc5x_@Je5s$H>3rf(R!DlpxX2mE<^9Xrg zqEVU@WxM@NtgY8>Y-~DC!)e@Vy!VgtnO}zGr09j?x7>OemPe7PzsmD;Sr4PvNq-hJ zxAya_43n%sR>?`+$B=h#k}S?=y?m0zg__6L9gb6X>Opg7K6iIJE$Mdl7A-mNcH1ra zcz18Hs5{#a+-ENihsPi09~UQ|^sgZBl2Uft=nwgf%5OoK`r|CkvjOsW&U*%+OC8`E zpjE0DVMbHbQ_5)s4G<0SY7781sh~pg8`%9=@AS(>i5;_FVR3Ti2 zIz=R<3Hpl_uwVc68okSF^l3{zbRRwWC0SmCuuB)|DLSvfT$*v7(MqdM zCt)rh!aP}+8;Vd*$NW+aC*f(e-V(3`&JtMH%_g7!&o96KpG~qYOTZHNuLy|Rfq&4$ zS2Abog)hfvtwcFQVdHU?R+R#0j$>8fqj(2J8Tuqwpq|l6DEnvelopes::create and EnvelopeViews::createRecipient.

- -

Payments Example

14. Send an envelope with an order form and payment field

Anchor text (AutoPlace) @@ -137,6 +135,33 @@ Envelopes::create.

+

15. Get the tab data from an envelope

+

This example retrieves the tab (field) values from an envelope.

+

+ API method used: + EnvelopeFormData::get. +

+ +

16. Set tab values for a envelope

+

This example sets the tab (field) values for an envelope including tabs that can and cannot be changed by the signer.

+

+ API method used: + Envelopes::create. +

+ +

17. Set template tab values

+

This example sets the tab (field) values for a template being used by an envelope.

+

+ API method used: + Envelopes::create. +

+ +

18. List envelope custom metadata field values

+

This example lists the envelope's custom metadata field values.

+

+ API method used: + EnvelopeCustomFields::list. +

diff --git a/app/views/eg015_get_envelope_tab_data/.DS_Store b/app/views/eg015_get_envelope_tab_data/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T015. Get the tab data from an envelope +

Get the tab (field) values from an envelope for all of the envelope's recipients.

+ +

+ This method is used to read the updated tab values from + the envelope. The method can be used after the envelope is complete or while it is + still in progress. +

+ +<% if @show_doc %> +

Documentation about this example.

+<% end %> + +

API method used: + EnvelopeFormData::get. +

+ +

+ View source file <%= @source_file %> on GitHub. +

+ + <% if @envelope_ok %> +

The envelope you created from an earlier example will be queried.

+ +
+ +
+ +<% else %> +

Problem: please first create an envelope using example 2.
+ Thank you.

+ +
+ +
+<% end %> diff --git a/app/views/eg016_set_envelope_tab_data/get.html.erb b/app/views/eg016_set_envelope_tab_data/get.html.erb new file mode 100644 index 0000000..a320f08 --- /dev/null +++ b/app/views/eg016_set_envelope_tab_data/get.html.erb @@ -0,0 +1,39 @@ + +

16. Set tab values for a envelope

+

+ This example creates an envelope with both read-only tabs (fields) and tabs that can + be updated by the recipient. +

+

The example also sets custom metadata in the envelope via the envelope custom fields feature.

+ + +<% if @show_doc %> +

Documentation about this example.

+<% end %> + +

+ API method used: + Envelopes::create. +

+ + +

+ View source file <%= @source_file %> on GitHub. +

+ + +
+
+ + + We'll never share your email with anyone else. +
+
+ + +
+ +
\ No newline at end of file diff --git a/app/views/eg017_set_template_tab_values/.DS_Store b/app/views/eg017_set_template_tab_values/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T017. Set template tab values +

+ This example sets the value of a template's tabs. It includes setting + radio button and checkbox tabs. +

+

The example also sets custom metadata in the envelope via the envelope custom fields feature.

+ +<% if @show_doc %> +

Documentation about this example.

+<% end %> + +

API method used: + Envelopes::create. +

+ +

+ View source file <%= @source_file %> on GitHub. +

+ + + <% if @template_ok %> +

The template you created via example 8 will be used.

+ +
+
+ + + We'll never share your email with anyone else. +
+
+ + +
+
+ + + The email for the cc recipient must be different from the signer's email. +
+
+ + +
+ +
+ + <% else %> +

Problem: please first create the template using example 8.
+ Thank you.

+ +
+ +
+ <% end %> \ No newline at end of file diff --git a/app/views/eg018_get_envelope_custom_field_data/get.html.erb b/app/views/eg018_get_envelope_custom_field_data/get.html.erb new file mode 100644 index 0000000..832cf50 --- /dev/null +++ b/app/views/eg018_get_envelope_custom_field_data/get.html.erb @@ -0,0 +1,39 @@ +

18. Get the custom field data for an envelope

+

+ Get the data values associated with the envelope itself. The custom data fields enable you to + add additional meta-data to the envelope. The custom data fields can be set by the Sender + via the DocuSign web tool, or can be set programmatically. The data can be included in the + envelope's certificate of completion. +

+ +

+ This method is used to read the custom field values from + an envelope. +

+<% if @show_doc %> +

Documentation about this example.

+<% end %> + +

API method used: + EnvelopeCustomFields::list. +

+ +

+ View source file <%= @source_file %> on GitHub. +

+ + <% if @envelope_ok %> +

The last envelope you created with the launcher will be queried.

+ +
+ +
+ +<% else %> +

Problem: please first create an envelope using example 2.
+ Thank you.

+ +
+ +
+<% end %> diff --git a/config/application.rb b/config/application.rb index 35a7636..58b7c15 100644 --- a/config/application.rb +++ b/config/application.rb @@ -52,4 +52,4 @@ class Application < Rails::Application # -- all .rb files in that directory are automatically loaded after loading # the framework and any gems in your application. end -end +end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index d5da30e..88c49eb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -55,6 +55,18 @@ get 'eg014' => 'eg014_collect_payment#get' post 'eg014' => 'eg014_collect_payment#create' + get 'eg015' => 'eg015_get_envelope_tab_data#get' + post 'eg015' => 'eg015_get_envelope_tab_data#create' + + get 'eg016' => 'eg016_set_envelope_tab_data#get' + post 'eg016' => 'eg016_set_envelope_tab_data#create' + + get 'eg017' => 'eg017_set_template_tab_values#get' + post 'eg017' => 'eg017_set_template_tab_values#create' + + get 'eg018' => 'eg018_get_envelope_custom_field_data#get' + post 'eg018' => 'eg018_get_envelope_custom_field_data#create' + get '/ds_common-return' => 'ds_common#ds_return' get '/ds/mustAuthenticate' => 'ds_common#ds_must_authenticate' diff --git a/data/World_Wide_Corp_salary.docx b/data/World_Wide_Corp_salary.docx new file mode 100644 index 0000000000000000000000000000000000000000..e47e2944ee262f91b84cd7bb90d5e338336c042a GIT binary patch literal 29934 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 literal 0 HcmV?d00001 From 66c1269a2fe300018c2d61bea5c91e228967cf29 Mon Sep 17 00:00:00 2001 From: MattKingDS <43220771+MattKingDS@users.noreply.github.com> Date: Fri, 18 Oct 2019 10:54:44 -0700 Subject: [PATCH 2/2] Update Gemfile --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 96ecd20..c4b6b8a 100644 --- a/Gemfile +++ b/Gemfile @@ -60,5 +60,5 @@ end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] -gem 'omniauth-oauth2' +gem 'omniauth-oauth2','>=1.6' gem 'docusign_esign', '=2.1.0'