From 374d1d10d0e5d4513806324630dbfdebec46299e Mon Sep 17 00:00:00 2001 From: Paul Huliganga Date: Tue, 21 Apr 2026 14:38:40 -0400 Subject: [PATCH] fix(verify): look up actual template role names before sending envelope Hardcoded "Signer" roleName caused envelopes to send without tags. Now fetches template recipients first and assigns test recipient to every role, falling back to "Signer" only if the template fetch fails. Co-Authored-By: Claude Sonnet 4.6 --- web/routers/verify.py | 55 +++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/web/routers/verify.py b/web/routers/verify.py index edd8c9e..709a4f5 100644 --- a/web/routers/verify.py +++ b/web/routers/verify.py @@ -42,28 +42,43 @@ async def send_test_envelope(body: SendRequest, request: Request): if err: return err - payload = { - "templateId": body.template_id, - "status": "sent", - "templateRoles": [ - { - "email": body.recipient_email, - "name": body.recipient_name, - "roleName": "Signer", - } - ], - "emailSubject": f"[Verification Test] Please sign this document", + headers = { + "Authorization": f"Bearer {session['docusign_access_token']}", + "Content-Type": "application/json", } + base = f"{settings.docusign_base_url}/v2.1/accounts/{settings.docusign_account_id}" async with httpx.AsyncClient() as client: - resp = await client.post( - f"{settings.docusign_base_url}/v2.1/accounts/{settings.docusign_account_id}/envelopes", - headers={ - "Authorization": f"Bearer {session['docusign_access_token']}", - "Content-Type": "application/json", - }, - json=payload, - ) + # Fetch template to discover actual role names + tpl_resp = await client.get(f"{base}/templates/{body.template_id}", headers=headers) + role_names = [] + if tpl_resp.is_success: + tpl = tpl_resp.json() + recipients = tpl.get("recipients", {}) + for group in recipients.values(): + if isinstance(group, list): + for r in group: + rn = r.get("roleName") + if rn and rn not in role_names: + role_names.append(rn) + + # Fall back to generic role name if template fetch failed + if not role_names: + role_names = ["Signer"] + + template_roles = [ + {"email": body.recipient_email, "name": body.recipient_name, "roleName": rn} + for rn in role_names + ] + + payload = { + "templateId": body.template_id, + "status": "sent", + "templateRoles": template_roles, + "emailSubject": "[Verification Test] Please sign this document", + } + + resp = await client.post(f"{base}/envelopes", headers=headers, json=payload) if not resp.is_success: return JSONResponse( @@ -72,7 +87,7 @@ async def send_test_envelope(body: SendRequest, request: Request): ) data = resp.json() - return {"envelope_id": data.get("envelopeId")} + return {"envelope_id": data.get("envelopeId"), "roles": role_names} @router.get("/status/{envelope_id}")