Box Signの構造化されたドキュメントの使用

Yuko Taniguchi
Box Developer Japan Blog
13 min readJan 16, 2024
Image by pch.vector on Freepik

この記事では、Box Platformを使用して、構造化されたドキュメントに電子サインを行う方法について説明します。

Box Signのコンテキストでは、構造化されたドキュメントにはタグが含まれており、これらのタグにより、Box Signでドキュメント内に描画する署名プロパティ (署名パッド、名前、日付など) を指定します。

これにより、アプリはドキュメントの準備を省略できるほか、ドキュメントがテンプレートに依存しないようにすることもできます。

最も一般的なユースケースとして、別のシステムでドキュメントを生成していて、署名の準備が必要になる場合があります。

以前の記事では、すべてのユースケースに共通する署名リクエストの多くの機能だけでなく、非構造化ドキュメントにBox Signを使用する方法やBox Signでテンプレートを使用する方法についても説明しました。以前の記事については以下を参照してください。

このワークショップは、こちらのGitHubリポジトリにあるコードサンプル一式を使用して進めることができます。ここでは、Box Platformの次世代のPython SDKを使用します。

構造化されたドキュメント

Box Signのコンテキストにおける構造化されたドキュメントとは、Box Sign APIが認識できる特殊なタグを含むドキュメントのことです。これらのタグは、特定の署名者に関連付けられた署名プロパティ (名前、日付、署名など) をドキュメント内に配置するために使用されます。

これにより、アプリでは、署名の準備が整った、動的に生成されたドキュメントを処理できます。これには、いくつかの利点があります。

  • ドキュメントを動的に生成できます。また、署名リクエストを作成する前に署名プロパティをドキュメントに追加できるため、実質的にドキュメントの準備手順を省略できます。
  • ドキュメントの形式はBox Signテンプレートの外部で処理できるため、柔軟性が高まり、外部のドキュメント管理システムとの統合が可能になります。

構造化されたドキュメントの詳細

構造化されたドキュメントの例を以下に示します。

Wordドキュメントでのタグの使用

上記の例では、[[c|1]] は署名者1に割り当てられたチェックボックスを指し、[[s|1]] は署名者1に割り当てられた署名パッドを指します。署名パッドでフォントサイズ48を使用して、署名用のスペースを縦方向に確保していることに注目してください。

[[t|1|id:tag_full_name|n:enter your complete name]] は、ラベルenter your complete nameとID tag_full_nameを使用して、署名者1に割り当てられた名前タグを指します。

利用可能なすべてのタグの詳細については、こちらのサポート記事をご覧ください。

タグを背景と同じ色に設定すると、タグは見えなくなりますが、存在はしています。

タグ内の番号は署名者の番号を指すため、[[c|1]] は署名者1のチェックボックス、[[c|2]] は署名者2のチェックボックスのようになります。署名順序を指すものではありません

タグ0は送信者用に予約されており、必ず存在します。したがって、送信者がドキュメントにデータを入力する必要がない場合でも、他の署名者には1以降を割り当てる必要があります。

構造化されたドキュメントからの署名リクエストの作成

これは、非構造化ドキュメントの署名リクエストを作成する場合と同じです。少なくとも、ドキュメント、受信用フォルダ、および署名者のメールアドレスを指定する必要があります。

構造化されたドキュメントにはすでに署名プロパティの詳細と場所が含まれているため、ドキュメントの準備は省略できます。

次のメソッドを考えてみましょう。

def create_sign_request_structured(
client: Client, file_id: str, signer_email: str
) -> SignRequest:
"""Create a sign request with structured data"""

# Sign request params
source_file = FileBase(id=file_id, type=FileBaseTypeField.FILE)
parent_folder = FolderMini(
id=SIGN_DOCS_FOLDER, type=FolderBaseTypeField.FOLDER
)
signer = SignRequestCreateSigner(signer_email)

# Create a sign request
sign_request = client.sign_requests.create_sign_request(
signers=[signer],
parent_folder=parent_folder,
source_files=[source_file],
)

return sign_request

このメソッドを呼び出します。

def main():
...

# Create a sign request with structured data
sign_request = create_sign_request_structured(
client, STRUCTURED_DOC, SIGNER_A
)
check_sign_request(sign_request)

結果は次のとおりです。

Simple sign request: 6878e048-e9bd-4fb1-88c6-8e502783e8d0
Status: converting
Signers: 2
final_copy_reader: ...@gmail.com
signer: YOUR_EMAIL+a@gmail.com
Prepare url: None

署名者のメールの受信トレイに移動し、Box Signからのメールを開き、[ドキュメントをレビュー] ボタンをクリックすると、署名プロパティが所定の位置に配置されているドキュメントが表示されます。

プロパティが所定の位置に配置されているドキュメント

処理を完了すると、署名済みドキュメントは次のようになります。

署名済みドキュメント

署名の属性の事前入力

ドキュメントのタグに外部IDが設定されている場合は、それを使用して値を事前入力できます。たとえば、タグにtag_full_nameというIDが設定されている場合は、そのIDを使用して署名者の名前を事前に入力できます。

次のメソッドを考えてみましょう。

def create_sign_request_structured_with_prefill(
client: Client, file_id: str, signer_name, signer_email: str
) -> SignRequest:
"""Create a sign request with structured data"""

# Sign request params
source_file = FileBase(id=file_id, type=FileBaseTypeField.FILE)
parent_folder = FolderMini(
id=SIGN_DOCS_FOLDER, type=FolderBaseTypeField.FOLDER
)
signer = SignRequestCreateSigner(signer_email)

# tags
tag_full_name = SignRequestPrefillTag(
document_tag_id="tag_full_name",
text_value=signer_name,
)

# Create a sign request
sign_request = client.sign_requests.create_sign_request(
signers=[signer],
parent_folder=parent_folder,
source_files=[source_file],
prefill_tags=[tag_full_name],
)

return sign_request

これをmainメソッドで使用します。

def main():
...

# Create a sign request with name pre populate
sign_request_pre_pop = create_sign_request_structured_with_prefill(
client, STRUCTURED_DOC, "Rui Barbosa", SIGNER_A
)
check_sign_request(sign_request_pre_pop)

結果は次のとおりです。

Simple sign request: 7b86e46c-72ba-4568-a6ff-787077cca007
Status: converting
Signers: 2
final_copy_reader: ...@gmail.com
signer: YOUR_EMAIL+a@gmail.com
Prepare url: None

これで、ドキュメントには名前が事前入力されるようになりました。

名前が事前入力された、署名の準備ができているドキュメント

署名済みドキュメントからの情報の抽出

たとえば、署名者の名前とその他のプロパティを署名済みドキュメントから抽出するとします。これは、署名リクエストの情報を再度システムに紐付ける必要がある場合に役立ちます。

署名済みのリクエストから情報を抽出するメソッドを作成します。

def check_sign_request_by_id(client: Client, sign_request_id: str):
"""Check sign request by id"""
sign_request = client.sign_requests.get_sign_request_by_id(sign_request_id)

print(f"\nSimple sign request: {sign_request.id}")
print(f" Status: {sign_request.status.value}")

print(f" Signers: {len(sign_request.signers)}")
for signer in sign_request.signers:
print(f" {signer.role.value}: {signer.email}")
for input in signer.inputs:
content_type = input.content_type
value = None

if content_type == SignRequestSignerInputTypeField.CHECKBOX:
value = input.checkbox_value
elif content_type == SignRequestSignerInputTypeField.TEXT:
value = input.text_value
elif content_type == SignRequestSignerInputTypeField.DATE:
value = input.date_value

print(
f" {input.type.value}: {value if value is not None else '<other>'}"
)

print(f" Prepare url: {sign_request.prepare_url}")

これを、前の演習の署名リクエストIDを指定したmainメソッドで使用します。

def main():
...

# Latest sign request
LATEST_SIGN_REQUEST = "7b86e46c-72ba-4568-a6ff-787077cca007"
check_sign_request_by_id(client, LATEST_SIGN_REQUEST)

結果は次のとおりです。

Simple sign request: 7b86e46c-72ba-4568-a6ff-787077cca007
Status: signed
Signers: 2
final_copy_reader: ...@gmail.com
signer: YOUR_EMAIL+a@gmail.com
checkbox: True
text: Rui Barbosa
date: 2023-11-15
signature: <other>
Prepare url: None

まとめ

構造化されたドキュメントの使用は、外部のドキュメント管理システムと統合して、署名可能な動的なドキュメントを作成するのに最適です。

ドキュメントの署名要件に多くの選択肢がある場合は、別のデータソースからこれらを事前に入力して、ユーザーの時間を節約することができます。

これらのプロパティを所有するユーザーはいつでも変更できることを覚えておいてください。

ドキュメントが署名された後に署名リクエストから情報を抽出できるのと同じように、その情報を再度システムに紐付ける必要がある場合に役立ちます。

ドキュメントと参考情報

アイデア、コメント、フィードバックがある場合は、コミュニティフォーラム (英語のみ) にコメントをお送りください。

--

--