๐Ÿ“… let's chat! explore the endless possibilities creating industries that don't exist. click here

documenso-debug-bundle

Comprehensive debugging toolkit for Documenso integrations. Use when troubleshooting complex issues, gathering diagnostic information, or creating support tickets for Documenso problems. Trigger with phrases like "debug documenso", "documenso diagnostics", "troubleshoot documenso", "documenso support ticket". allowed-tools: Read, Write, Edit, Bash(curl:*), Bash(node:*), Grep version: 1.0.0 license: MIT author: Jeremy Longshore <jeremy@intentsolutions.io>

Allowed Tools

No tools specified

Provided by Plugin

documenso-pack

Claude Code skill pack for Documenso (24 skills)

saas packs v1.0.0
View Plugin

Installation

This skill is included in the documenso-pack plugin:

/plugin install documenso-pack@claude-code-plugins-plus

Click to copy

Instructions

# Documenso Debug Bundle ## Overview Comprehensive debugging tools and diagnostic scripts for Documenso integration issues. ## Prerequisites - Documenso SDK installed - Access to logs and configuration - curl for API testing ## Debug Scripts ### Script 1: Connection Diagnostic ```typescript // scripts/documenso-diagnostic.ts import { Documenso } from "@documenso/sdk-typescript"; interface DiagnosticResult { timestamp: string; environment: { nodeVersion: string; sdkVersion: string; apiKeyPresent: boolean; apiKeyPrefix: string; baseUrl: string; }; connectivity: { canConnect: boolean; latencyMs: number; error?: string; }; account: { documentsCount?: number; templatesCount?: number; error?: string; }; } async function runDiagnostic(): Promise { const result: DiagnosticResult = { timestamp: new Date().toISOString(), environment: { nodeVersion: process.version, sdkVersion: "latest", // Get from package.json apiKeyPresent: !!process.env.DOCUMENSO_API_KEY, apiKeyPrefix: process.env.DOCUMENSO_API_KEY?.substring(0, 7) ?? "missing", baseUrl: process.env.DOCUMENSO_BASE_URL ?? "https://app.documenso.com/api/v2/", }, connectivity: { canConnect: false, latencyMs: 0, }, account: {}, }; if (!process.env.DOCUMENSO_API_KEY) { result.connectivity.error = "DOCUMENSO_API_KEY not set"; return result; } const client = new Documenso({ apiKey: process.env.DOCUMENSO_API_KEY, serverURL: process.env.DOCUMENSO_BASE_URL, }); // Test connectivity const startTime = Date.now(); try { const docs = await client.documents.findV0({ perPage: 1 }); result.connectivity.canConnect = true; result.connectivity.latencyMs = Date.now() - startTime; result.account.documentsCount = docs.totalPages ?? 0; } catch (error: any) { result.connectivity.error = `${error.statusCode}: ${error.message}`; result.connectivity.latencyMs = Date.now() - startTime; } // Test templates access try { const templates = await client.templates.findV0({ perPage: 1 }); result.account.templatesCount = templates.totalPages ?? 0; } catch (error: any) { result.account.error = error.message; } return result; } // Run and output runDiagnostic().then(result => { console.log("\n=== Documenso Diagnostic Report ===\n"); console.log(JSON.stringify(result, null, 2)); // Summary console.log("\n=== Summary ==="); if (result.connectivity.canConnect) { console.log("Connection: OK"); console.log(`Latency: ${result.connectivity.latencyMs}ms`); } else { console.log("Connection: FAILED"); console.log(`Error: ${result.connectivity.error}`); } }); ``` ### Script 2: Document Inspector ```typescript // scripts/inspect-document.ts import { Documenso } from "@documenso/sdk-typescript"; async function inspectDocument(documentId: string) { const client = new Documenso({ apiKey: process.env.DOCUMENSO_API_KEY ?? "", }); console.log(`\n=== Inspecting Document: ${documentId} ===\n`); try { const doc = await client.documents.getV0({ documentId }); console.log("Document Details:"); console.log(` ID: ${doc.id}`); console.log(` Title: ${doc.title}`); console.log(` Status: ${doc.status}`); console.log(` Created: ${doc.createdAt}`); console.log(` Updated: ${doc.updatedAt}`); console.log("\nRecipients:"); for (const recipient of doc.recipients ?? []) { console.log(` - ${recipient.email}`); console.log(` Name: ${recipient.name}`); console.log(` Role: ${recipient.role}`); console.log(` Status: ${recipient.signingStatus}`); console.log(` Signing Order: ${recipient.signingOrder}`); } console.log("\nFields:"); for (const field of doc.fields ?? []) { console.log(` - Type: ${field.type}`); console.log(` Page: ${field.page}`); console.log(` Position: (${field.positionX}, ${field.positionY})`); console.log(` Size: ${field.width}x${field.height}`); console.log(` Recipient: ${field.recipientId}`); } return doc; } catch (error: any) { console.error(`Failed to inspect document: ${error.message}`); console.error(`Status: ${error.statusCode}`); throw error; } } // Usage: npx tsx scripts/inspect-document.ts doc_abc123 const documentId = process.argv[2]; if (documentId) { inspectDocument(documentId); } else { console.log("Usage: npx tsx scripts/inspect-document.ts "); } ``` ### Script 3: API Request Logger ```typescript // scripts/logged-client.ts import { Documenso } from "@documenso/sdk-typescript"; // Create a logged wrapper function createLoggedClient(): Documenso { const client = new Documenso({ apiKey: process.env.DOCUMENSO_API_KEY ?? "", serverURL: process.env.DOCUMENSO_BASE_URL, debugLogger: { log: (...args) => { const timestamp = new Date().toISOString(); console.log(`[${timestamp}] DEBUG:`, ...args); }, warn: (...args) => { const timestamp = new Date().toISOString(); console.warn(`[${timestamp}] WARN:`, ...args); }, error: (...args) => { const timestamp = new Date().toISOString(); console.error(`[${timestamp}] ERROR:`, ...args); }, }, }); return client; } export { createLoggedClient }; ``` ### Script 4: Webhook Tester ```typescript // scripts/test-webhook.ts import express from "express"; import crypto from "crypto"; const app = express(); // Log all incoming requests app.use((req, res, next) => { console.log(`\n=== Incoming Request ===`); console.log(`Time: ${new Date().toISOString()}`); console.log(`Method: ${req.method}`); console.log(`Path: ${req.path}`); console.log(`Headers:`, JSON.stringify(req.headers, null, 2)); next(); }); // Parse raw body for signature verification app.use(express.raw({ type: "application/json" })); app.post("/webhook/documenso", (req, res) => { const secret = req.headers["x-documenso-secret"]; const expectedSecret = process.env.DOCUMENSO_WEBHOOK_SECRET; console.log(`\n=== Webhook Received ===`); console.log(`Secret Header: ${secret ? "present" : "missing"}`); console.log(`Secret Valid: ${secret === expectedSecret}`); try { const payload = JSON.parse(req.body.toString()); console.log(`Event: ${payload.event}`); console.log(`Document ID: ${payload.payload?.id}`); console.log(`Status: ${payload.payload?.status}`); console.log(`Full Payload:`, JSON.stringify(payload, null, 2)); res.status(200).json({ received: true }); } catch (error) { console.error(`Failed to parse webhook:`, error); res.status(400).json({ error: "Invalid JSON" }); } }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Webhook test server running on port ${PORT}`); console.log(`Endpoint: POST http://localhost:${PORT}/webhook/documenso`); console.log(`\nUse ngrok to expose: ngrok http ${PORT}`); }); ``` ### Script 5: Bulk Document Status Check ```typescript // scripts/check-document-status.ts import { Documenso } from "@documenso/sdk-typescript"; async function checkAllDocuments() { const client = new Documenso({ apiKey: process.env.DOCUMENSO_API_KEY ?? "", }); console.log("Fetching all documents...\n"); const statusCounts: Record = {}; const pendingDocs: Array<{ id: string; title: string; age: string }> = []; let page = 1; let hasMore = true; while (hasMore) { const result = await client.documents.findV0({ page, perPage: 100, }); for (const doc of result.documents ?? []) { const status = doc.status ?? "UNKNOWN"; statusCounts[status] = (statusCounts[status] ?? 0) + 1; // Track pending documents if (status === "PENDING") { const createdAt = new Date(doc.createdAt!); const age = getAge(createdAt); pendingDocs.push({ id: doc.id!, title: doc.title ?? "Untitled", age, }); } } hasMore = (result.documents?.length ?? 0) === 100; page++; } console.log("=== Document Status Summary ==="); for (const [status, count] of Object.entries(statusCounts)) { console.log(`${status}: ${count}`); } if (pendingDocs.length > 0) { console.log("\n=== Pending Documents ==="); for (const doc of pendingDocs.slice(0, 10)) { console.log(`- ${doc.title} (${doc.id}) - ${doc.age} old`); } if (pendingDocs.length > 10) { console.log(`... and ${pendingDocs.length - 10} more`); } } } function getAge(date: Date): string { const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); if (diffDays === 0) return "< 1 day"; if (diffDays === 1) return "1 day"; if (diffDays < 7) return `${diffDays} days`; if (diffDays < 30) return `${Math.floor(diffDays / 7)} weeks`; return `${Math.floor(diffDays / 30)} months`; } checkAllDocuments().catch(console.error); ``` ## curl Debug Commands ```bash # Test API connectivity curl -v -H "Authorization: Bearer $DOCUMENSO_API_KEY" \ https://app.documenso.com/api/v2/documents # Get specific document curl -H "Authorization: Bearer $DOCUMENSO_API_KEY" \ https://app.documenso.com/api/v2/documents/{documentId} # List templates curl -H "Authorization: Bearer $DOCUMENSO_API_KEY" \ https://app.documenso.com/api/v2/templates # Test webhook endpoint curl -X POST http://localhost:3000/webhook/documenso \ -H "Content-Type: application/json" \ -H "X-Documenso-Secret: your-secret" \ -d '{"event":"document.completed","payload":{"id":"test"}}' ``` ## Environment Checklist ```bash #!/bin/bash # scripts/check-env.sh echo "=== Documenso Environment Check ===" # Check API key if [ -z "$DOCUMENSO_API_KEY" ]; then echo "DOCUMENSO_API_KEY: NOT SET" else echo "DOCUMENSO_API_KEY: SET (${DOCUMENSO_API_KEY:0:7}...)" fi # Check base URL if [ -z "$DOCUMENSO_BASE_URL" ]; then echo "DOCUMENSO_BASE_URL: NOT SET (using default)" else echo "DOCUMENSO_BASE_URL: $DOCUMENSO_BASE_URL" fi # Check webhook secret if [ -z "$DOCUMENSO_WEBHOOK_SECRET" ]; then echo "DOCUMENSO_WEBHOOK_SECRET: NOT SET" else echo "DOCUMENSO_WEBHOOK_SECRET: SET" fi # Test connectivity echo "" echo "Testing connectivity..." response=$(curl -s -o /dev/null -w "%{http_code}" \ -H "Authorization: Bearer $DOCUMENSO_API_KEY" \ ${DOCUMENSO_BASE_URL:-https://app.documenso.com/api/v2/}documents?perPage=1) if [ "$response" = "200" ]; then echo "API Connection: OK" elif [ "$response" = "401" ]; then echo "API Connection: UNAUTHORIZED (check API key)" else echo "API Connection: FAILED (HTTP $response)" fi ``` ## Support Ticket Template When creating a support ticket, include: ```markdown ## Documenso Support Request ### Environment - SDK Version: @documenso/sdk-typescript@x.x.x - Node.js Version: v20.x.x - Environment: Production / Staging - API Base URL: https://app.documenso.com/api/v2/ ### Issue Description [Describe what you expected vs what happened] ### Steps to Reproduce 1. [Step 1] 2. [Step 2] 3. [Step 3] ### Error Details ``` [Paste error message and stack trace] ``` ### Diagnostic Output ```json [Paste output from documenso-diagnostic.ts] ``` ### Document IDs (if applicable) - Document ID: doc_xxx - Template ID: tmpl_xxx ### Request/Response (if applicable) ``` [Paste relevant API request and response] ``` ``` ## Output - Diagnostic scripts ready - Environment validated - Debug logging enabled - Support ticket template prepared ## Resources - [Documenso GitHub Issues](https://github.com/documenso/documenso/issues) - [Documenso Discord](https://documenso.com/discord) - [API Status](https://status.documenso.com) ## Next Steps For rate limit handling, see `documenso-rate-limits`.

Skill file: plugins/saas-packs/documenso-pack/skills/documenso-debug-bundle/SKILL.md