diff --git a/OAuth/code_grant.php b/OAuth/code_grant.php index e32285b..091d765 100644 --- a/OAuth/code_grant.php +++ b/OAuth/code_grant.php @@ -31,7 +31,7 @@ elseif($api_version == "Maestro") : $scope = "signature aow_manage"; elseif($api_version == "Navigator") : - $scope = "signature adm_store_unified_repo_read"; + $scope = "signature adm_store_unified_repo_read document_uploader_write document_uploader_read"; elseif($api_version == "Workspaces") : $scope = "signature impersonation dtr.company.read dtr.rooms.read dtr.rooms.write dtr.documents.write"; endif; diff --git a/OAuth/jwt.php b/OAuth/jwt.php index 676dd42..f438e2a 100644 --- a/OAuth/jwt.php +++ b/OAuth/jwt.php @@ -34,7 +34,7 @@ } else if ($api_version == "Maestro") { $scope = "signature aow_manage"; } else if ($api_version == "Navigator") { - $scope = "signature adm_store_unified_repo_read"; + $scope = "signature adm_store_unified_repo_read document_uploader_write document_uploader_read"; } else if ($api_version == "ConnectedFields") { $scope = "signature adm_store_unified_repo_read"; } else if ($api_version == "Workspaces") { diff --git a/OAuth/jwt_auth.py b/OAuth/jwt_auth.py index c29ff41..92b1839 100644 --- a/OAuth/jwt_auth.py +++ b/OAuth/jwt_auth.py @@ -61,7 +61,7 @@ ] NAVIGATOR_SCOPES = [ - "signature", "adm_store_unified_repo_read" + "signature", "adm_store_unified_repo_read document_uploader_write document_uploader_read" ] CONNECTED_FIELDS_SCOPES = [ diff --git a/README.md b/README.md index f675bb4..ca07078 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,14 @@ For more information about the scopes used for obtaining authorization to use th For a list of code examples that use the Rooms API, see the [How-to guides overview](https://developers.docusign.com/docs/rooms-api/how-to/) on the Docusign Developer Center. +## Trust Records API + +**Note:** To run the Trust Records API examples, you must first complete the [Prerequisites](https://developers.docusign.com/docs/trust-records-api/how-to/retrieve-idevidence-artifacts/). + +For more information about the scopes used for obtaining authorization to use the Trust Records API, see [Required scopes](https://developers.docusign.com/platform/auth/reference/scopes/). + +For a list of code examples that use the Trust Records API, see the [How-to guides overview](https://developers.docusign.com/docs/trust-records-api/how-to/) on the Docusign Developer Center. + ## Web Forms API The Web Forms API is available in all developer accounts, but only in certain production account plans. Contact [Docusign Support](https://support.docusign.com/) or your account manager to find out whether the Web Forms API is available for your production account plan. diff --git a/config/RECIPIENT_ID_GUID b/config/RECIPIENT_ID_GUID new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/config/RECIPIENT_ID_GUID @@ -0,0 +1 @@ + diff --git a/demo_documents/Id.jpg b/demo_documents/Id.jpg new file mode 100644 index 0000000..423ddde Binary files /dev/null and b/demo_documents/Id.jpg differ diff --git a/demo_documents/Welcome.txt b/demo_documents/Welcome.txt new file mode 100644 index 0000000..9d6c62a --- /dev/null +++ b/demo_documents/Welcome.txt @@ -0,0 +1,7 @@ + + + + Welcome to the DocuSign Recruiting Event + + + Please Sign in! \ No newline at end of file diff --git a/examples/Navigator/eg003BulkUpload.sh b/examples/Navigator/eg003BulkUpload.sh new file mode 100644 index 0000000..7889a7e --- /dev/null +++ b/examples/Navigator/eg003BulkUpload.sh @@ -0,0 +1,132 @@ +# Check that we're in a bash shell +if [[ $SHELL != *"bash"* ]]; then + echo "PROBLEM: Run these scripts from within the bash shell." +fi + +# Obtain your OAuth token +ACCESS_TOKEN=$(cat config/ds_access_token.txt) + +# Set up variables for full code example +account_id=$(cat config/API_ACCOUNT_ID) +base_path="https://api-d.docusign.com/v1" + +request_data=$(mktemp /tmp/request-nav-003.XXXXXX) +response=$(mktemp /tmp/response-nav-003.XXXXXX) + +#ds-snippet-start:Navigator3Step2 +printf \ +'{ + "job_name": "Example bulk upload job", + "expected_number_of_docs": 5, + "language": "en-US" +}' >> $request_data + +curl --request POST ${base_path}/accounts/${account_id}/upload/jobs \ + --header "Authorization: Bearer ${ACCESS_TOKEN}" \ + --header "Accept: application/json" \ + --header "Content-Type: application/json" \ + --data-binary @${request_data} \ + --output $response + +# Extract job ID and upload URLs for each document +job_id=$(cat "$response" | grep -o '"id":"[^"]*' | head -1 | cut -d'"' -f4) +upload_urls=$(cat $response | grep -o '"upload_document":"[^"]*' | cut -d'"' -f4) +#ds-snippet-end:Navigator3Step2 + +echo "Created upload job with ID: $job_id" + +read -p "Press Enter to upload documents for this job" + +echo "Uploading documents..." +echo "" + +#ds-snippet-start:Navigator3Step3 +# Array of demo documents to upload +declare -a demo_files=( + "demo_documents/World_Wide_Corp_Battle_Plan_Trafalgar.docx" + "demo_documents/World_Wide_Corp_lorem.pdf" + "demo_documents/doc_1.html" + "demo_documents/Welcome.txt" + "demo_documents/Id.jpg" +) + +# Convert to array (cross-platform: works on macOS and Linux) +upload_urls_array=() +while IFS= read -r url; do + upload_urls_array+=("$url") +done <<<"$upload_urls" + +# Upload each file +for i in "${!demo_files[@]}"; do + file_path="${demo_files[$i]}" + upload_url="${upload_urls_array[$i]}" + + # Extract filename from path + filename=$(basename "$file_path") + + if [[ ! -f "$file_path" ]]; then + echo "Skipping $filename - file not found: $file_path" + continue + fi + + if [[ -z "$upload_url" ]]; then + echo "Skipping $filename - no upload URL found" + continue + fi + + case "$filename" in + *.docx) + content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document" + ;; + *.pdf) + content_type="application/pdf" + ;; + *.html) + content_type="text/html" + ;; + *.txt) + content_type="text/plain" + ;; + *.jpg|*.jpeg) + content_type="image/jpeg" + ;; + *) + content_type="application/octet-stream" + ;; + esac + + echo "Uploading $filename..." + + + # Make PUT request with binary file content and required headers. + curl --request PUT "$upload_url" \ + --header "x-ms-blob-type: BlockBlob" \ + --header "x-ms-meta-filename: ${filename}" \ + --header "Content-Type: ${content_type}" \ + --data-binary @"$file_path" +done +#ds-snippet-end:Navigator3Step3 + +echo "" +read -p "The documents have been uploaded. Press Enter to update the job status." + +#ds-snippet-start:Navigator3Step4 +curl --request POST "${base_path}/accounts/${account_id}/upload/jobs/${job_id}/actions/complete" \ + --header "Authorization: Bearer ${ACCESS_TOKEN}" \ + --header "Accept: application/json" \ + --header "Content-Type: application/json" \ + --output "$response" +#ds-snippet-end:Navigator3Step4 + +echo "" +echo "Bulk upload job has been completed. Response:" +echo "" +cat "$response" +echo "" + +rm -f "$response" +rm -f "$request_data" + +echo "" +echo "Done." +echo "" diff --git a/examples/TrustRecords/eg001RetrieveIDEvidenceArtifacts.sh b/examples/TrustRecords/eg001RetrieveIDEvidenceArtifacts.sh new file mode 100644 index 0000000..c2ff7f9 --- /dev/null +++ b/examples/TrustRecords/eg001RetrieveIDEvidenceArtifacts.sh @@ -0,0 +1,136 @@ +#!/bin/bash + +# Check that we're in a bash shell +if [[ $SHELL != *"bash"* ]]; then + echo "PROBLEM: Run these scripts from within the bash shell." +fi + +# Obtain your OAuth token and Account ID +access_token=$(cat ../../config/ds_access_token.txt) +account_id=$(cat ../../config/API_ACCOUNT_ID) + +# --- ID Input Selection --- +echo "Have you already completed one of the following: IDNow for GwG, Identity Verification, or a Maestro 'Verify Identity' step?" +read -p "(y/n): " has_completed + +if [[ "$has_completed" =~ ^[Yy]$ ]]; then + echo "-------------------------------------------------------" + echo "NOTE: In the case of eSignature, the Recipient ID and the Record ID are the same." + echo "-------------------------------------------------------" + echo "Do you have an (1) Envelope ID or a (2) Record ID?" + read -p "Enter 1 or 2: " id_type + + if [[ "$id_type" == "1" ]]; then + echo "Please enter the Envelope ID:" + read idv_envelope_id + + if [ -z "$idv_envelope_id" ]; then + echo "Error: To retrieve the data, either an Envelope ID or Record ID is required. Please try again." + exit 1 + fi + + echo "Retrieving Record ID from envelope recipients..." + #ds-snippet-start:TrustRecords1Step2 + uri="https://demo.docusign.net/restapi/v2.1/accounts/${account_id}/envelopes/${idv_envelope_id}/recipients" + declare -a Headers=('--header' "Authorization: Bearer ${access_token}" '--header' "Accept: application/json") + + response_file=$(mktemp /tmp/recipients.XXXXXX) + status=$(curl -s -w "%{http_code}" --request GET "${uri}" "${Headers[@]}" --output ${response_file}) + #ds-snippet-end:TrustRecords1Step2 + + if [[ "$status" -eq 200 ]]; then + # Parsing the recipientIdGuid to use as the record_id + record_id=$(cat $response_file | grep -o '"recipientIdGuid":"[^"]*' | sed 's/"recipientIdGuid":"//' | head -1) + echo "Found Record ID: $record_id" + else + echo "Failed to retrieve recipients. Status: $status. Please try again." + exit 1 + fi + elif [[ "$id_type" == "2" ]]; then + echo "Please enter the Record ID:" + read record_id + else + echo "Invalid selection. To retrieve the data, either an Envelope ID or Record ID is required. Please try again." + exit 1 + fi +else + echo "To retrieve the data, either an Envelope ID or Record ID is required. Please try again." + exit 1 +fi + +# Final check for Record ID +if [ -z "$record_id" ]; then + echo "Error: Record ID is missing. To retrieve the data, either an Envelope ID or Record ID is required. Please try again." + exit 1 +fi + +# Store the value internally as RECIPIENT_ID_GUID to maintain compatibility with existing config structures if needed +echo $record_id > ../../config/RECIPIENT_ID_GUID + +# --- Step 4: Call Trust Records Endpoint --- +#ds-snippet-start:TrustRecords1Step3 +declare -a Headers=('--header' "Authorization: Bearer ${access_token}" '--header' "Accept: application/json") +#ds-snippet-end:TrustRecords1Step3 + +#ds-snippet-start:TrustRecords1Step4 +uri="https://api-d.docusign.com/v1/accounts/${account_id}/trust-records/${record_id}" +response_json=$(mktemp /tmp/trust_record.XXXXXX) +#ds-snippet-end:TrustRecords1Step4 +echo "-------------------------------------------------------" +echo "Fetching Trust Records for Record ID: $record_id" +echo "-------------------------------------------------------" + +status=$(curl -s -w "%{http_code}" --request GET "${uri}" "${Headers[@]}" --output ${response_json}) + +if [[ "$status" -gt "201" ]]; then + echo "Error fetching trust records. Status: $status" + cat $response_json + exit 1 +fi + +# Display the API response to the user +echo "API Response:" +cat $response_json +echo -e "\n-------------------------------------------------------" + +# Parse the relative pdf_url +#ds-snippet-start:TrustRecords1Step5 +pdf_path=$(cat $response_json | grep -o '"pdf_url":"[^"]*' | sed 's/"pdf_url":"//') + +if [ -n "$pdf_path" ]; then + # Construct the Full URL using the requested base + clean_path=$(echo $pdf_path | sed 's/^\///') + full_download_url="https://api-d.docusign.com/v1/${clean_path}" +#ds-snippet-end:TrustRecords1Step5 + echo "SUCCESS: The 'pdf_url' has been found in the API response." + echo "Full PDF Download URL: $full_download_url" + echo "-------------------------------------------------------" + + # Download Prompt + read -p "Would you like to download the ID artifact (PDF) now? (y/n): " download_choice + + if [[ "$download_choice" =~ ^[Yy]$ ]]; then + mkdir -p proofs + file_name="identity_proof_$(date +%Y%m%d_%H%M%S).pdf" + + echo "Downloading PDF to proofs/$file_name..." + + curl -s -L --request GET "${full_download_url}" \ + --header "Authorization: Bearer ${access_token}" \ + --output "proofs/$file_name" + + if [ $? -eq 0 ] && [ -s "proofs/$file_name" ]; then + echo "Download complete! PDF saved in the 'proofs' folder." + else + echo "Download failed or file is empty." + fi + fi +else + echo "Note: API call was successful, but no 'pdf_url' was found in this record." +fi + +# Cleanup +rm "$response_json" +[ -f "$response_file" ] && rm "$response_file" + +echo "Done." \ No newline at end of file diff --git a/launcher.sh b/launcher.sh index 06a4a85..c606501 100644 --- a/launcher.sh +++ b/launcher.sh @@ -1033,6 +1033,7 @@ function startNavigator() { select CHOICE in \ "List_Agreements" \ "Get_Single_Agreement" \ + "Bulk_Upload" \ "Home"; do case "$CHOICE" in @@ -1047,6 +1048,10 @@ function startNavigator() { bash examples/Navigator/eg002GetSingleAgreement.sh startNavigator ;; + Bulk_Upload) + bash examples/Navigator/eg003BulkUpload.sh + startNavigator + ;; *) echo "Default action..." startNavigator