diff --git a/docs/TurboDocx Templating/API Templates.md b/docs/TurboDocx Templating/API Templates.md
index cc86b92..6206302 100644
--- a/docs/TurboDocx Templating/API Templates.md
+++ b/docs/TurboDocx Templating/API Templates.md
@@ -36,7 +36,7 @@ import ScriptLoader from '@site/src/components/ScriptLoader';
This comprehensive guide walks you through the Template Generation API integration process. Learn how to programmatically upload new templates or select existing ones, then generate beautiful documents with variable substitution using our RESTful API.
-
+
## Overview
@@ -77,7 +77,6 @@ Don't want to read the novel? Here's the executive summary:
| `subvariables` | Nested variable structures | `{Employee.FirstName}` | Complex hierarchical data |
| `variableStack` | Multiple instances of content | `{Projects[0].Name}` | Repeating sections, lists |
| `richText` | HTML/formatted text content | `{Description}` | Formatted text with styling |
-| `aiPrompt` | AI-generated content | `{Summary}` | Dynamic content generation |
### Complete Dual-Path Workflow
@@ -89,52 +88,31 @@ Don't want to read the novel? Here's the executive summary:
### Quick Variable Structure Example
-Here's what a complex variable payload looks like:
+Here's what a simple variable payload looks like:
```json
{
"templateId": "abc123-def456-ghi789",
- "name": "Employee Contract Draft",
- "description": "Generated contract for new hire",
+ "name": "Generated Document",
+ "description": "Simple document example",
"variables": [
{
- "name": "Employee",
- "placeholder": "{Employee}",
- "text": "John Smith",
- "subvariables": [
- {
- "placeholder": "{Employee.Title}",
- "text": "Senior Developer"
- },
- {
- "placeholder": "{Employee.StartDate}",
- "text": "2024-01-15"
- }
- ]
+ "mimeType": "text",
+ "name": "Company Name",
+ "placeholder": "{CompanyName}",
+ "text": "Acme Corporation"
},
{
- "name": "Projects",
- "placeholder": "{Projects}",
- "variableStack": {
- "0": {
- "text": "Project Alpha - Backend Development",
- "subvariables": [
- {
- "placeholder": "{Projects.Duration}",
- "text": "6 months"
- }
- ]
- },
- "1": {
- "text": "Project Beta - API Integration",
- "subvariables": [
- {
- "placeholder": "{Projects.Duration}",
- "text": "3 months"
- }
- ]
- }
- }
+ "mimeType": "text",
+ "name": "Employee Name",
+ "placeholder": "{EmployeeName}",
+ "text": "John Smith"
+ },
+ {
+ "mimeType": "text",
+ "name": "Date",
+ "placeholder": "{Date}",
+ "text": "January 15, 2024"
}
]
}
@@ -201,8 +179,6 @@ User-Agent: TurboDocx API Client
"templateFile": [DOCX_OR_PPTX_FILE_BINARY],
"name": "Employee Contract Template",
"description": "Standard employee contract with variable placeholders",
- "variables": "[]", // Optional: Pre-defined variables (usually extracted automatically)
- "tags": "[]" // Optional: Categorization tags
}
```
@@ -499,84 +475,25 @@ User-Agent: TurboDocx API Client
```json
{
"templateId": "0b1099cf-d7b9-41a4-822b-51b68fd4885a",
- "name": "Employee Contract - John Smith",
- "description": "Employment contract for new senior developer",
+ "name": "Contract - John Smith",
+ "description": "Simple contract example",
"variables": [
{
- "mimeType": "text",
+ "name": "Company Name",
+ "placeholder": "{CompanyName}",
+ "text": "Acme Corporation"
+ },
+ {
"name": "Employee Name",
"placeholder": "{EmployeeName}",
- "text": "John Smith",
- "allowRichTextInjection": 0,
- "autogenerated": false,
- "count": 1,
- "order": 1,
- "subvariables": [
- {
- "placeholder": "{Employee.Title}",
- "text": "Senior Software Developer"
- },
- {
- "placeholder": "{Employee.StartDate}",
- "text": "January 15, 2024"
- }
- ],
- "aiPrompt": "Generate a professional job description for a senior developer role"
+ "text": "John Smith"
},
{
- "mimeType": "text",
- "name": "Department",
- "placeholder": "{Department}",
- "text": "Engineering",
- "allowRichTextInjection": 1,
- "autogenerated": false,
- "count": 3,
- "order": 2,
- "subvariables": [
- {
- "placeholder": "{Department.Manager}",
- "text": "Sarah Johnson"
- }
- ],
- "variableStack": {
- "0": {
- "text": "Frontend Development Team",
- "subvariables": [
- {
- "placeholder": "{Team.Focus}",
- "text": "React and TypeScript development"
- }
- ]
- },
- "1": {
- "text": "Backend Development Team",
- "subvariables": [
- {
- "placeholder": "{Team.Focus}",
- "text": "Node.js and database optimization"
- }
- ]
- }
- },
- "metadata": {
- "customField": "Engineering Department"
- },
- "aiPrompt": "Describe the key responsibilities of the engineering department"
+ "name": "Date",
+ "placeholder": "{Date}",
+ "text": "January 15, 2024"
}
- ],
- "tags": ["hr-template", "contract", "full-time"],
- "fonts": "[{\"name\":\"Arial\",\"usage\":269}]",
- "defaultFont": "Arial",
- "replaceFonts": true,
- "metadata": {
- "sessions": [
- {
- "id": "session-abc123",
- "starttime": "2024-01-15T14:12:10.721Z",
- "endtime": "2024-01-15T14:13:45.724Z"
- }
- ]
- }
+ ]
}
```
@@ -736,6 +653,35 @@ Content-Length: 287456
label="Final Step: Generate Deliverable Examples"
/>
+## Advanced File Attachment Examples
+
+For advanced workflows that combine template upload with data file processing, explore these comprehensive examples that demonstrate Excel file attachment, sheet selection, and AI variable generation integration.
+
+### File Attachment with Sheet Selection
+
+These examples show how to upload templates alongside Excel data files, with specific sheet selection and data range configuration for AI-powered variable generation:
+
+
+
+### Key Features Demonstrated
+
+- **📊 Excel File Attachment**: Upload spreadsheet data alongside template files
+- **📋 Sheet Selection**: Choose specific sheets from multi-sheet workbooks
+- **📐 Data Range Configuration**: Define cell ranges for targeted data analysis
+- **🤖 AI Variable Integration**: Pre-configure AI variables that reference attached data
+- **🔗 Multi-Sheet Support**: Handle complex workbooks with multiple data sources
+
+### Use Cases
+
+- **Financial Reports**: Upload templates with Q4 financial data and auto-generate summaries
+- **Business Analysis**: Combine report templates with multi-sheet business data
+- **Data-Driven Documents**: Create documents that pull insights from attached spreadsheets
+- **Dynamic Content**: Generate variables based on real-time data uploads
+
## Best Practices
### Security
diff --git a/docs/TurboDocx Templating/ai-variable-generation.md b/docs/TurboDocx Templating/ai-variable-generation.md
index c60a6c3..94b253f 100644
--- a/docs/TurboDocx Templating/ai-variable-generation.md
+++ b/docs/TurboDocx Templating/ai-variable-generation.md
@@ -16,13 +16,6 @@ keywords:
- smart content generation
- ai-powered templates
- turbodocx ai api
- - ai variable extraction
- - intelligent placeholder filling
- - ai content api
- - automated variable creation
- - ai document analysis
- - smart variable generation
- - ai template integration
---
import ScriptLoader from '@site/src/components/ScriptLoader';
@@ -31,7 +24,7 @@ import ScriptLoader from '@site/src/components/ScriptLoader';
Transform your document workflows with intelligent, context-aware variable generation. This API leverages advanced AI to automatically create rich, relevant content for your template variables by analyzing uploaded files, understanding context, and generating human-quality text based on your specific prompts.
-
+
## Overview
@@ -45,12 +38,12 @@ The AI Variable Generation API represents the cutting edge of document automatio
### Key Capabilities
-🧠 **AI-Powered Content Creation**: Advanced language models generate human-quality content
-📎 **File Attachment Processing**: Upload and analyze documents for context-driven generation
-📊 **Spreadsheet Intelligence**: Select specific sheets and extract relevant data automatically
-🎯 **Context Integration**: Use existing templates to inform and guide content generation
-✨ **Rich Text Generation**: Create formatted content with styling and structure
-🔧 **Customizable Prompts**: Fine-tune AI behavior with specific instructions and hints
+- 🧠 **AI-Powered Content Creation**: Advanced language models generate human-quality content
+- 📎 **File Attachment Processing**: Upload and analyze documents for context-driven generation
+- 📊 **Spreadsheet Intelligence**: Select specific sheets and extract relevant data automatically
+- 🎯 **Context Integration**: Use existing templates to inform and guide content generation
+- ✨ **Rich Text Generation**: Create formatted content with styling and structure
+- 🔧 **Customizable Prompts**: Fine-tune AI behavior with specific instructions and hints
## How It Works
@@ -66,21 +59,13 @@ The AI Variable Generation process follows a simple but powerful workflow:
## TLDR; Quick Example 🚀
-Ready to jump in? Here's a complete working example:
+Ready to jump in? Here are complete working examples in multiple programming languages:
-```bash
-curl 'https://api.turbodocx.com/ai/generate/variable/one' \
- -H 'Authorization: Bearer YOUR_API_TOKEN' \
- -H 'x-rapiddocx-org-id: YOUR_ORG_ID' \
- -H 'Content-Type: multipart/form-data' \
- -F 'FileResource-123e4567-e89b-12d3-a456-426614174000=@financial-report.xlsx' \
- -F 'fileResourceMetadata={"123e4567-e89b-12d3-a456-426614174000":{"selectedSheet":"Q4 Results","hasMultipleSheets":true}}' \
- -F 'name=Company Performance Summary' \
- -F 'placeholder={Q4Performance}' \
- -F 'templateId=template-abc123' \
- -F 'aiHint=Generate a professional executive summary of Q4 financial performance based on the attached spreadsheet data' \
- -F 'richTextEnabled=true'
-```
+
**Response:**
@@ -111,7 +96,8 @@ Before you begin generating AI-powered variables, ensure you have:
3. **API Keys Section**: Generate or retrieve your API access token
4. **Organization ID**: Copy your organization ID from the settings
-
+
+
### Supported File Types
@@ -234,69 +220,161 @@ When attaching files, provide metadata to guide AI processing:
When working with spreadsheets, the AI can analyze specific sheets and data ranges:
-```bash
-# Example: Financial data analysis
-curl 'https://api.turbodocx.com/ai/generate/variable/one' \
- -H 'Authorization: Bearer YOUR_API_TOKEN' \
- -H 'x-rapiddocx-org-id: YOUR_ORG_ID' \
- -H 'Content-Type: multipart/form-data' \
- -F 'FileResource-fin123=@quarterly-financials.xlsx' \
- -F 'fileResourceMetadata={"fin123":{"selectedSheet":"Income Statement","hasMultipleSheets":true,"dataRange":"A1:F50"}}' \
- -F 'name=Revenue Analysis' \
- -F 'placeholder={RevenueAnalysis}' \
- -F 'aiHint=Analyze the quarterly revenue trends and provide insights on growth patterns, highlighting key metrics and year-over-year changes' \
- -F 'richTextEnabled=true'
+```javascript
+// Configuration variables
+const API_TOKEN = "YOUR_API_TOKEN";
+const ORGANIZATION_ID = "YOUR_ORGANIZATION_ID";
+const API_URL = "https://api.turbodocx.com/ai/generate/variable/one";
+const FILE_UUID = "fin123";
+const VARIABLE_NAME = "Revenue Analysis";
+const VARIABLE_PLACEHOLDER = "{RevenueAnalysis}";
+const SELECTED_SHEET = "Income Statement";
+const DATA_RANGE = "A1:F50";
+const AI_HINT = "Analyze the quarterly revenue trends and provide insights on growth patterns, highlighting key metrics and year-over-year changes";
+const RICH_TEXT_ENABLED = "true";
+
+// Create FormData for file upload
+const formData = new FormData();
+
+// Attach the Excel/spreadsheet file
+formData.append(`FileResource-${FILE_UUID}`, quarterlyFinancialsFile);
+
+// Specify sheet and data range metadata
+formData.append(
+ "fileResourceMetadata",
+ JSON.stringify({
+ [FILE_UUID]: {
+ selectedSheet: SELECTED_SHEET,
+ hasMultipleSheets: true,
+ dataRange: DATA_RANGE,
+ },
+ })
+);
+
+// Add variable parameters
+formData.append("name", VARIABLE_NAME);
+formData.append("placeholder", VARIABLE_PLACEHOLDER);
+formData.append("aiHint", AI_HINT);
+formData.append("richTextEnabled", RICH_TEXT_ENABLED);
+
+const response = await fetch(API_URL, {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${API_TOKEN}`,
+ "x-rapiddocx-org-id": ORGANIZATION_ID,
+ // Note: Don't set Content-Type - let browser set multipart boundary
+ },
+ body: formData,
+});
```
#### Document Content Extraction
For text documents, the AI can extract and synthesize key information:
-```bash
-# Example: Contract analysis
-curl 'https://api.turbodocx.com/ai/generate/variable/one' \
- -H 'Authorization: Bearer YOUR_API_TOKEN' \
- -H 'x-rapiddocx-org-id: YOUR_ORG_ID' \
- -H 'Content-Type: multipart/form-data' \
- -F 'FileResource-doc456=@contract-draft.docx' \
- -F 'fileResourceMetadata={"doc456":{"contentType":"legal-document"}}' \
- -F 'name=Contract Key Terms' \
- -F 'placeholder={KeyTerms}' \
- -F 'aiHint=Extract and summarize the key terms, obligations, and important dates from this contract document' \
- -F 'richTextEnabled=false'
+```javascript
+// Configuration variables
+const API_TOKEN = "YOUR_API_TOKEN";
+const ORGANIZATION_ID = "YOUR_ORGANIZATION_ID";
+const API_URL = "https://api.turbodocx.com/ai/generate/variable/one";
+const FILE_UUID = "doc456";
+const VARIABLE_NAME = "Contract Key Terms";
+const VARIABLE_PLACEHOLDER = "{KeyTerms}";
+const CONTENT_TYPE = "legal-document";
+const AI_HINT = "Extract and summarize the key terms, obligations, and important dates from this contract document";
+const RICH_TEXT_ENABLED = "false";
+
+// Create FormData for document upload
+const formData = new FormData();
+
+// Attach the document file (PDF, DOCX, etc.)
+formData.append(`FileResource-${FILE_UUID}`, contractDraftFile);
+
+// Specify document metadata
+formData.append(
+ "fileResourceMetadata",
+ JSON.stringify({
+ [FILE_UUID]: {
+ contentType: CONTENT_TYPE,
+ },
+ })
+);
+
+// Add variable parameters
+formData.append("name", VARIABLE_NAME);
+formData.append("placeholder", VARIABLE_PLACEHOLDER);
+formData.append("aiHint", AI_HINT);
+formData.append("richTextEnabled", RICH_TEXT_ENABLED);
+
+const response = await fetch(API_URL, {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${API_TOKEN}`,
+ "x-rapiddocx-org-id": ORGANIZATION_ID,
+ // Note: Don't set Content-Type - let browser set multipart boundary
+ },
+ body: formData,
+});
```
### Context-Aware Generation
Leverage existing template context for more accurate content generation:
-```bash
-# Using template context
-curl 'https://api.turbodocx.com/ai/generate/variable/one' \
- -H 'Authorization: Bearer YOUR_API_TOKEN' \
- -H 'x-rapiddocx-org-id: YOUR_ORG_ID' \
- -H 'Content-Type: multipart/form-data' \
- -F 'name=Project Scope Description' \
- -F 'placeholder={ProjectScope}' \
- -F 'templateId=project-template-789' \
- -F 'aiHint=Generate a detailed project scope description that aligns with the project template structure and includes deliverables, timeline, and success criteria' \
- -F 'richTextEnabled=true'
+```javascript
+// Configuration variables
+const API_TOKEN = "YOUR_API_TOKEN";
+const ORGANIZATION_ID = "YOUR_ORGANIZATION_ID";
+const API_URL = "https://api.turbodocx.com/ai/generate/variable/one";
+const VARIABLE_NAME = "Project Scope Description";
+const VARIABLE_PLACEHOLDER = "{ProjectScope}";
+const AI_HINT = "Generate a detailed project scope description that aligns with the project template structure and includes deliverables, timeline, and success criteria";
+const RICH_TEXT_ENABLED = true;
+
+const response = await fetch(API_URL, {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${API_TOKEN}`,
+ "x-rapiddocx-org-id": ORGANIZATION_ID,
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ name: VARIABLE_NAME,
+ placeholder: VARIABLE_PLACEHOLDER,
+ aiHint: AI_HINT,
+ richTextEnabled: RICH_TEXT_ENABLED,
+ }),
+});
```
### Rich Text Generation
Enable rich text for formatted output with HTML styling:
-```bash
-# Rich text example
-curl 'https://api.turbodocx.com/ai/generate/variable/one' \
- -H 'Authorization: Bearer YOUR_API_TOKEN' \
- -H 'x-rapiddocx-org-id: YOUR_ORG_ID' \
- -H 'Content-Type: multipart/form-data' \
- -F 'name=Executive Summary' \
- -F 'placeholder={ExecutiveSummary}' \
- -F 'aiHint=Create a comprehensive executive summary with bullet points, key metrics, and strategic recommendations formatted for presentation' \
- -F 'richTextEnabled=true'
+```javascript
+// Configuration variables
+const API_TOKEN = "YOUR_API_TOKEN";
+const ORGANIZATION_ID = "YOUR_ORGANIZATION_ID";
+const API_URL = "https://api.turbodocx.com/ai/generate/variable/one";
+const VARIABLE_NAME = "Executive Summary";
+const VARIABLE_PLACEHOLDER = "{ExecutiveSummary}";
+const AI_HINT = "Create a comprehensive executive summary with bullet points, key metrics, and strategic recommendations formatted for presentation";
+const RICH_TEXT_ENABLED = true;
+
+const response = await fetch(API_URL, {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${API_TOKEN}`,
+ "x-rapiddocx-org-id": ORGANIZATION_ID,
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ name: VARIABLE_NAME,
+ placeholder: VARIABLE_PLACEHOLDER,
+ aiHint: AI_HINT,
+ richTextEnabled: RICH_TEXT_ENABLED,
+ }),
+});
```
**Rich Text Response Example:**
@@ -326,67 +404,176 @@ curl 'https://api.turbodocx.com/ai/generate/variable/one' \
**Scenario**: Generate executive summaries from quarterly financial spreadsheets
-```bash
-curl 'https://api.turbodocx.com/ai/generate/variable/one' \
- -H 'Authorization: Bearer YOUR_API_TOKEN' \
- -H 'x-rapiddocx-org-id: YOUR_ORG_ID' \
- -H 'Content-Type: multipart/form-data' \
- -F 'FileResource-12345=@Q4-financials.xlsx' \
- -F 'fileResourceMetadata={"12345":{"selectedSheet":"Summary","hasMultipleSheets":true}}' \
- -F 'name=Financial Performance Summary' \
- -F 'placeholder={FinancialSummary}' \
- -F 'aiHint=Create a concise executive summary highlighting revenue growth, profit margins, and key financial metrics from the Q4 data' \
- -F 'richTextEnabled=true'
+```javascript
+// Configuration variables
+const API_TOKEN = "YOUR_API_TOKEN";
+const ORGANIZATION_ID = "YOUR_ORGANIZATION_ID";
+const API_URL = "https://api.turbodocx.com/ai/generate/variable/one";
+const FILE_UUID = "12345";
+const VARIABLE_NAME = "Financial Performance Summary";
+const VARIABLE_PLACEHOLDER = "{FinancialSummary}";
+const SELECTED_SHEET = "Summary";
+const AI_HINT = "Create a concise executive summary highlighting revenue growth, profit margins, and key financial metrics from the Q4 data";
+const RICH_TEXT_ENABLED = "true";
+
+// Create FormData for financial spreadsheet upload
+const formData = new FormData();
+
+// Attach the Q4 financial spreadsheet
+formData.append(`FileResource-${FILE_UUID}`, q4FinancialsFile);
+
+// Specify sheet selection metadata
+formData.append(
+ "fileResourceMetadata",
+ JSON.stringify({
+ [FILE_UUID]: {
+ selectedSheet: SELECTED_SHEET,
+ hasMultipleSheets: true,
+ },
+ })
+);
+
+// Add variable parameters
+formData.append("name", VARIABLE_NAME);
+formData.append("placeholder", VARIABLE_PLACEHOLDER);
+formData.append("aiHint", AI_HINT);
+formData.append("richTextEnabled", RICH_TEXT_ENABLED);
+
+const response = await fetch(API_URL, {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${API_TOKEN}`,
+ "x-rapiddocx-org-id": ORGANIZATION_ID,
+ // Note: Don't set Content-Type - let browser set multipart boundary
+ },
+ body: formData,
+});
```
### 2. Contract Key Terms Extraction
**Scenario**: Extract important terms and dates from legal documents
-```bash
-curl 'https://api.turbodocx.com/ai/generate/variable/one' \
- -H 'Authorization: Bearer YOUR_API_TOKEN' \
- -H 'x-rapiddocx-org-id: YOUR_ORG_ID' \
- -H 'Content-Type: multipart/form-data' \
- -F 'FileResource-67890=@service-agreement.pdf' \
- -F 'name=Contract Terms' \
- -F 'placeholder={ContractTerms}' \
- -F 'aiHint=Extract contract duration, payment terms, key obligations, and important deadlines in a structured format' \
- -F 'richTextEnabled=false'
+```javascript
+// Configuration variables
+const API_TOKEN = "YOUR_API_TOKEN";
+const ORGANIZATION_ID = "YOUR_ORGANIZATION_ID";
+const API_URL = "https://api.turbodocx.com/ai/generate/variable/one";
+const FILE_UUID = "67890";
+const VARIABLE_NAME = "Contract Terms";
+const VARIABLE_PLACEHOLDER = "{ContractTerms}";
+const AI_HINT = "Extract contract duration, payment terms, key obligations, and important deadlines in a structured format";
+const RICH_TEXT_ENABLED = "false";
+
+// Create FormData for service agreement upload
+const formData = new FormData();
+
+// Attach the service agreement document
+formData.append(`FileResource-${FILE_UUID}`, serviceAgreementFile);
+
+// Add variable parameters
+formData.append("name", VARIABLE_NAME);
+formData.append("placeholder", VARIABLE_PLACEHOLDER);
+formData.append("aiHint", AI_HINT);
+formData.append("richTextEnabled", RICH_TEXT_ENABLED);
+
+const response = await fetch(API_URL, {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${API_TOKEN}`,
+ "x-rapiddocx-org-id": ORGANIZATION_ID,
+ // Note: Don't set Content-Type - let browser set multipart boundary
+ },
+ body: formData,
+});
```
### 3. Project Proposal Generation
**Scenario**: Create project descriptions based on scope documents
-```bash
-curl 'https://api.turbodocx.com/ai/generate/variable/one' \
- -H 'Authorization: Bearer YOUR_API_TOKEN' \
- -H 'x-rapiddocx-org-id: YOUR_ORG_ID' \
- -H 'Content-Type: multipart/form-data' \
- -F 'FileResource-abcde=@project-requirements.docx' \
- -F 'name=Project Description' \
- -F 'placeholder={ProjectDescription}' \
- -F 'templateId=proposal-template-123' \
- -F 'aiHint=Generate a professional project description including objectives, deliverables, timeline, and success criteria based on the requirements document' \
- -F 'richTextEnabled=true'
+```javascript
+// Configuration variables
+const API_TOKEN = "YOUR_API_TOKEN";
+const ORGANIZATION_ID = "YOUR_ORGANIZATION_ID";
+const API_URL = "https://api.turbodocx.com/ai/generate/variable/one";
+const FILE_UUID = "abcde";
+const VARIABLE_NAME = "Project Description";
+const VARIABLE_PLACEHOLDER = "{ProjectDescription}";
+const AI_HINT = "Generate a professional project description including objectives, deliverables, timeline, and success criteria based on the requirements document";
+const RICH_TEXT_ENABLED = "true";
+
+// Create FormData for project requirements upload
+const formData = new FormData();
+
+// Attach the project requirements document
+formData.append(`FileResource-${FILE_UUID}`, projectRequirementsFile);
+
+// Add variable parameters
+formData.append("name", VARIABLE_NAME);
+formData.append("placeholder", VARIABLE_PLACEHOLDER);
+formData.append("aiHint", AI_HINT);
+formData.append("richTextEnabled", RICH_TEXT_ENABLED);
+
+const response = await fetch(API_URL, {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${API_TOKEN}`,
+ "x-rapiddocx-org-id": ORGANIZATION_ID,
+ // Note: Don't set Content-Type - let browser set multipart boundary
+ },
+ body: formData,
+});
```
### 4. Data-Driven Insights
**Scenario**: Generate insights from research data and surveys
-```bash
-curl 'https://api.turbodocx.com/ai/generate/variable/one' \
- -H 'Authorization: Bearer YOUR_API_TOKEN' \
- -H 'x-rapiddocx-org-id: YOUR_ORG_ID' \
- -H 'Content-Type: multipart/form-data' \
- -F 'FileResource-xyz789=@market-research.xlsx' \
- -F 'fileResourceMetadata={"xyz789":{"selectedSheet":"Survey Results","hasMultipleSheets":true}}' \
- -F 'name=Market Insights' \
- -F 'placeholder={MarketInsights}' \
- -F 'aiHint=Analyze the survey data and generate key market insights, trends, and actionable recommendations for product strategy' \
- -F 'richTextEnabled=true'
+```javascript
+// Configuration variables
+const API_TOKEN = "YOUR_API_TOKEN";
+const ORGANIZATION_ID = "YOUR_ORGANIZATION_ID";
+const API_URL = "https://api.turbodocx.com/ai/generate/variable/one";
+const FILE_UUID = "xyz789";
+const VARIABLE_NAME = "Market Insights";
+const VARIABLE_PLACEHOLDER = "{MarketInsights}";
+const SELECTED_SHEET = "Survey Results";
+const AI_HINT = "Analyze the survey data and generate key market insights, trends, and actionable recommendations for product strategy";
+const RICH_TEXT_ENABLED = "true";
+
+// Create FormData for market research data upload
+const formData = new FormData();
+
+// Attach the market research spreadsheet
+formData.append(`FileResource-${FILE_UUID}`, marketResearchFile);
+
+// Specify survey results sheet metadata
+formData.append(
+ "fileResourceMetadata",
+ JSON.stringify({
+ [FILE_UUID]: {
+ selectedSheet: SELECTED_SHEET,
+ hasMultipleSheets: true,
+ },
+ })
+);
+
+// Add variable parameters
+formData.append("name", VARIABLE_NAME);
+formData.append("placeholder", VARIABLE_PLACEHOLDER);
+formData.append("aiHint", AI_HINT);
+formData.append("richTextEnabled", RICH_TEXT_ENABLED);
+
+const response = await fetch(API_URL, {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${API_TOKEN}`,
+ "x-rapiddocx-org-id": ORGANIZATION_ID,
+ // Note: Don't set Content-Type - let browser set multipart boundary
+ },
+ body: formData,
+});
```
## AI Prompt Engineering
diff --git a/static/img/ai/ai.png b/static/img/ai/ai.png
new file mode 100644
index 0000000..4917d51
Binary files /dev/null and b/static/img/ai/ai.png differ
diff --git a/static/img/template-generation-api/banner.gif b/static/img/template-generation-api/banner.gif
deleted file mode 100644
index c67ac30..0000000
Binary files a/static/img/template-generation-api/banner.gif and /dev/null differ
diff --git a/static/img/template-generation-api/banner.png b/static/img/template-generation-api/banner.png
new file mode 100644
index 0000000..a5778d5
Binary files /dev/null and b/static/img/template-generation-api/banner.png differ
diff --git a/static/scripts/ai/variable-generation/csharp/controller.cs b/static/scripts/ai/variable-generation/csharp/controller.cs
new file mode 100644
index 0000000..b5b6aa4
--- /dev/null
+++ b/static/scripts/ai/variable-generation/csharp/controller.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+using System.Text.Json;
+using System.Text;
+
+class Program
+{
+ // Configuration
+ private const string API_TOKEN = "YOUR_API_TOKEN";
+ private const string ORG_ID = "YOUR_ORGANIZATION_ID";
+ private const string BASE_URL = "https://api.turbodocx.com";
+
+ static async Task Main(string[] args)
+ {
+ try
+ {
+ await GenerateAIVariable();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Error: {ex.Message}");
+ }
+ }
+
+ static async Task GenerateAIVariable()
+ {
+ using var client = new HttpClient();
+
+ var payload = new
+ {
+ name = "Company Performance Summary",
+ placeholder = "{Q4Performance}",
+ aiHint = "Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements",
+ richTextEnabled = true
+ };
+
+ string jsonPayload = JsonSerializer.Serialize(payload);
+ var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
+
+ // Set headers
+ client.DefaultRequestHeaders.Add("Authorization", $"Bearer {API_TOKEN}");
+ client.DefaultRequestHeaders.Add("x-rapiddocx-org-id", ORG_ID);
+
+ // Send request
+ var response = await client.PostAsync($"{BASE_URL}/ai/generate/variable/one", content);
+
+ if (!response.IsSuccessStatusCode)
+ {
+ throw new HttpRequestException($"AI generation failed: {response.StatusCode}");
+ }
+
+ var result = await response.Content.ReadAsStringAsync();
+ Console.WriteLine($"Generated variable: {result}");
+ }
+}
\ No newline at end of file
diff --git a/static/scripts/ai/variable-generation/csharp/minimal.cs b/static/scripts/ai/variable-generation/csharp/minimal.cs
new file mode 100644
index 0000000..b5b6aa4
--- /dev/null
+++ b/static/scripts/ai/variable-generation/csharp/minimal.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+using System.Text.Json;
+using System.Text;
+
+class Program
+{
+ // Configuration
+ private const string API_TOKEN = "YOUR_API_TOKEN";
+ private const string ORG_ID = "YOUR_ORGANIZATION_ID";
+ private const string BASE_URL = "https://api.turbodocx.com";
+
+ static async Task Main(string[] args)
+ {
+ try
+ {
+ await GenerateAIVariable();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Error: {ex.Message}");
+ }
+ }
+
+ static async Task GenerateAIVariable()
+ {
+ using var client = new HttpClient();
+
+ var payload = new
+ {
+ name = "Company Performance Summary",
+ placeholder = "{Q4Performance}",
+ aiHint = "Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements",
+ richTextEnabled = true
+ };
+
+ string jsonPayload = JsonSerializer.Serialize(payload);
+ var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
+
+ // Set headers
+ client.DefaultRequestHeaders.Add("Authorization", $"Bearer {API_TOKEN}");
+ client.DefaultRequestHeaders.Add("x-rapiddocx-org-id", ORG_ID);
+
+ // Send request
+ var response = await client.PostAsync($"{BASE_URL}/ai/generate/variable/one", content);
+
+ if (!response.IsSuccessStatusCode)
+ {
+ throw new HttpRequestException($"AI generation failed: {response.StatusCode}");
+ }
+
+ var result = await response.Content.ReadAsStringAsync();
+ Console.WriteLine($"Generated variable: {result}");
+ }
+}
\ No newline at end of file
diff --git a/static/scripts/ai/variable-generation/curl.sh b/static/scripts/ai/variable-generation/curl.sh
index ffb3a21..cfdb776 100644
--- a/static/scripts/ai/variable-generation/curl.sh
+++ b/static/scripts/ai/variable-generation/curl.sh
@@ -1,103 +1,41 @@
#!/bin/bash
-# Configuration - Update these values
+# Configuration
API_TOKEN="YOUR_API_TOKEN"
ORG_ID="YOUR_ORGANIZATION_ID"
BASE_URL="https://api.turbodocx.com"
-##
-# AI-Powered Variable Generation Examples
-# Generate intelligent content for template variables using AI with optional file attachments
-##
-
-# Example 1: Basic AI Variable Generation (no file attachment)
-echo "=== Example 1: Basic AI Variable Generation ==="
-curl "${BASE_URL}/ai/generate/variable/one" \
- -H "Authorization: Bearer ${API_TOKEN}" \
- -H "x-rapiddocx-org-id: ${ORG_ID}" \
- -H "User-Agent: TurboDocx AI Client" \
- -H "Content-Type: multipart/form-data" \
- -F "name=Company Overview" \
- -F "placeholder={CompanyOverview}" \
- -F "aiHint=Generate a professional company overview for a technology consulting firm specializing in digital transformation" \
- -F "richTextEnabled=false"
-
-echo -e "\n=== Example 2: AI Generation with Excel File Attachment ==="
-# Example 2: AI Variable Generation with Excel File
-curl "${BASE_URL}/ai/generate/variable/one" \
- -H "Authorization: Bearer ${API_TOKEN}" \
- -H "x-rapiddocx-org-id: ${ORG_ID}" \
- -H "User-Agent: TurboDocx AI Client" \
- -H "Content-Type: multipart/form-data" \
- -F "FileResource-e0f12963-10ff-496a-9703-06df14f171af=@financial-report.xlsx" \
- -F "fileResourceMetadata={\"e0f12963-10ff-496a-9703-06df14f171af\":{\"selectedSheet\":\"Q4 Results\",\"hasMultipleSheets\":true,\"dataRange\":\"A1:F50\"}}" \
- -F "name=Financial Performance Summary" \
- -F "placeholder={FinancialSummary}" \
- -F "templateId=quarterly-report-template-123" \
- -F "aiHint=Analyze the Q4 financial data and generate a comprehensive executive summary highlighting revenue growth, profit margins, and key performance indicators" \
- -F "richTextEnabled=true"
-
-echo -e "\n=== Example 3: AI Generation with Word Document ==="
-# Example 3: AI Variable Generation with Word Document
-curl "${BASE_URL}/ai/generate/variable/one" \
- -H "Authorization: Bearer ${API_TOKEN}" \
- -H "x-rapiddocx-org-id: ${ORG_ID}" \
- -H "User-Agent: TurboDocx AI Client" \
- -H "Content-Type: multipart/form-data" \
- -F "FileResource-abc12345-def6-789a-bcde-123456789abc=@project-requirements.docx" \
- -F "fileResourceMetadata={\"abc12345-def6-789a-bcde-123456789abc\":{\"contentType\":\"project-document\"}}" \
- -F "name=Project Scope" \
- -F "placeholder={ProjectScope}" \
- -F "templateId=project-proposal-template-456" \
- -F "aiHint=Based on the project requirements document, create a detailed project scope including objectives, deliverables, timeline, and success criteria" \
- -F "richTextEnabled=true"
-
-echo -e "\n=== Example 4: Contract Analysis ==="
-# Example 4: Legal Document Analysis
-curl "${BASE_URL}/ai/generate/variable/one" \
- -H "Authorization: Bearer ${API_TOKEN}" \
- -H "x-rapiddocx-org-id: ${ORG_ID}" \
- -H "User-Agent: TurboDocx AI Client" \
- -H "Content-Type: multipart/form-data" \
- -F "FileResource-legal123-456a-789b-cdef-987654321abc=@service-agreement.pdf" \
- -F "fileResourceMetadata={\"legal123-456a-789b-cdef-987654321abc\":{\"contentType\":\"legal-document\"}}" \
- -F "name=Contract Key Terms" \
- -F "placeholder={KeyTerms}" \
- -F "aiHint=Extract and summarize the key terms, payment obligations, contract duration, and important deadlines from this service agreement" \
- -F "richTextEnabled=false"
-
-echo -e "\n=== Example 5: Rich Text Generation ==="
-# Example 5: Rich Text Content Generation
-curl "${BASE_URL}/ai/generate/variable/one" \
- -H "Authorization: Bearer ${API_TOKEN}" \
- -H "x-rapiddocx-org-id: ${ORG_ID}" \
- -H "User-Agent: TurboDocx AI Client" \
- -H "Content-Type: multipart/form-data" \
- -F "name=Marketing Campaign Summary" \
- -F "placeholder={CampaignSummary}" \
- -F "templateId=marketing-report-template-789" \
- -F "aiHint=Create a comprehensive marketing campaign summary with bullet points for key metrics, formatted sections for strategy overview, and highlighted call-to-action recommendations" \
- -F "richTextEnabled=true"
-
-echo -e "\n=== Example 6: Data Analysis with CSV ==="
-# Example 6: CSV Data Analysis
-curl "${BASE_URL}/ai/generate/variable/one" \
- -H "Authorization: Bearer ${API_TOKEN}" \
- -H "x-rapiddocx-org-id: ${ORG_ID}" \
- -H "User-Agent: TurboDocx AI Client" \
- -H "Content-Type: multipart/form-data" \
- -F "FileResource-data789-abc1-2345-6def-abcdef123456=@sales-data.csv" \
- -F "fileResourceMetadata={\"data789-abc1-2345-6def-abcdef123456\":{\"contentType\":\"sales-data\",\"hasHeaders\":true}}" \
- -F "name=Sales Performance Analysis" \
- -F "placeholder={SalesAnalysis}" \
- -F "aiHint=Analyze the sales data to identify top-performing products, seasonal trends, and growth opportunities. Provide actionable insights for sales strategy" \
- -F "richTextEnabled=true"
-
-echo -e "\n=== AI Variable Generation Examples Complete ==="
-echo "All examples demonstrate different aspects of AI-powered variable generation:"
-echo "1. Basic text generation without file attachments"
-echo "2. Excel spreadsheet analysis with sheet selection"
-echo "3. Word document content extraction"
-echo "4. Legal document term extraction"
-echo "5. Rich text formatting for presentation"
-echo "6. CSV data analysis and insights"
\ No newline at end of file
+# AI Variable Generation Example
+echo "🤖 Generating AI Variable..."
+
+# Generate AI variable
+RESPONSE=$(curl -s -X POST "$BASE_URL/ai/generate/variable/one" \
+ -H "Authorization: Bearer $API_TOKEN" \
+ -H "x-rapiddocx-org-id: $ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "name": "Company Performance Summary",
+ "placeholder": "{Q4Performance}",
+ "aiHint": "Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements",
+ "richTextEnabled": true
+ }')
+
+# Check if generation was successful
+if [ $? -ne 0 ]; then
+ echo "❌ AI generation failed"
+ exit 1
+fi
+
+# Extract and display result
+GENERATED_TEXT=$(echo "$RESPONSE" | jq -r '.data.text')
+CONTENT_TYPE=$(echo "$RESPONSE" | jq -r '.data.mimeType')
+
+if [ "$GENERATED_TEXT" == "null" ] || [ -z "$GENERATED_TEXT" ]; then
+ echo "❌ Failed to extract generated content from response"
+ echo "Response: $RESPONSE"
+ exit 1
+fi
+
+echo "✅ AI Variable generated successfully!"
+echo "Content Type: $CONTENT_TYPE"
+echo "Generated Content: $GENERATED_TEXT"
\ No newline at end of file
diff --git a/static/scripts/ai/variable-generation/go.go b/static/scripts/ai/variable-generation/go.go
new file mode 100644
index 0000000..aa718a4
--- /dev/null
+++ b/static/scripts/ai/variable-generation/go.go
@@ -0,0 +1,63 @@
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "net/http"
+)
+
+// Configuration
+const (
+ API_TOKEN = "YOUR_API_TOKEN"
+ ORG_ID = "YOUR_ORGANIZATION_ID"
+ BASE_URL = "https://api.turbodocx.com"
+)
+
+func generateAIVariable() error {
+ payload := map[string]interface{}{
+ "name": "Company Performance Summary",
+ "placeholder": "{Q4Performance}",
+ "aiHint": "Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements",
+ "richTextEnabled": true,
+ }
+
+ jsonData, err := json.Marshal(payload)
+ if err != nil {
+ return err
+ }
+
+ // Create request
+ req, err := http.NewRequest("POST", BASE_URL+"/ai/generate/variable/one", bytes.NewBuffer(jsonData))
+ if err != nil {
+ return err
+ }
+
+ req.Header.Set("Authorization", "Bearer "+API_TOKEN)
+ req.Header.Set("x-rapiddocx-org-id", ORG_ID)
+ req.Header.Set("Content-Type", "application/json")
+
+ // Send request
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ return fmt.Errorf("AI generation failed: %d", resp.StatusCode)
+ }
+
+ var result map[string]interface{}
+ json.NewDecoder(resp.Body).Decode(&result)
+
+ fmt.Printf("Generated variable: %+v\n", result["data"])
+ return nil
+}
+
+func main() {
+ if err := generateAIVariable(); err != nil {
+ fmt.Printf("Error: %v\n", err)
+ }
+}
\ No newline at end of file
diff --git a/static/scripts/ai/variable-generation/java.java b/static/scripts/ai/variable-generation/java.java
new file mode 100644
index 0000000..e631bea
--- /dev/null
+++ b/static/scripts/ai/variable-generation/java.java
@@ -0,0 +1,53 @@
+import java.io.*;
+import java.net.http.*;
+import java.net.URI;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.Map;
+import java.util.HashMap;
+
+public class AIVariableGenerator {
+ // Configuration
+ private static final String API_TOKEN = "YOUR_API_TOKEN";
+ private static final String ORG_ID = "YOUR_ORGANIZATION_ID";
+ private static final String BASE_URL = "https://api.turbodocx.com";
+
+ public static void main(String[] args) {
+ try {
+ generateAIVariable();
+ } catch (Exception e) {
+ System.err.println("Error: " + e.getMessage());
+ }
+ }
+
+ public static void generateAIVariable() throws Exception {
+ ObjectMapper mapper = new ObjectMapper();
+
+ // Create payload
+ Map payload = new HashMap<>();
+ payload.put("name", "Company Performance Summary");
+ payload.put("placeholder", "{Q4Performance}");
+ payload.put("aiHint", "Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements");
+ payload.put("richTextEnabled", true);
+
+ String jsonPayload = mapper.writeValueAsString(payload);
+
+ // Create request
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(BASE_URL + "/ai/generate/variable/one"))
+ .header("Authorization", "Bearer " + API_TOKEN)
+ .header("x-rapiddocx-org-id", ORG_ID)
+ .header("Content-Type", "application/json")
+ .POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
+ .build();
+
+ // Send request
+ HttpClient client = HttpClient.newHttpClient();
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+
+ if (response.statusCode() != 200) {
+ throw new RuntimeException("AI generation failed: " + response.statusCode());
+ }
+
+ System.out.println("Generated variable: " + response.body());
+ }
+}
\ No newline at end of file
diff --git a/static/scripts/ai/variable-generation/javascript.js b/static/scripts/ai/variable-generation/javascript.js
index 3b3bca8..ff3a7a9 100644
--- a/static/scripts/ai/variable-generation/javascript.js
+++ b/static/scripts/ai/variable-generation/javascript.js
@@ -17,7 +17,6 @@ async function generateAIVariable(options) {
fileMetadata,
name,
placeholder,
- templateId,
aiHint,
richTextEnabled = false
} = options;
@@ -48,10 +47,6 @@ async function generateAIVariable(options) {
formData.append('aiHint', aiHint);
formData.append('richTextEnabled', richTextEnabled.toString());
- if (templateId) {
- formData.append('templateId', templateId);
- }
-
try {
const response = await fetch(`${BASE_URL}/ai/generate/variable/one`, {
method: 'POST',
@@ -132,7 +127,6 @@ async function example2_ExcelAnalysis(excelFile) {
},
name: 'Financial Performance Summary',
placeholder: '{FinancialSummary}',
- templateId: 'quarterly-report-template-123',
aiHint: 'Analyze the Q4 financial data and generate a comprehensive executive summary highlighting revenue growth, profit margins, key performance indicators, and strategic recommendations',
richTextEnabled: true
});
@@ -159,7 +153,6 @@ async function example3_DocumentAnalysis(wordFile) {
},
name: 'Project Scope',
placeholder: '{ProjectScope}',
- templateId: 'project-proposal-template-456',
aiHint: 'Based on the project requirements document, create a detailed project scope including objectives, key deliverables, timeline milestones, and success criteria',
richTextEnabled: true
});
@@ -208,7 +201,6 @@ async function example5_RichTextGeneration() {
const result = await generateAIVariable({
name: 'Marketing Campaign Summary',
placeholder: '{CampaignSummary}',
- templateId: 'marketing-report-template-789',
aiHint: 'Create a comprehensive marketing campaign summary with structured sections: Executive Overview, Key Metrics (with specific numbers), Strategic Insights, and Action Items. Format with appropriate headings and bullet points.',
richTextEnabled: true
});
diff --git a/static/scripts/ai/variable-generation/nodejs/express.js b/static/scripts/ai/variable-generation/nodejs/express.js
index 41f8bde..4d26813 100644
--- a/static/scripts/ai/variable-generation/nodejs/express.js
+++ b/static/scripts/ai/variable-generation/nodejs/express.js
@@ -1,395 +1,36 @@
-const express = require('express');
-const multer = require('multer');
-const FormData = require('form-data');
-const axios = require('axios');
-const fs = require('fs');
-const { v4: uuidv4 } = require('uuid');
+const fetch = require('node-fetch');
-// Configuration - Update these values
+// Configuration
const API_TOKEN = "YOUR_API_TOKEN";
const ORG_ID = "YOUR_ORGANIZATION_ID";
const BASE_URL = "https://api.turbodocx.com";
-const app = express();
-const upload = multer({ dest: 'uploads/' });
-
-// Middleware
-app.use(express.json());
-app.use(express.static('public'));
-
-/**
- * AI-Powered Variable Generation Service
- */
-class AIVariableService {
- constructor(apiToken, orgId, baseUrl = BASE_URL) {
- this.apiToken = apiToken;
- this.orgId = orgId;
- this.baseUrl = baseUrl;
- }
-
- /**
- * Generate AI-powered variable content with optional file attachment
- */
- async generateVariable(options) {
- const {
- file,
- fileMetadata,
- name,
- placeholder,
- templateId,
- aiHint,
- richTextEnabled = false
- } = options;
-
- const form = new FormData();
-
- // Add file if provided
- if (file) {
- const fileUuid = uuidv4();
- form.append(`FileResource-${fileUuid}`, fs.createReadStream(file.path), {
- filename: file.originalname,
- contentType: this.getContentType(file.originalname)
- });
-
- // Add file metadata
- const metadata = {
- [fileUuid]: {
- selectedSheet: fileMetadata?.selectedSheet || "Sheet1",
- hasMultipleSheets: fileMetadata?.hasMultipleSheets || false,
- contentType: fileMetadata?.contentType || "document",
- dataRange: fileMetadata?.dataRange,
- hasHeaders: fileMetadata?.hasHeaders
- }
- };
- form.append('fileResourceMetadata', JSON.stringify(metadata));
- }
-
- // Add variable parameters
- form.append('name', name);
- form.append('placeholder', placeholder);
- form.append('aiHint', aiHint);
- form.append('richTextEnabled', richTextEnabled.toString());
-
- if (templateId) {
- form.append('templateId', templateId);
- }
-
- try {
- console.log(`Generating AI variable: ${name}`);
- console.log(`AI Hint: ${aiHint.substring(0, 100)}...`);
-
- const response = await axios.post(`${this.baseUrl}/ai/generate/variable/one`, form, {
- headers: {
- 'Authorization': `Bearer ${this.apiToken}`,
- 'x-rapiddocx-org-id': this.orgId,
- 'User-Agent': 'TurboDocx AI Client',
- ...form.getHeaders()
- }
- });
-
- console.log('✅ AI Variable generated successfully!');
- console.log(`Content Type: ${response.data.data.mimeType}`);
- console.log(`Generated Content: ${response.data.data.text.substring(0, 100)}...`);
-
- // Clean up uploaded file
- if (file && fs.existsSync(file.path)) {
- fs.unlinkSync(file.path);
- }
-
- return response.data;
-
- } catch (error) {
- console.error('❌ AI Variable generation failed:', error.response?.data || error.message);
-
- // Clean up on error
- if (file && fs.existsSync(file.path)) {
- fs.unlinkSync(file.path);
- }
-
- throw error;
- }
- }
-
- /**
- * Get content type based on file extension
- */
- getContentType(filename) {
- const ext = filename.toLowerCase().split('.').pop();
- const contentTypes = {
- 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- 'xls': 'application/vnd.ms-excel',
- 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'doc': 'application/msword',
- 'pdf': 'application/pdf',
- 'csv': 'text/csv',
- 'txt': 'text/plain',
- 'png': 'image/png',
- 'jpg': 'image/jpeg',
- 'jpeg': 'image/jpeg'
- };
- return contentTypes[ext] || 'application/octet-stream';
- }
+async function generateAIVariable() {
+ const payload = {
+ name: 'Company Performance Summary',
+ placeholder: '{Q4Performance}',
+ aiHint: 'Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements',
+ richTextEnabled: true
+ };
+
+ const response = await fetch(`${BASE_URL}/ai/generate/variable/one`, {
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${API_TOKEN}`,
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(payload)
+ });
+
+ if (!response.ok) {
+ throw new Error(`AI generation failed: ${response.status}`);
+ }
+
+ const result = await response.json();
+ console.log('Generated variable:', result.data);
+ return result;
}
-// Initialize service
-const aiService = new AIVariableService(API_TOKEN, ORG_ID);
-
-// Routes
-
-/**
- * Generate AI variable without file attachment
- */
-app.post('/ai/generate-basic', async (req, res) => {
- try {
- const { name, placeholder, aiHint, templateId, richTextEnabled } = req.body;
-
- if (!name || !placeholder || !aiHint) {
- return res.status(400).json({
- error: 'Missing required fields: name, placeholder, aiHint'
- });
- }
-
- const result = await aiService.generateVariable({
- name,
- placeholder,
- aiHint,
- templateId,
- richTextEnabled: richTextEnabled === 'true' || richTextEnabled === true
- });
-
- res.json({
- success: true,
- message: 'AI variable generated successfully',
- data: result
- });
-
- } catch (error) {
- console.error('Error in basic generation:', error);
- res.status(500).json({
- error: 'AI variable generation failed',
- message: error.message
- });
- }
-});
-
-/**
- * Generate AI variable with file attachment
- */
-app.post('/ai/generate-with-file', upload.single('file'), async (req, res) => {
- try {
- const { name, placeholder, aiHint, templateId, richTextEnabled } = req.body;
- const file = req.file;
-
- if (!name || !placeholder || !aiHint) {
- return res.status(400).json({
- error: 'Missing required fields: name, placeholder, aiHint'
- });
- }
-
- // Parse file metadata if provided
- let fileMetadata = {};
- if (req.body.fileMetadata) {
- try {
- fileMetadata = JSON.parse(req.body.fileMetadata);
- } catch (e) {
- console.warn('Invalid file metadata JSON, using defaults');
- }
- }
-
- const result = await aiService.generateVariable({
- file,
- fileMetadata,
- name,
- placeholder,
- aiHint,
- templateId,
- richTextEnabled: richTextEnabled === 'true' || richTextEnabled === true
- });
-
- res.json({
- success: true,
- message: 'AI variable generated successfully with file',
- data: result
- });
-
- } catch (error) {
- console.error('Error in file-based generation:', error);
- res.status(500).json({
- error: 'AI variable generation with file failed',
- message: error.message
- });
- }
-});
-
-/**
- * Batch AI variable generation
- */
-app.post('/ai/generate-batch', upload.single('file'), async (req, res) => {
- try {
- const { variables } = req.body;
- const file = req.file;
-
- if (!variables) {
- return res.status(400).json({
- error: 'Missing variables array'
- });
- }
-
- const variableList = JSON.parse(variables);
-
- // Parse file metadata if provided
- let fileMetadata = {};
- if (req.body.fileMetadata) {
- try {
- fileMetadata = JSON.parse(req.body.fileMetadata);
- } catch (e) {
- console.warn('Invalid file metadata JSON, using defaults');
- }
- }
-
- const results = [];
- for (const variable of variableList) {
- try {
- const result = await aiService.generateVariable({
- file: file ? { ...file, path: file.path } : null,
- fileMetadata,
- name: variable.name,
- placeholder: variable.placeholder,
- aiHint: variable.aiHint,
- templateId: variable.templateId,
- richTextEnabled: variable.richTextEnabled || false
- });
- results.push({ success: true, variable: variable.name, data: result });
- } catch (error) {
- results.push({ success: false, variable: variable.name, error: error.message });
- }
- }
-
- res.json({
- success: true,
- message: 'Batch AI variable generation completed',
- results: results
- });
-
- } catch (error) {
- console.error('Error in batch generation:', error);
- res.status(500).json({
- error: 'Batch AI variable generation failed',
- message: error.message
- });
- }
-});
-
-/**
- * Health check endpoint
- */
-app.get('/health', (req, res) => {
- res.json({
- status: 'healthy',
- service: 'ai-variable-generation',
- timestamp: new Date().toISOString()
- });
-});
-
-/**
- * Service information endpoint
- */
-app.get('/ai/info', (req, res) => {
- res.json({
- service: 'TurboDocx AI Variable Generation Service',
- endpoints: {
- 'POST /ai/generate-basic': 'Generate AI variable without file attachment',
- 'POST /ai/generate-with-file': 'Generate AI variable with file attachment',
- 'POST /ai/generate-batch': 'Batch generate multiple AI variables',
- 'GET /health': 'Service health check',
- 'GET /ai/info': 'Service information'
- },
- configuration: {
- baseUrl: BASE_URL,
- hasToken: !!API_TOKEN && API_TOKEN !== 'YOUR_API_TOKEN',
- hasOrgId: !!ORG_ID && ORG_ID !== 'YOUR_ORGANIZATION_ID'
- },
- supportedFileTypes: [
- 'Excel (.xlsx, .xls)',
- 'Word (.docx, .doc)',
- 'PDF (.pdf)',
- 'CSV (.csv)',
- 'Text (.txt)',
- 'Images (.png, .jpg, .jpeg)'
- ]
- });
-});
-
-/**
- * Example usage endpoint
- */
-app.get('/ai/examples', (req, res) => {
- res.json({
- examples: [
- {
- name: 'Basic Generation',
- endpoint: 'POST /ai/generate-basic',
- payload: {
- name: 'Company Overview',
- placeholder: '{CompanyOverview}',
- aiHint: 'Generate a professional company overview for a technology consulting firm',
- richTextEnabled: false
- }
- },
- {
- name: 'Excel Analysis',
- endpoint: 'POST /ai/generate-with-file',
- payload: {
- name: 'Financial Summary',
- placeholder: '{FinancialSummary}',
- aiHint: 'Analyze Q4 financial data and generate executive summary',
- fileMetadata: JSON.stringify({
- selectedSheet: 'Q4 Results',
- hasMultipleSheets: true
- }),
- richTextEnabled: true
- },
- note: 'Include Excel file in multipart form data'
- },
- {
- name: 'Document Analysis',
- endpoint: 'POST /ai/generate-with-file',
- payload: {
- name: 'Project Scope',
- placeholder: '{ProjectScope}',
- aiHint: 'Extract project scope from requirements document',
- fileMetadata: JSON.stringify({
- contentType: 'project-document'
- }),
- richTextEnabled: true
- },
- note: 'Include Word/PDF file in multipart form data'
- }
- ]
- });
-});
-
-// Error handling middleware
-app.use((error, req, res, next) => {
- console.error('Unhandled error:', error);
- res.status(500).json({
- error: 'Internal server error',
- message: error.message
- });
-});
-
-// Start server
-const PORT = process.env.PORT || 3001;
-app.listen(PORT, () => {
- console.log('🤖 TurboDocx AI Variable Generation Service started');
- console.log(`📡 Server listening on http://localhost:${PORT}`);
- console.log('\nAvailable endpoints:');
- console.log(` POST http://localhost:${PORT}/ai/generate-basic`);
- console.log(` POST http://localhost:${PORT}/ai/generate-with-file`);
- console.log(` POST http://localhost:${PORT}/ai/generate-batch`);
- console.log(` GET http://localhost:${PORT}/health`);
- console.log(` GET http://localhost:${PORT}/ai/info`);
- console.log(` GET http://localhost:${PORT}/ai/examples`);
-});
-
-module.exports = app;
\ No newline at end of file
+// Run the example
+generateAIVariable().catch(console.error);
\ No newline at end of file
diff --git a/static/scripts/ai/variable-generation/nodejs/fastify.js b/static/scripts/ai/variable-generation/nodejs/fastify.js
index 8ee590a..4d26813 100644
--- a/static/scripts/ai/variable-generation/nodejs/fastify.js
+++ b/static/scripts/ai/variable-generation/nodejs/fastify.js
@@ -1,571 +1,36 @@
-const fastify = require('fastify')({ logger: true });
-const FormData = require('form-data');
-const axios = require('axios');
-const fs = require('fs');
-const { v4: uuidv4 } = require('uuid');
+const fetch = require('node-fetch');
-// Configuration - Update these values
+// Configuration
const API_TOKEN = "YOUR_API_TOKEN";
const ORG_ID = "YOUR_ORGANIZATION_ID";
const BASE_URL = "https://api.turbodocx.com";
-/**
- * AI-Powered Variable Generation Service
- */
-class AIVariableService {
- constructor(apiToken, orgId, baseUrl = BASE_URL) {
- this.apiToken = apiToken;
- this.orgId = orgId;
- this.baseUrl = baseUrl;
- }
-
- /**
- * Generate AI-powered variable content with optional file attachment
- */
- async generateVariable(options) {
- const {
- file,
- fileMetadata,
- name,
- placeholder,
- templateId,
- aiHint,
- richTextEnabled = false
- } = options;
-
- const form = new FormData();
-
- // Add file if provided
- if (file) {
- const fileUuid = uuidv4();
- const fileBuffer = await file.toBuffer();
-
- form.append(`FileResource-${fileUuid}`, fileBuffer, {
- filename: file.filename,
- contentType: this.getContentType(file.filename)
- });
-
- // Add file metadata
- const metadata = {
- [fileUuid]: {
- selectedSheet: fileMetadata?.selectedSheet || "Sheet1",
- hasMultipleSheets: fileMetadata?.hasMultipleSheets || false,
- contentType: fileMetadata?.contentType || "document",
- dataRange: fileMetadata?.dataRange,
- hasHeaders: fileMetadata?.hasHeaders
- }
- };
- form.append('fileResourceMetadata', JSON.stringify(metadata));
- }
-
- // Add variable parameters
- form.append('name', name);
- form.append('placeholder', placeholder);
- form.append('aiHint', aiHint);
- form.append('richTextEnabled', richTextEnabled.toString());
-
- if (templateId) {
- form.append('templateId', templateId);
- }
-
- try {
- console.log(`Generating AI variable: ${name}`);
- console.log(`AI Hint: ${aiHint.substring(0, 100)}...`);
-
- const response = await axios.post(`${this.baseUrl}/ai/generate/variable/one`, form, {
- headers: {
- 'Authorization': `Bearer ${this.apiToken}`,
- 'x-rapiddocx-org-id': this.orgId,
- 'User-Agent': 'TurboDocx AI Client',
- ...form.getHeaders()
- }
- });
-
- console.log('✅ AI Variable generated successfully!');
- console.log(`Content Type: ${response.data.data.mimeType}`);
- console.log(`Generated Content: ${response.data.data.text.substring(0, 100)}...`);
-
- return response.data;
-
- } catch (error) {
- console.error('❌ AI Variable generation failed:', error.response?.data || error.message);
- throw error;
- }
- }
-
- /**
- * Get content type based on file extension
- */
- getContentType(filename) {
- const ext = filename.toLowerCase().split('.').pop();
- const contentTypes = {
- 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- 'xls': 'application/vnd.ms-excel',
- 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'doc': 'application/msword',
- 'pdf': 'application/pdf',
- 'csv': 'text/csv',
- 'txt': 'text/plain',
- 'png': 'image/png',
- 'jpg': 'image/jpeg',
- 'jpeg': 'image/jpeg'
- };
- return contentTypes[ext] || 'application/octet-stream';
- }
-}
-
-// Initialize service
-const aiService = new AIVariableService(API_TOKEN, ORG_ID);
-
-// Register multipart content parsing
-fastify.register(require('@fastify/multipart'));
-
-// Routes
-
-/**
- * Generate AI variable without file attachment
- */
-fastify.post('/ai/generate-basic', async (request, reply) => {
- try {
- const { name, placeholder, aiHint, templateId, richTextEnabled } = request.body;
-
- if (!name || !placeholder || !aiHint) {
- return reply.code(400).send({
- error: 'Missing required fields: name, placeholder, aiHint'
- });
- }
-
- const result = await aiService.generateVariable({
- name,
- placeholder,
- aiHint,
- templateId,
- richTextEnabled: richTextEnabled === 'true' || richTextEnabled === true
- });
-
- reply.send({
- success: true,
- message: 'AI variable generated successfully',
- data: result
- });
-
- } catch (error) {
- fastify.log.error('Error in basic generation:', error);
- reply.code(500).send({
- error: 'AI variable generation failed',
- message: error.message
- });
- }
-});
-
-/**
- * Generate AI variable with file attachment
- */
-fastify.post('/ai/generate-with-file', async (request, reply) => {
- try {
- const parts = request.parts();
- let file = null;
- let fileMetadata = {};
- let name, placeholder, aiHint, templateId, richTextEnabled;
-
- // Process multipart data
- for await (const part of parts) {
- if (part.file) {
- file = part;
- } else {
- const value = part.value;
- switch (part.fieldname) {
- case 'name':
- name = value;
- break;
- case 'placeholder':
- placeholder = value;
- break;
- case 'aiHint':
- aiHint = value;
- break;
- case 'templateId':
- templateId = value;
- break;
- case 'richTextEnabled':
- richTextEnabled = value;
- break;
- case 'fileMetadata':
- try {
- fileMetadata = JSON.parse(value);
- } catch (e) {
- fastify.log.warn('Invalid file metadata JSON, using defaults');
- }
- break;
- }
- }
- }
-
- if (!name || !placeholder || !aiHint) {
- return reply.code(400).send({
- error: 'Missing required fields: name, placeholder, aiHint'
- });
- }
-
- const result = await aiService.generateVariable({
- file,
- fileMetadata,
- name,
- placeholder,
- aiHint,
- templateId,
- richTextEnabled: richTextEnabled === 'true' || richTextEnabled === true
- });
-
- reply.send({
- success: true,
- message: 'AI variable generated successfully with file',
- data: result
- });
-
- } catch (error) {
- fastify.log.error('Error in file-based generation:', error);
- reply.code(500).send({
- error: 'AI variable generation with file failed',
- message: error.message
- });
- }
-});
-
-/**
- * Batch AI variable generation
- */
-fastify.post('/ai/generate-batch', async (request, reply) => {
- try {
- const parts = request.parts();
- let file = null;
- let fileMetadata = {};
- let variables;
-
- // Process multipart data
- for await (const part of parts) {
- if (part.file) {
- file = part;
- } else {
- const value = part.value;
- switch (part.fieldname) {
- case 'variables':
- try {
- variables = JSON.parse(value);
- } catch (e) {
- return reply.code(400).send({
- error: 'Invalid variables JSON format'
- });
- }
- break;
- case 'fileMetadata':
- try {
- fileMetadata = JSON.parse(value);
- } catch (e) {
- fastify.log.warn('Invalid file metadata JSON, using defaults');
- }
- break;
- }
- }
- }
-
- if (!variables || !Array.isArray(variables)) {
- return reply.code(400).send({
- error: 'Missing or invalid variables array'
- });
- }
-
- const results = [];
- for (const variable of variables) {
- try {
- const result = await aiService.generateVariable({
- file,
- fileMetadata,
- name: variable.name,
- placeholder: variable.placeholder,
- aiHint: variable.aiHint,
- templateId: variable.templateId,
- richTextEnabled: variable.richTextEnabled || false
- });
- results.push({ success: true, variable: variable.name, data: result });
- } catch (error) {
- results.push({ success: false, variable: variable.name, error: error.message });
- }
- }
-
- reply.send({
- success: true,
- message: 'Batch AI variable generation completed',
- results: results
- });
-
- } catch (error) {
- fastify.log.error('Error in batch generation:', error);
- reply.code(500).send({
- error: 'Batch AI variable generation failed',
- message: error.message
- });
- }
-});
-
-/**
- * Complete workflow: AI generation + template integration
- */
-fastify.post('/ai/complete-workflow', async (request, reply) => {
- try {
- const parts = request.parts();
- let file = null;
- let fileMetadata = {};
- let templateId, aiHint, variableName, placeholder;
-
- // Process multipart data
- for await (const part of parts) {
- if (part.file) {
- file = part;
- } else {
- const value = part.value;
- switch (part.fieldname) {
- case 'templateId':
- templateId = value;
- break;
- case 'aiHint':
- aiHint = value;
- break;
- case 'variableName':
- variableName = value;
- break;
- case 'placeholder':
- placeholder = value;
- break;
- case 'fileMetadata':
- try {
- fileMetadata = JSON.parse(value);
- } catch (e) {
- fastify.log.warn('Invalid file metadata JSON, using defaults');
- }
- break;
- }
- }
- }
-
- if (!variableName || !placeholder || !aiHint) {
- return reply.code(400).send({
- error: 'Missing required fields: variableName, placeholder, aiHint'
- });
- }
-
- // Step 1: Generate AI content
- const aiResult = await aiService.generateVariable({
- file,
- fileMetadata,
- name: variableName,
- placeholder,
- aiHint,
- templateId,
- richTextEnabled: true
- });
-
- // Step 2: Prepare template variables
- const templateVariables = [{
- name: variableName,
- placeholder: placeholder,
- text: aiResult.data.text,
- mimeType: aiResult.data.mimeType,
- allowRichTextInjection: aiResult.data.mimeType === 'html' ? 1 : 0
- }];
-
- reply.send({
- success: true,
- message: 'Complete AI workflow executed successfully',
- data: {
- aiContent: aiResult,
- templateVariables: templateVariables,
- summary: {
- variableName: variableName,
- contentType: aiResult.data.mimeType,
- contentLength: aiResult.data.text.length
- }
- }
- });
-
- } catch (error) {
- fastify.log.error('Error in complete workflow:', error);
- reply.code(500).send({
- error: 'Complete AI workflow failed',
- message: error.message
- });
- }
-});
-
-/**
- * Health check endpoint
- */
-fastify.get('/health', async (request, reply) => {
- reply.send({
- status: 'healthy',
- service: 'ai-variable-generation',
- timestamp: new Date().toISOString()
- });
-});
-
-/**
- * Service information endpoint
- */
-fastify.get('/ai/info', async (request, reply) => {
- reply.send({
- service: 'TurboDocx AI Variable Generation Service (Fastify)',
- endpoints: {
- 'POST /ai/generate-basic': 'Generate AI variable without file attachment',
- 'POST /ai/generate-with-file': 'Generate AI variable with file attachment',
- 'POST /ai/generate-batch': 'Batch generate multiple AI variables',
- 'POST /ai/complete-workflow': 'Complete AI generation and template integration',
- 'GET /health': 'Service health check',
- 'GET /ai/info': 'Service information',
- 'GET /ai/examples': 'Usage examples'
- },
- configuration: {
- baseUrl: BASE_URL,
- hasToken: !!API_TOKEN && API_TOKEN !== 'YOUR_API_TOKEN',
- hasOrgId: !!ORG_ID && ORG_ID !== 'YOUR_ORGANIZATION_ID'
- },
- supportedFileTypes: [
- 'Excel (.xlsx, .xls)',
- 'Word (.docx, .doc)',
- 'PDF (.pdf)',
- 'CSV (.csv)',
- 'Text (.txt)',
- 'Images (.png, .jpg, .jpeg)'
- ]
- });
-});
-
-/**
- * Example usage endpoint
- */
-fastify.get('/ai/examples', async (request, reply) => {
- reply.send({
- examples: [
- {
- name: 'Basic Generation',
- endpoint: 'POST /ai/generate-basic',
- payload: {
- name: 'Company Overview',
- placeholder: '{CompanyOverview}',
- aiHint: 'Generate a professional company overview for a technology consulting firm',
- richTextEnabled: false
- }
- },
- {
- name: 'Excel Analysis',
- endpoint: 'POST /ai/generate-with-file',
- description: 'Upload Excel file with form data fields',
- formFields: {
- name: 'Financial Summary',
- placeholder: '{FinancialSummary}',
- aiHint: 'Analyze Q4 financial data and generate executive summary',
- fileMetadata: '{"selectedSheet":"Q4 Results","hasMultipleSheets":true}',
- richTextEnabled: 'true',
- file: '[Excel file binary data]'
- }
- },
- {
- name: 'Batch Generation',
- endpoint: 'POST /ai/generate-batch',
- description: 'Generate multiple variables from single file',
- formFields: {
- variables: JSON.stringify([
- {
- name: 'Executive Summary',
- placeholder: '{ExecutiveSummary}',
- aiHint: 'Create high-level executive summary'
- },
- {
- name: 'Key Metrics',
- placeholder: '{KeyMetrics}',
- aiHint: 'Extract important KPIs and metrics'
- }
- ]),
- fileMetadata: '{"contentType":"business-data"}',
- file: '[Data file binary data]'
- }
- },
- {
- name: 'Complete Workflow',
- endpoint: 'POST /ai/complete-workflow',
- description: 'AI generation with template integration',
- formFields: {
- variableName: 'Business Analysis',
- placeholder: '{BusinessAnalysis}',
- aiHint: 'Generate comprehensive business analysis with recommendations',
- templateId: 'template-123',
- fileMetadata: '{"selectedSheet":"Data"}',
- file: '[Business data file]'
- }
- }
- ],
- curlExamples: [
- {
- name: 'Basic Generation',
- curl: `curl -X POST http://localhost:3001/ai/generate-basic \\
- -H "Content-Type: application/json" \\
- -d '{
- "name": "Company Overview",
- "placeholder": "{CompanyOverview}",
- "aiHint": "Generate a professional company overview",
- "richTextEnabled": false
- }'`
- },
- {
- name: 'File Upload',
- curl: `curl -X POST http://localhost:3001/ai/generate-with-file \\
- -F "name=Financial Summary" \\
- -F "placeholder={FinancialSummary}" \\
- -F "aiHint=Analyze financial data" \\
- -F "richTextEnabled=true" \\
- -F "fileMetadata={\\"selectedSheet\\":\\"Q4 Results\\"}" \\
- -F "file=@financial-data.xlsx"`
- }
- ]
- });
-});
-
-// Error handler
-fastify.setErrorHandler((error, request, reply) => {
- fastify.log.error(error);
- reply.status(500).send({
- error: 'Internal server error',
- message: error.message
- });
-});
-
-// Start server
-const start = async () => {
- try {
- const port = process.env.PORT || 3001;
- const host = process.env.HOST || '0.0.0.0';
-
- await fastify.listen({ port, host });
-
- console.log('🤖 TurboDocx AI Variable Generation Service (Fastify) started');
- console.log(`📡 Server listening on http://${host}:${port}`);
- console.log('\nAvailable endpoints:');
- console.log(` POST http://${host}:${port}/ai/generate-basic`);
- console.log(` POST http://${host}:${port}/ai/generate-with-file`);
- console.log(` POST http://${host}:${port}/ai/generate-batch`);
- console.log(` POST http://${host}:${port}/ai/complete-workflow`);
- console.log(` GET http://${host}:${port}/health`);
- console.log(` GET http://${host}:${port}/ai/info`);
- console.log(` GET http://${host}:${port}/ai/examples`);
-
- } catch (err) {
- fastify.log.error(err);
- process.exit(1);
- }
-};
-
-// Check if this file is being run directly
-if (require.main === module) {
- start();
+async function generateAIVariable() {
+ const payload = {
+ name: 'Company Performance Summary',
+ placeholder: '{Q4Performance}',
+ aiHint: 'Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements',
+ richTextEnabled: true
+ };
+
+ const response = await fetch(`${BASE_URL}/ai/generate/variable/one`, {
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${API_TOKEN}`,
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(payload)
+ });
+
+ if (!response.ok) {
+ throw new Error(`AI generation failed: ${response.status}`);
+ }
+
+ const result = await response.json();
+ console.log('Generated variable:', result.data);
+ return result;
}
-module.exports = fastify;
\ No newline at end of file
+// Run the example
+generateAIVariable().catch(console.error);
\ No newline at end of file
diff --git a/static/scripts/ai/variable-generation/php.php b/static/scripts/ai/variable-generation/php.php
new file mode 100644
index 0000000..b06096d
--- /dev/null
+++ b/static/scripts/ai/variable-generation/php.php
@@ -0,0 +1,69 @@
+ 'Company Performance Summary',
+ 'placeholder' => '{Q4Performance}',
+ 'aiHint' => 'Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements',
+ 'richTextEnabled' => true
+ );
+
+ $jsonPayload = json_encode($payload);
+
+ // Set up headers
+ $headers = array(
+ 'Authorization: Bearer ' . $API_TOKEN,
+ 'x-rapiddocx-org-id: ' . $ORG_ID,
+ 'Content-Type: application/json',
+ 'Content-Length: ' . strlen($jsonPayload)
+ );
+
+ // Initialize cURL
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonPayload);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+
+ $response = curl_exec($ch);
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+
+ if (curl_error($ch)) {
+ throw new Exception("cURL error: " . curl_error($ch));
+ }
+
+ curl_close($ch);
+
+ if ($httpCode !== 200) {
+ throw new Exception("AI generation failed: HTTP " . $httpCode);
+ }
+
+ $result = json_decode($response, true);
+
+ if (json_last_error() !== JSON_ERROR_NONE) {
+ throw new Exception("JSON decode error: " . json_last_error_msg());
+ }
+
+ echo "Generated variable: " . json_encode($result['data']) . "\n";
+ return $result;
+}
+
+// Run the example
+try {
+ generateAIVariable();
+} catch (Exception $e) {
+ echo "Error: " . $e->getMessage() . "\n";
+}
+
+?>
\ No newline at end of file
diff --git a/static/scripts/ai/variable-generation/powershell.ps1 b/static/scripts/ai/variable-generation/powershell.ps1
new file mode 100644
index 0000000..fddd2c5
--- /dev/null
+++ b/static/scripts/ai/variable-generation/powershell.ps1
@@ -0,0 +1,36 @@
+# Configuration
+$API_TOKEN = "YOUR_API_TOKEN"
+$ORG_ID = "YOUR_ORGANIZATION_ID"
+$BASE_URL = "https://api.turbodocx.com"
+
+function Generate-AIVariable {
+ $uri = "$BASE_URL/ai/generate/variable/one"
+
+ # Create payload
+ $payload = @{
+ name = "Company Performance Summary"
+ placeholder = "{Q4Performance}"
+ aiHint = "Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements"
+ richTextEnabled = $true
+ } | ConvertTo-Json
+
+ # Create headers
+ $headers = @{
+ 'Authorization' = "Bearer $API_TOKEN"
+ 'x-rapiddocx-org-id' = $ORG_ID
+ 'Content-Type' = "application/json"
+ }
+
+ # Send request
+ try {
+ $response = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $payload
+ Write-Host "Generated variable: $($response.data)"
+ return $response
+ }
+ catch {
+ Write-Error "AI generation failed: $($_.Exception.Message)"
+ }
+}
+
+# Run the example
+Generate-AIVariable
\ No newline at end of file
diff --git a/static/scripts/ai/variable-generation/python/fastapi.py b/static/scripts/ai/variable-generation/python/fastapi.py
new file mode 100644
index 0000000..da53eea
--- /dev/null
+++ b/static/scripts/ai/variable-generation/python/fastapi.py
@@ -0,0 +1,39 @@
+import requests
+import json
+
+# Configuration
+API_TOKEN = "YOUR_API_TOKEN"
+ORG_ID = "YOUR_ORGANIZATION_ID"
+BASE_URL = "https://api.turbodocx.com"
+
+def generate_ai_variable():
+ url = f"{BASE_URL}/ai/generate/variable/one"
+
+ headers = {
+ 'Authorization': f'Bearer {API_TOKEN}',
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'Content-Type': 'application/json'
+ }
+
+ payload = {
+ 'name': 'Company Performance Summary',
+ 'placeholder': '{Q4Performance}',
+ 'aiHint': 'Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements',
+ 'richTextEnabled': True
+ }
+
+ response = requests.post(url, headers=headers, json=payload)
+
+ if not response.ok:
+ raise Exception(f"AI generation failed: {response.status_code}")
+
+ result = response.json()
+ print(f"Generated variable: {result['data']}")
+ return result
+
+# Run the example
+if __name__ == "__main__":
+ try:
+ generate_ai_variable()
+ except Exception as e:
+ print(f"Error: {e}")
\ No newline at end of file
diff --git a/static/scripts/ai/variable-generation/python/flask.py b/static/scripts/ai/variable-generation/python/flask.py
index a5574ea..da53eea 100644
--- a/static/scripts/ai/variable-generation/python/flask.py
+++ b/static/scripts/ai/variable-generation/python/flask.py
@@ -1,546 +1,39 @@
-#!/usr/bin/env python3
-
-import os
import requests
import json
-import uuid
-from flask import Flask, request, jsonify
-from werkzeug.utils import secure_filename
-from pathlib import Path
-# Configuration - Update these values
+# Configuration
API_TOKEN = "YOUR_API_TOKEN"
ORG_ID = "YOUR_ORGANIZATION_ID"
BASE_URL = "https://api.turbodocx.com"
-app = Flask(__name__)
-app.config['MAX_CONTENT_LENGTH'] = 25 * 1024 * 1024 # 25MB max file size
-
-class AIVariableService:
- """AI-Powered Variable Generation Service"""
-
- def __init__(self, api_token: str, org_id: str, base_url: str = BASE_URL):
- self.api_token = api_token
- self.org_id = org_id
- self.base_url = base_url
-
- def generate_variable(self, **kwargs):
- """Generate AI-powered variable content with optional file attachment"""
-
- file_path = kwargs.get('file_path')
- file_metadata = kwargs.get('file_metadata', {})
- name = kwargs.get('name')
- placeholder = kwargs.get('placeholder')
- template_id = kwargs.get('template_id')
- ai_hint = kwargs.get('ai_hint')
- rich_text_enabled = kwargs.get('rich_text_enabled', False)
-
- url = f"{self.base_url}/ai/generate/variable/one"
-
- # Prepare headers
- headers = {
- 'Authorization': f'Bearer {self.api_token}',
- 'x-rapiddocx-org-id': self.org_id,
- 'User-Agent': 'TurboDocx AI Client (Flask)'
- }
-
- # Prepare form data
- data = {
- 'name': name,
- 'placeholder': placeholder,
- 'aiHint': ai_hint,
- 'richTextEnabled': str(rich_text_enabled).lower()
- }
-
- if template_id:
- data['templateId'] = template_id
-
- files = {}
-
- # Handle file attachment
- if file_path and os.path.exists(file_path):
- file_uuid = str(uuid.uuid4())
- file_path_obj = Path(file_path)
-
- # Open file for upload
- files[f'FileResource-{file_uuid}'] = (
- file_path_obj.name,
- open(file_path_obj, 'rb'),
- self._get_content_type(file_path_obj)
- )
-
- # Prepare file metadata
- default_metadata = {
- file_uuid: {
- 'contentType': 'document',
- 'hasMultipleSheets': False
- }
- }
-
- default_metadata[file_uuid].update(file_metadata)
- data['fileResourceMetadata'] = json.dumps(default_metadata)
-
- try:
- print(f"Generating AI variable: {name}")
- print(f"AI Hint: {ai_hint[:100]}...")
-
- response = requests.post(url, headers=headers, data=data, files=files)
- response.raise_for_status()
-
- result = response.json()
-
- print("✅ AI Variable generated successfully!")
- print(f"Content Type: {result['data']['mimeType']}")
- print(f"Generated Content: {result['data']['text'][:100]}...")
-
- return result
-
- except requests.exceptions.RequestException as e:
- error_msg = f"AI Variable generation failed: {str(e)}"
- if hasattr(e, 'response') and e.response is not None:
- try:
- error_data = e.response.json()
- error_msg += f" - {error_data}"
- except:
- error_msg += f" - {e.response.text}"
- print(f"❌ {error_msg}")
- raise
-
- finally:
- # Close file handles
- for file_handle in files.values():
- if hasattr(file_handle[1], 'close'):
- file_handle[1].close()
-
- def _get_content_type(self, file_path: Path) -> str:
- """Get appropriate content type based on file extension"""
- extension = file_path.suffix.lower()
- content_types = {
- '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- '.xls': 'application/vnd.ms-excel',
- '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- '.doc': 'application/msword',
- '.pdf': 'application/pdf',
- '.csv': 'text/csv',
- '.txt': 'text/plain',
- '.png': 'image/png',
- '.jpg': 'image/jpeg',
- '.jpeg': 'image/jpeg'
- }
- return content_types.get(extension, 'application/octet-stream')
-
-# Initialize service
-ai_service = AIVariableService(API_TOKEN, ORG_ID)
-
-# Routes
-
-@app.route('/ai/generate-basic', methods=['POST'])
-def generate_basic():
- """Generate AI variable without file attachment"""
- try:
- data = request.get_json()
-
- if not data:
- return jsonify({'error': 'JSON payload required'}), 400
-
- required_fields = ['name', 'placeholder', 'aiHint']
- missing_fields = [field for field in required_fields if not data.get(field)]
-
- if missing_fields:
- return jsonify({
- 'error': f'Missing required fields: {", ".join(missing_fields)}'
- }), 400
-
- result = ai_service.generate_variable(
- name=data['name'],
- placeholder=data['placeholder'],
- ai_hint=data['aiHint'],
- template_id=data.get('templateId'),
- rich_text_enabled=data.get('richTextEnabled', False)
- )
-
- return jsonify({
- 'success': True,
- 'message': 'AI variable generated successfully',
- 'data': result
- })
-
- except Exception as e:
- app.logger.error(f'Error in basic generation: {str(e)}')
- return jsonify({
- 'error': 'AI variable generation failed',
- 'message': str(e)
- }), 500
-
-@app.route('/ai/generate-with-file', methods=['POST'])
-def generate_with_file():
- """Generate AI variable with file attachment"""
- try:
- # Check for required form fields
- required_fields = ['name', 'placeholder', 'aiHint']
- missing_fields = [field for field in required_fields if not request.form.get(field)]
-
- if missing_fields:
- return jsonify({
- 'error': f'Missing required fields: {", ".join(missing_fields)}'
- }), 400
-
- # Handle file upload
- file_path = None
- if 'file' in request.files:
- file = request.files['file']
- if file.filename:
- filename = secure_filename(file.filename)
- file_path = os.path.join('/tmp', filename)
- file.save(file_path)
-
- # Parse file metadata
- file_metadata = {}
- if request.form.get('fileMetadata'):
- try:
- file_metadata = json.loads(request.form.get('fileMetadata'))
- except json.JSONDecodeError:
- app.logger.warning('Invalid file metadata JSON, using defaults')
-
- result = ai_service.generate_variable(
- file_path=file_path,
- file_metadata=file_metadata,
- name=request.form['name'],
- placeholder=request.form['placeholder'],
- ai_hint=request.form['aiHint'],
- template_id=request.form.get('templateId'),
- rich_text_enabled=request.form.get('richTextEnabled', 'false').lower() == 'true'
- )
+def generate_ai_variable():
+ url = f"{BASE_URL}/ai/generate/variable/one"
- # Clean up uploaded file
- if file_path and os.path.exists(file_path):
- os.remove(file_path)
+ headers = {
+ 'Authorization': f'Bearer {API_TOKEN}',
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'Content-Type': 'application/json'
+ }
- return jsonify({
- 'success': True,
- 'message': 'AI variable generated successfully with file',
- 'data': result
- })
+ payload = {
+ 'name': 'Company Performance Summary',
+ 'placeholder': '{Q4Performance}',
+ 'aiHint': 'Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements',
+ 'richTextEnabled': True
+ }
- except Exception as e:
- # Clean up on error
- if 'file_path' in locals() and file_path and os.path.exists(file_path):
- os.remove(file_path)
-
- app.logger.error(f'Error in file-based generation: {str(e)}')
- return jsonify({
- 'error': 'AI variable generation with file failed',
- 'message': str(e)
- }), 500
-
-@app.route('/ai/generate-batch', methods=['POST'])
-def generate_batch():
- """Batch generate multiple AI variables"""
- try:
- # Parse variables from form or JSON
- if request.content_type and 'application/json' in request.content_type:
- data = request.get_json()
- variables = data.get('variables', [])
- file_path = None
- else:
- variables_json = request.form.get('variables')
- if not variables_json:
- return jsonify({'error': 'Missing variables field'}), 400
+ response = requests.post(url, headers=headers, json=payload)
- try:
- variables = json.loads(variables_json)
- except json.JSONDecodeError:
- return jsonify({'error': 'Invalid variables JSON format'}), 400
-
- # Handle file upload
- file_path = None
- if 'file' in request.files:
- file = request.files['file']
- if file.filename:
- filename = secure_filename(file.filename)
- file_path = os.path.join('/tmp', filename)
- file.save(file_path)
-
- if not isinstance(variables, list):
- return jsonify({'error': 'Variables must be an array'}), 400
-
- # Parse file metadata
- file_metadata = {}
- metadata_str = request.form.get('fileMetadata') if request.form else None
- if metadata_str:
- try:
- file_metadata = json.loads(metadata_str)
- except json.JSONDecodeError:
- app.logger.warning('Invalid file metadata JSON, using defaults')
-
- results = []
- for variable in variables:
- try:
- result = ai_service.generate_variable(
- file_path=file_path,
- file_metadata=file_metadata,
- name=variable.get('name'),
- placeholder=variable.get('placeholder'),
- ai_hint=variable.get('aiHint'),
- template_id=variable.get('templateId'),
- rich_text_enabled=variable.get('richTextEnabled', False)
- )
- results.append({
- 'success': True,
- 'variable': variable.get('name'),
- 'data': result
- })
- except Exception as e:
- results.append({
- 'success': False,
- 'variable': variable.get('name'),
- 'error': str(e)
- })
-
- # Clean up uploaded file
- if file_path and os.path.exists(file_path):
- os.remove(file_path)
-
- return jsonify({
- 'success': True,
- 'message': 'Batch AI variable generation completed',
- 'results': results
- })
-
- except Exception as e:
- # Clean up on error
- if 'file_path' in locals() and file_path and os.path.exists(file_path):
- os.remove(file_path)
+ if not response.ok:
+ raise Exception(f"AI generation failed: {response.status_code}")
- app.logger.error(f'Error in batch generation: {str(e)}')
- return jsonify({
- 'error': 'Batch AI variable generation failed',
- 'message': str(e)
- }), 500
+ result = response.json()
+ print(f"Generated variable: {result['data']}")
+ return result
-@app.route('/ai/complete-workflow', methods=['POST'])
-def complete_workflow():
- """Complete AI generation and template integration workflow"""
+# Run the example
+if __name__ == "__main__":
try:
- # Check for required form fields
- required_fields = ['variableName', 'placeholder', 'aiHint']
- missing_fields = [field for field in required_fields if not request.form.get(field)]
-
- if missing_fields:
- return jsonify({
- 'error': f'Missing required fields: {", ".join(missing_fields)}'
- }), 400
-
- # Handle file upload
- file_path = None
- if 'file' in request.files:
- file = request.files['file']
- if file.filename:
- filename = secure_filename(file.filename)
- file_path = os.path.join('/tmp', filename)
- file.save(file_path)
-
- # Parse file metadata
- file_metadata = {}
- if request.form.get('fileMetadata'):
- try:
- file_metadata = json.loads(request.form.get('fileMetadata'))
- except json.JSONDecodeError:
- app.logger.warning('Invalid file metadata JSON, using defaults')
-
- # Step 1: Generate AI content
- ai_result = ai_service.generate_variable(
- file_path=file_path,
- file_metadata=file_metadata,
- name=request.form['variableName'],
- placeholder=request.form['placeholder'],
- ai_hint=request.form['aiHint'],
- template_id=request.form.get('templateId'),
- rich_text_enabled=True
- )
-
- # Step 2: Prepare template variables
- template_variables = [{
- 'name': request.form['variableName'],
- 'placeholder': request.form['placeholder'],
- 'text': ai_result['data']['text'],
- 'mimeType': ai_result['data']['mimeType'],
- 'allowRichTextInjection': 1 if ai_result['data']['mimeType'] == 'html' else 0
- }]
-
- # Clean up uploaded file
- if file_path and os.path.exists(file_path):
- os.remove(file_path)
-
- return jsonify({
- 'success': True,
- 'message': 'Complete AI workflow executed successfully',
- 'data': {
- 'aiContent': ai_result,
- 'templateVariables': template_variables,
- 'summary': {
- 'variableName': request.form['variableName'],
- 'contentType': ai_result['data']['mimeType'],
- 'contentLength': len(ai_result['data']['text'])
- }
- }
- })
-
+ generate_ai_variable()
except Exception as e:
- # Clean up on error
- if 'file_path' in locals() and file_path and os.path.exists(file_path):
- os.remove(file_path)
-
- app.logger.error(f'Error in complete workflow: {str(e)}')
- return jsonify({
- 'error': 'Complete AI workflow failed',
- 'message': str(e)
- }), 500
-
-@app.route('/health', methods=['GET'])
-def health_check():
- """Health check endpoint"""
- return jsonify({
- 'status': 'healthy',
- 'service': 'ai-variable-generation-flask',
- 'timestamp': app.logger.handlers[0].formatter.formatTime(None) if app.logger.handlers else None
- })
-
-@app.route('/ai/info', methods=['GET'])
-def service_info():
- """Service information endpoint"""
- return jsonify({
- 'service': 'TurboDocx AI Variable Generation Service (Flask)',
- 'endpoints': {
- 'POST /ai/generate-basic': 'Generate AI variable without file attachment',
- 'POST /ai/generate-with-file': 'Generate AI variable with file attachment',
- 'POST /ai/generate-batch': 'Batch generate multiple AI variables',
- 'POST /ai/complete-workflow': 'Complete AI generation and template integration',
- 'GET /health': 'Service health check',
- 'GET /ai/info': 'Service information',
- 'GET /ai/examples': 'Usage examples'
- },
- 'configuration': {
- 'baseUrl': BASE_URL,
- 'hasToken': bool(API_TOKEN and API_TOKEN != 'YOUR_API_TOKEN'),
- 'hasOrgId': bool(ORG_ID and ORG_ID != 'YOUR_ORGANIZATION_ID'),
- 'maxFileSize': '25MB'
- },
- 'supportedFileTypes': [
- 'Excel (.xlsx, .xls)',
- 'Word (.docx, .doc)',
- 'PDF (.pdf)',
- 'CSV (.csv)',
- 'Text (.txt)',
- 'Images (.png, .jpg, .jpeg)'
- ]
- })
-
-@app.route('/ai/examples', methods=['GET'])
-def usage_examples():
- """Usage examples endpoint"""
- return jsonify({
- 'examples': [
- {
- 'name': 'Basic Generation',
- 'endpoint': 'POST /ai/generate-basic',
- 'contentType': 'application/json',
- 'payload': {
- 'name': 'Company Overview',
- 'placeholder': '{CompanyOverview}',
- 'aiHint': 'Generate a professional company overview for a technology consulting firm',
- 'richTextEnabled': False
- }
- },
- {
- 'name': 'Excel Analysis',
- 'endpoint': 'POST /ai/generate-with-file',
- 'contentType': 'multipart/form-data',
- 'formFields': {
- 'name': 'Financial Summary',
- 'placeholder': '{FinancialSummary}',
- 'aiHint': 'Analyze Q4 financial data and generate executive summary',
- 'fileMetadata': '{"selectedSheet":"Q4 Results","hasMultipleSheets":true}',
- 'richTextEnabled': 'true',
- 'file': '[Excel file upload]'
- }
- },
- {
- 'name': 'Batch Generation',
- 'endpoint': 'POST /ai/generate-batch',
- 'contentType': 'multipart/form-data',
- 'formFields': {
- 'variables': json.dumps([
- {
- 'name': 'Executive Summary',
- 'placeholder': '{ExecutiveSummary}',
- 'aiHint': 'Create high-level executive summary'
- },
- {
- 'name': 'Key Metrics',
- 'placeholder': '{KeyMetrics}',
- 'aiHint': 'Extract important KPIs and metrics'
- }
- ]),
- 'fileMetadata': '{"contentType":"business-data"}',
- 'file': '[Data file upload]'
- }
- }
- ],
- 'curlExamples': [
- {
- 'name': 'Basic Generation',
- 'curl': '''curl -X POST http://localhost:5001/ai/generate-basic \\
- -H "Content-Type: application/json" \\
- -d '{
- "name": "Company Overview",
- "placeholder": "{CompanyOverview}",
- "aiHint": "Generate a professional company overview",
- "richTextEnabled": false
- }\'
-'''
- },
- {
- 'name': 'File Upload',
- 'curl': '''curl -X POST http://localhost:5001/ai/generate-with-file \\
- -F "name=Financial Summary" \\
- -F "placeholder={FinancialSummary}" \\
- -F "aiHint=Analyze financial data and create summary" \\
- -F "richTextEnabled=true" \\
- -F "fileMetadata={\\"selectedSheet\\":\\"Q4 Results\\"}" \\
- -F "file=@financial-data.xlsx"'''
- }
- ]
- })
-
-# Error handlers
-@app.errorhandler(413)
-def file_too_large(e):
- return jsonify({
- 'error': 'File too large',
- 'message': 'Maximum file size is 25MB'
- }), 413
-
-@app.errorhandler(500)
-def internal_error(e):
- return jsonify({
- 'error': 'Internal server error',
- 'message': str(e)
- }), 500
-
-if __name__ == '__main__':
- port = int(os.environ.get('PORT', 5001))
- host = os.environ.get('HOST', '0.0.0.0')
-
- print('🤖 TurboDocx AI Variable Generation Service (Flask) started')
- print(f'📡 Server listening on http://{host}:{port}')
- print('\nAvailable endpoints:')
- print(f' POST http://{host}:{port}/ai/generate-basic')
- print(f' POST http://{host}:{port}/ai/generate-with-file')
- print(f' POST http://{host}:{port}/ai/generate-batch')
- print(f' POST http://{host}:{port}/ai/complete-workflow')
- print(f' GET http://{host}:{port}/health')
- print(f' GET http://{host}:{port}/ai/info')
- print(f' GET http://{host}:{port}/ai/examples')
-
- app.run(host=host, port=port, debug=False)
\ No newline at end of file
+ print(f"Error: {e}")
\ No newline at end of file
diff --git a/static/scripts/ai/variable-generation/python/requests.py b/static/scripts/ai/variable-generation/python/requests.py
index 94d3246..28b3a7b 100644
--- a/static/scripts/ai/variable-generation/python/requests.py
+++ b/static/scripts/ai/variable-generation/python/requests.py
@@ -64,9 +64,6 @@ def generate_variable(
'richTextEnabled': str(rich_text_enabled).lower()
}
- if template_id:
- data['templateId'] = template_id
-
files = {}
# Handle file attachment
@@ -184,7 +181,6 @@ def example2_excel_analysis(file_path: str):
'dataRange': 'A1:F50',
'contentType': 'financial-data'
},
- template_id='quarterly-report-template-123',
rich_text_enabled=True
)
@@ -209,7 +205,6 @@ def example3_document_analysis(file_path: str):
file_metadata={
'contentType': 'project-document'
},
- template_id='project-proposal-template-456',
rich_text_enabled=True
)
@@ -254,7 +249,6 @@ def example5_rich_text_generation():
name='Marketing Campaign Summary',
placeholder='{CampaignSummary}',
ai_hint='Create a comprehensive marketing campaign summary with structured sections: Executive Overview, Key Metrics (with specific numbers), Strategic Insights, and Action Items. Format with appropriate headings and bullet points.',
- template_id='marketing-report-template-789',
rich_text_enabled=True
)
diff --git a/static/scripts/ai/variable-generation/ruby.rb b/static/scripts/ai/variable-generation/ruby.rb
new file mode 100644
index 0000000..dc4b3bc
--- /dev/null
+++ b/static/scripts/ai/variable-generation/ruby.rb
@@ -0,0 +1,48 @@
+require 'net/http'
+require 'uri'
+require 'json'
+
+# Configuration
+API_TOKEN = "YOUR_API_TOKEN"
+ORG_ID = "YOUR_ORGANIZATION_ID"
+BASE_URL = "https://api.turbodocx.com"
+
+def generate_ai_variable
+ uri = URI("#{BASE_URL}/ai/generate/variable/one")
+
+ payload = {
+ 'name' => 'Company Performance Summary',
+ 'placeholder' => '{Q4Performance}',
+ 'aiHint' => 'Generate a professional executive summary of Q4 financial performance highlighting revenue growth, profit margins, and key achievements',
+ 'richTextEnabled' => true
+ }
+
+ # Create HTTP connection
+ http = Net::HTTP.new(uri.host, uri.port)
+ http.use_ssl = true
+
+ # Create request
+ request = Net::HTTP::Post.new(uri)
+ request['Authorization'] = "Bearer #{API_TOKEN}"
+ request['x-rapiddocx-org-id'] = ORG_ID
+ request['Content-Type'] = 'application/json'
+ request.body = payload.to_json
+
+ # Send request
+ response = http.request(request)
+
+ unless response.code == '200'
+ raise "AI generation failed: #{response.code}"
+ end
+
+ result = JSON.parse(response.body)
+ puts "Generated variable: #{result['data']}"
+ result
+end
+
+# Run the example
+begin
+ generate_ai_variable
+rescue => e
+ puts "Error: #{e.message}"
+end
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/csharp/controller.cs b/static/scripts/templates/api/complete-workflows/csharp/controller.cs
index 43846db..a01d7dc 100644
--- a/static/scripts/templates/api/complete-workflows/csharp/controller.cs
+++ b/static/scripts/templates/api/complete-workflows/csharp/controller.cs
@@ -4,11 +4,10 @@
using System.Threading.Tasks;
using System.Text.Json;
using System.Text;
-using System.Web;
/**
- * Complete Template Generation Workflows
- * Demonstrates both Path A (Upload) and Path B (Browse/Select) followed by generation
+ * Complete Workflow: Upload → Generate → Download
+ * Simple 3-step process for document generation
*/
class TemplateWorkflowManager
{
@@ -33,18 +32,13 @@ static async Task Main(string[] args)
try
{
- // Demo Path B (Browse existing templates)
- await workflow.DemoPathB();
-
- // Uncomment to demo Path A (requires template file):
- // await workflow.DemoPathA("./path/to/your/template.docx");
-
- // Uncomment to run full comparison:
- // await workflow.DemoComparison();
+ // Replace with your template file path
+ string templatePath = "./template.docx";
+ await workflow.CompleteWorkflow(templatePath);
}
catch (Exception ex)
{
- Console.WriteLine($"Workflow demo failed: {ex.Message}");
+ Console.WriteLine($"❌ Workflow failed: {ex.Message}");
}
finally
{
@@ -52,58 +46,8 @@ static async Task Main(string[] args)
}
}
- // ===============================
- // PATH A: Upload New Template
- // ===============================
-
- /**
- * Complete Path A workflow: Upload → Generate
- */
- public async Task PathA_UploadAndGenerate(string templateFilePath, string deliverableName)
- {
- Console.WriteLine("🔄 PATH A: Upload New Template → Generate Deliverable");
- Console.WriteLine(new string('=', 48));
-
- try
- {
- // Step 1: Upload and create template
- Console.WriteLine("\n📤 Step 1: Uploading template...");
- var template = await UploadTemplate(templateFilePath);
-
- // Step 2: Generate deliverable using uploaded template
- Console.WriteLine("\n📝 Step 2: Generating deliverable...");
- using var templateDoc = JsonDocument.Parse(template);
- var templateInfo = templateDoc.RootElement.GetProperty("data").GetProperty("results").GetProperty("template");
-
- var deliverable = await GenerateDeliverable(
- templateInfo.GetProperty("id").GetString(),
- deliverableName,
- $"Generated from uploaded template: {templateInfo.GetProperty("name").GetString()}"
- );
-
- Console.WriteLine("\n✅ PATH A COMPLETE!");
- Console.WriteLine($"Template ID: {templateInfo.GetProperty("id").GetString()}");
-
- using var deliverableDoc = JsonDocument.Parse(deliverable);
- var deliverableInfo = deliverableDoc.RootElement.GetProperty("data").GetProperty("results").GetProperty("deliverable");
- Console.WriteLine($"Deliverable ID: {deliverableInfo.GetProperty("id").GetString()}");
-
- // Download the generated file
- await DownloadDeliverable(
- deliverableInfo.GetProperty("id").GetString(),
- $"{deliverableInfo.GetProperty("name").GetString()}.docx"
- );
-
- return new TemplateWorkflowResult(template, deliverable, null);
- }
- catch (Exception ex)
- {
- Console.WriteLine($"❌ Path A failed: {ex.Message}");
- throw;
- }
- }
-
- private async Task UploadTemplate(string templateFilePath)
+ // Step 1: Upload template file
+ public async Task UploadTemplate(string templateFilePath)
{
if (!File.Exists(templateFilePath))
{
@@ -113,249 +57,56 @@ private async Task UploadTemplate(string templateFilePath)
using var content = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(File.ReadAllBytes(templateFilePath));
- fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
- content.Add(fileContent, "templateFile", Path.GetFileName(templateFilePath));
+ fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
+ content.Add(fileContent, "templateFile", "template.docx");
- content.Add(new StringContent("API Upload Template"), "name");
- content.Add(new StringContent("Template uploaded via API for testing"), "description");
- content.Add(new StringContent("[]"), "variables");
- content.Add(new StringContent("[\"api\", \"test\", \"upload\"]"), "tags");
+ content.Add(new StringContent("Simple Template"), "name");
+ content.Add(new StringContent("Template uploaded for document generation"), "description");
var response = await client.PostAsync($"{BASE_URL}/template/upload-and-create", content);
if (!response.IsSuccessStatusCode)
{
- var errorContent = await response.Content.ReadAsStringAsync();
- throw new HttpRequestException($"Upload failed: {response.StatusCode} - {errorContent}");
+ throw new HttpRequestException($"Upload failed: {response.StatusCode}");
}
var result = await response.Content.ReadAsStringAsync();
-
using var document = JsonDocument.Parse(result);
var template = document.RootElement.GetProperty("data").GetProperty("results").GetProperty("template");
Console.WriteLine($"✅ Template uploaded: {template.GetProperty("name").GetString()} ({template.GetProperty("id").GetString()})");
- var variableCount = 0;
- if (template.TryGetProperty("variables", out var variables) && variables.ValueKind != JsonValueKind.Null)
- {
- variableCount = variables.GetArrayLength();
- }
- Console.WriteLine($"📊 Variables extracted: {variableCount}");
-
- Console.WriteLine($"🔤 Default font: {template.GetProperty("defaultFont").GetString()}");
-
- var fontCount = 0;
- if (template.TryGetProperty("fonts", out var fonts) && fonts.ValueKind != JsonValueKind.Null)
- {
- fontCount = fonts.GetArrayLength();
- }
- Console.WriteLine($"📝 Fonts used: {fontCount}");
-
- return result;
+ return template;
}
- // ===============================
- // PATH B: Browse and Select
- // ===============================
-
- /**
- * Complete Path B workflow: Browse → Select → Generate
- */
- public async Task PathB_BrowseAndGenerate(string searchQuery, string deliverableName)
- {
- Console.WriteLine("🔍 PATH B: Browse Existing Templates → Generate Deliverable");
- Console.WriteLine(new string('=', 56));
-
- try
- {
- // Step 1: Browse templates
- Console.WriteLine("\n🔍 Step 1: Browsing templates...");
- var browseResult = await BrowseTemplates(searchQuery);
-
- // Step 2: Select first available template
- using var browseDoc = JsonDocument.Parse(browseResult);
- var results = browseDoc.RootElement.GetProperty("data").GetProperty("results");
-
- JsonElement? selectedTemplate = null;
- foreach (var item in results.EnumerateArray())
- {
- if (item.GetProperty("type").GetString() == "template")
- {
- selectedTemplate = item;
- break;
- }
- }
-
- if (!selectedTemplate.HasValue)
- {
- throw new Exception("No templates found in browse results");
- }
-
- var template = selectedTemplate.Value;
- Console.WriteLine($"📋 Selected: {template.GetProperty("name").GetString()} ({template.GetProperty("id").GetString()})");
-
- // Step 3: Get template details
- Console.WriteLine("\n📖 Step 2: Getting template details...");
- var templateDetails = await GetTemplateDetails(template.GetProperty("id").GetString());
-
- // Step 4: Get PDF preview (optional)
- Console.WriteLine("\n🖼️ Step 3: Getting PDF preview...");
- var pdfPreview = await GetTemplatePDFPreview(template.GetProperty("id").GetString());
-
- // Step 5: Generate deliverable
- Console.WriteLine("\n📝 Step 4: Generating deliverable...");
- using var detailsDoc = JsonDocument.Parse(templateDetails);
- var templateInfo = detailsDoc.RootElement.GetProperty("data").GetProperty("results");
-
- var deliverable = await GenerateDeliverable(
- templateInfo.GetProperty("id").GetString(),
- deliverableName,
- $"Generated from existing template: {templateInfo.GetProperty("name").GetString()}"
- );
-
- Console.WriteLine("\n✅ PATH B COMPLETE!");
- Console.WriteLine($"Template ID: {templateInfo.GetProperty("id").GetString()}");
-
- using var deliverableDoc = JsonDocument.Parse(deliverable);
- var deliverableInfo = deliverableDoc.RootElement.GetProperty("data").GetProperty("results").GetProperty("deliverable");
- Console.WriteLine($"Deliverable ID: {deliverableInfo.GetProperty("id").GetString()}");
- Console.WriteLine($"PDF Preview: {pdfPreview}");
-
- // Download the generated file
- Console.WriteLine("\n📥 Step 5: Downloading file...");
- await DownloadDeliverable(
- deliverableInfo.GetProperty("id").GetString(),
- $"{deliverableInfo.GetProperty("name").GetString()}.docx"
- );
-
- return new TemplateWorkflowResult(templateDetails, deliverable, pdfPreview);
- }
- catch (Exception ex)
- {
- Console.WriteLine($"❌ Path B failed: {ex.Message}");
- throw;
- }
- }
-
- private async Task BrowseTemplates(string query)
- {
- var queryParams = "limit=25&offset=0&showTags=true";
-
- if (!string.IsNullOrEmpty(query))
- {
- queryParams += $"&query={HttpUtility.UrlEncode(query)}";
- }
-
- var response = await client.GetAsync($"{BASE_URL}/template-item?{queryParams}");
-
- if (!response.IsSuccessStatusCode)
- {
- var errorContent = await response.Content.ReadAsStringAsync();
- throw new HttpRequestException($"Browse failed: {response.StatusCode} - {errorContent}");
- }
-
- var result = await response.Content.ReadAsStringAsync();
-
- using var document = JsonDocument.Parse(result);
- var totalRecords = document.RootElement.GetProperty("data").GetProperty("totalRecords").GetInt32();
- Console.WriteLine($"🔍 Found {totalRecords} templates/folders");
-
- return result;
- }
-
- private async Task GetTemplateDetails(string templateId)
- {
- var response = await client.GetAsync($"{BASE_URL}/template/{templateId}");
-
- if (!response.IsSuccessStatusCode)
- {
- var errorContent = await response.Content.ReadAsStringAsync();
- throw new HttpRequestException($"Template details failed: {response.StatusCode} - {errorContent}");
- }
-
- var result = await response.Content.ReadAsStringAsync();
-
- using var document = JsonDocument.Parse(result);
- var template = document.RootElement.GetProperty("data").GetProperty("results");
-
- var variableCount = 0;
- if (template.TryGetProperty("variables", out var variables) && variables.ValueKind != JsonValueKind.Null)
- {
- variableCount = variables.GetArrayLength();
- }
- Console.WriteLine($"📊 Variables: {variableCount}");
-
- var defaultFont = template.TryGetProperty("defaultFont", out var font) ? font.GetString() : "N/A";
- Console.WriteLine($"🔤 Default font: {defaultFont}");
-
- return result;
- }
-
- private async Task GetTemplatePDFPreview(string templateId)
- {
- var response = await client.GetAsync($"{BASE_URL}/template/{templateId}/previewpdflink");
-
- if (!response.IsSuccessStatusCode)
- {
- var errorContent = await response.Content.ReadAsStringAsync();
- throw new HttpRequestException($"PDF preview failed: {response.StatusCode} - {errorContent}");
- }
-
- var result = await response.Content.ReadAsStringAsync();
-
- using var document = JsonDocument.Parse(result);
- var pdfUrl = document.RootElement.GetProperty("results").GetString();
-
- Console.WriteLine($"🖼️ PDF Preview available: {pdfUrl}");
-
- return pdfUrl;
- }
-
- // ===============================
- // COMMON: Generate Deliverable
- // ===============================
-
- private async Task GenerateDeliverable(string templateId, string name, string description)
+ // Step 2: Generate deliverable with simple variables
+ public async Task GenerateDeliverable(string templateId)
{
var payload = $$"""
{
"templateId": "{{templateId}}",
- "name": "{{name}}",
- "description": "{{description}}",
+ "name": "Generated Document",
+ "description": "Simple document example",
"variables": [
{
"mimeType": "text",
- "name": "Sample Variable",
- "placeholder": "{SampleVariable}",
- "text": "Sample Content from C# Workflow",
- "allowRichTextInjection": 0,
- "autogenerated": false,
- "count": 1,
- "order": 1,
- "subvariables": [],
- "metadata": {
- "generatedBy": "C# Workflow"
- },
- "aiPrompt": ""
+ "name": "Company Name",
+ "placeholder": "{CompanyName}",
+ "text": "Acme Corporation"
+ },
+ {
+ "mimeType": "text",
+ "name": "Employee Name",
+ "placeholder": "{EmployeeName}",
+ "text": "John Smith"
+ },
+ {
+ "mimeType": "text",
+ "name": "Date",
+ "placeholder": "{Date}",
+ "text": "January 15, 2024"
}
- ],
- "tags": ["api-generated"],
- "fonts": "[]",
- "defaultFont": "Arial",
- "replaceFonts": true,
- "metadata": {
- "sessions": [
- {
- "id": "{{Guid.NewGuid()}}",
- "starttime": "{{DateTime.UtcNow:yyyy-MM-ddTHH:mm:ss.fffZ}}",
- "endtime": "{{DateTime.UtcNow:yyyy-MM-ddTHH:mm:ss.fffZ}}"
- }
- ],
- "workflow": "C# Complete Workflow",
- "generated": "{{DateTime.UtcNow:yyyy-MM-ddTHH:mm:ss.fffZ}}"
- }
+ ]
}
""";
@@ -364,26 +115,21 @@ private async Task GenerateDeliverable(string templateId, string name, s
if (!response.IsSuccessStatusCode)
{
- var errorContent = await response.Content.ReadAsStringAsync();
- throw new HttpRequestException($"Deliverable generation failed: {response.StatusCode} - {errorContent}");
+ throw new HttpRequestException($"Generation failed: {response.StatusCode}");
}
var result = await response.Content.ReadAsStringAsync();
-
using var document = JsonDocument.Parse(result);
var deliverable = document.RootElement.GetProperty("data").GetProperty("results").GetProperty("deliverable");
- Console.WriteLine($"✅ Generated: {deliverable.GetProperty("name").GetString()}");
- Console.WriteLine($"📄 Created by: {deliverable.GetProperty("createdBy").GetString()}");
- Console.WriteLine($"📅 Created on: {deliverable.GetProperty("createdOn").GetString()}");
+ Console.WriteLine($"✅ Document generated: {deliverable.GetProperty("name").GetString()} ({deliverable.GetProperty("id").GetString()})");
- return result;
+ return deliverable;
}
- private async Task DownloadDeliverable(string deliverableId, string filename)
+ // Step 3: Download generated file
+ public async Task DownloadFile(string deliverableId, string filename)
{
- Console.WriteLine($"📥 Downloading file: {filename}");
-
var response = await client.GetAsync($"{BASE_URL}/deliverable/file/{deliverableId}");
if (!response.IsSuccessStatusCode)
@@ -393,76 +139,32 @@ private async Task DownloadDeliverable(string deliverableId, string filename)
Console.WriteLine($"✅ File ready for download: {filename}");
- var contentType = response.Content.Headers.ContentType?.ToString() ?? "N/A";
- var contentLength = response.Content.Headers.ContentLength?.ToString() ?? "N/A";
-
- Console.WriteLine($"📁 Content-Type: {contentType}");
- Console.WriteLine($"📊 Content-Length: {contentLength} bytes");
-
- // In a real application, you would save the file
+ // In a real application, you would save the file:
// var fileBytes = await response.Content.ReadAsByteArrayAsync();
// await File.WriteAllBytesAsync(filename, fileBytes);
}
- // ===============================
- // DEMO FUNCTIONS
- // ===============================
-
- public async Task DemoPathA(string templateFilePath)
- {
- Console.WriteLine("🚀 DEMO: Path A - Upload New Template Workflow");
- Console.WriteLine(new string('=', 45));
- Console.WriteLine();
-
- return await PathA_UploadAndGenerate(templateFilePath, "Contract Generated via Path A - API Upload");
- }
-
- public async Task DemoPathB()
+ // Complete workflow: Upload → Generate → Download
+ public async Task CompleteWorkflow(string templateFilePath)
{
- Console.WriteLine("🚀 DEMO: Path B - Browse Existing Template Workflow");
- Console.WriteLine(new string('=', 51));
- Console.WriteLine();
+ Console.WriteLine("🚀 Starting complete workflow...");
- return await PathB_BrowseAndGenerate("contract", "Contract Generated via Path B - Browse & Select");
- }
-
- public async Task DemoComparison()
- {
- Console.WriteLine("🚀 DEMO: Complete Workflow Comparison");
- Console.WriteLine(new string('=', 36));
- Console.WriteLine();
-
- try
- {
- Console.WriteLine("Testing both paths with the same template type...\n");
-
- // Run Path B first (browse existing)
- var pathBResult = await DemoPathB();
-
- Console.WriteLine("\n" + new string('=', 60) + "\n");
+ // Step 1: Upload template
+ Console.WriteLine("\n📤 Step 1: Uploading template...");
+ var template = await UploadTemplate(templateFilePath);
- // For Path A, we'd need a template file
- Console.WriteLine("📝 Path A requires a template file to upload.");
- Console.WriteLine(" Example: await workflow.DemoPathA(\"./contract-template.docx\")");
- }
- catch (Exception ex)
- {
- Console.WriteLine($"Demo comparison failed: {ex.Message}");
- }
- }
+ // Step 2: Generate deliverable
+ Console.WriteLine("\n📝 Step 2: Generating document...");
+ var deliverable = await GenerateDeliverable(template.GetProperty("id").GetString());
- // Result container class
- public class TemplateWorkflowResult
- {
- public string Template { get; }
- public string Deliverable { get; }
- public string PdfPreview { get; }
+ // Step 3: Download file
+ Console.WriteLine("\n📥 Step 3: Downloading file...");
+ string filename = deliverable.GetProperty("name").GetString() + ".docx";
+ await DownloadFile(deliverable.GetProperty("id").GetString(), filename);
- public TemplateWorkflowResult(string template, string deliverable, string pdfPreview)
- {
- Template = template;
- Deliverable = deliverable;
- PdfPreview = pdfPreview;
- }
+ Console.WriteLine("\n✅ Workflow complete!");
+ Console.WriteLine($"Template: {template.GetProperty("id").GetString()}");
+ Console.WriteLine($"Document: {deliverable.GetProperty("id").GetString()}");
+ Console.WriteLine($"File: {filename}");
}
}
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/csharp/minimal.cs b/static/scripts/templates/api/complete-workflows/csharp/minimal.cs
index 43846db..a01d7dc 100644
--- a/static/scripts/templates/api/complete-workflows/csharp/minimal.cs
+++ b/static/scripts/templates/api/complete-workflows/csharp/minimal.cs
@@ -4,11 +4,10 @@
using System.Threading.Tasks;
using System.Text.Json;
using System.Text;
-using System.Web;
/**
- * Complete Template Generation Workflows
- * Demonstrates both Path A (Upload) and Path B (Browse/Select) followed by generation
+ * Complete Workflow: Upload → Generate → Download
+ * Simple 3-step process for document generation
*/
class TemplateWorkflowManager
{
@@ -33,18 +32,13 @@ static async Task Main(string[] args)
try
{
- // Demo Path B (Browse existing templates)
- await workflow.DemoPathB();
-
- // Uncomment to demo Path A (requires template file):
- // await workflow.DemoPathA("./path/to/your/template.docx");
-
- // Uncomment to run full comparison:
- // await workflow.DemoComparison();
+ // Replace with your template file path
+ string templatePath = "./template.docx";
+ await workflow.CompleteWorkflow(templatePath);
}
catch (Exception ex)
{
- Console.WriteLine($"Workflow demo failed: {ex.Message}");
+ Console.WriteLine($"❌ Workflow failed: {ex.Message}");
}
finally
{
@@ -52,58 +46,8 @@ static async Task Main(string[] args)
}
}
- // ===============================
- // PATH A: Upload New Template
- // ===============================
-
- /**
- * Complete Path A workflow: Upload → Generate
- */
- public async Task PathA_UploadAndGenerate(string templateFilePath, string deliverableName)
- {
- Console.WriteLine("🔄 PATH A: Upload New Template → Generate Deliverable");
- Console.WriteLine(new string('=', 48));
-
- try
- {
- // Step 1: Upload and create template
- Console.WriteLine("\n📤 Step 1: Uploading template...");
- var template = await UploadTemplate(templateFilePath);
-
- // Step 2: Generate deliverable using uploaded template
- Console.WriteLine("\n📝 Step 2: Generating deliverable...");
- using var templateDoc = JsonDocument.Parse(template);
- var templateInfo = templateDoc.RootElement.GetProperty("data").GetProperty("results").GetProperty("template");
-
- var deliverable = await GenerateDeliverable(
- templateInfo.GetProperty("id").GetString(),
- deliverableName,
- $"Generated from uploaded template: {templateInfo.GetProperty("name").GetString()}"
- );
-
- Console.WriteLine("\n✅ PATH A COMPLETE!");
- Console.WriteLine($"Template ID: {templateInfo.GetProperty("id").GetString()}");
-
- using var deliverableDoc = JsonDocument.Parse(deliverable);
- var deliverableInfo = deliverableDoc.RootElement.GetProperty("data").GetProperty("results").GetProperty("deliverable");
- Console.WriteLine($"Deliverable ID: {deliverableInfo.GetProperty("id").GetString()}");
-
- // Download the generated file
- await DownloadDeliverable(
- deliverableInfo.GetProperty("id").GetString(),
- $"{deliverableInfo.GetProperty("name").GetString()}.docx"
- );
-
- return new TemplateWorkflowResult(template, deliverable, null);
- }
- catch (Exception ex)
- {
- Console.WriteLine($"❌ Path A failed: {ex.Message}");
- throw;
- }
- }
-
- private async Task UploadTemplate(string templateFilePath)
+ // Step 1: Upload template file
+ public async Task UploadTemplate(string templateFilePath)
{
if (!File.Exists(templateFilePath))
{
@@ -113,249 +57,56 @@ private async Task UploadTemplate(string templateFilePath)
using var content = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(File.ReadAllBytes(templateFilePath));
- fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
- content.Add(fileContent, "templateFile", Path.GetFileName(templateFilePath));
+ fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
+ content.Add(fileContent, "templateFile", "template.docx");
- content.Add(new StringContent("API Upload Template"), "name");
- content.Add(new StringContent("Template uploaded via API for testing"), "description");
- content.Add(new StringContent("[]"), "variables");
- content.Add(new StringContent("[\"api\", \"test\", \"upload\"]"), "tags");
+ content.Add(new StringContent("Simple Template"), "name");
+ content.Add(new StringContent("Template uploaded for document generation"), "description");
var response = await client.PostAsync($"{BASE_URL}/template/upload-and-create", content);
if (!response.IsSuccessStatusCode)
{
- var errorContent = await response.Content.ReadAsStringAsync();
- throw new HttpRequestException($"Upload failed: {response.StatusCode} - {errorContent}");
+ throw new HttpRequestException($"Upload failed: {response.StatusCode}");
}
var result = await response.Content.ReadAsStringAsync();
-
using var document = JsonDocument.Parse(result);
var template = document.RootElement.GetProperty("data").GetProperty("results").GetProperty("template");
Console.WriteLine($"✅ Template uploaded: {template.GetProperty("name").GetString()} ({template.GetProperty("id").GetString()})");
- var variableCount = 0;
- if (template.TryGetProperty("variables", out var variables) && variables.ValueKind != JsonValueKind.Null)
- {
- variableCount = variables.GetArrayLength();
- }
- Console.WriteLine($"📊 Variables extracted: {variableCount}");
-
- Console.WriteLine($"🔤 Default font: {template.GetProperty("defaultFont").GetString()}");
-
- var fontCount = 0;
- if (template.TryGetProperty("fonts", out var fonts) && fonts.ValueKind != JsonValueKind.Null)
- {
- fontCount = fonts.GetArrayLength();
- }
- Console.WriteLine($"📝 Fonts used: {fontCount}");
-
- return result;
+ return template;
}
- // ===============================
- // PATH B: Browse and Select
- // ===============================
-
- /**
- * Complete Path B workflow: Browse → Select → Generate
- */
- public async Task PathB_BrowseAndGenerate(string searchQuery, string deliverableName)
- {
- Console.WriteLine("🔍 PATH B: Browse Existing Templates → Generate Deliverable");
- Console.WriteLine(new string('=', 56));
-
- try
- {
- // Step 1: Browse templates
- Console.WriteLine("\n🔍 Step 1: Browsing templates...");
- var browseResult = await BrowseTemplates(searchQuery);
-
- // Step 2: Select first available template
- using var browseDoc = JsonDocument.Parse(browseResult);
- var results = browseDoc.RootElement.GetProperty("data").GetProperty("results");
-
- JsonElement? selectedTemplate = null;
- foreach (var item in results.EnumerateArray())
- {
- if (item.GetProperty("type").GetString() == "template")
- {
- selectedTemplate = item;
- break;
- }
- }
-
- if (!selectedTemplate.HasValue)
- {
- throw new Exception("No templates found in browse results");
- }
-
- var template = selectedTemplate.Value;
- Console.WriteLine($"📋 Selected: {template.GetProperty("name").GetString()} ({template.GetProperty("id").GetString()})");
-
- // Step 3: Get template details
- Console.WriteLine("\n📖 Step 2: Getting template details...");
- var templateDetails = await GetTemplateDetails(template.GetProperty("id").GetString());
-
- // Step 4: Get PDF preview (optional)
- Console.WriteLine("\n🖼️ Step 3: Getting PDF preview...");
- var pdfPreview = await GetTemplatePDFPreview(template.GetProperty("id").GetString());
-
- // Step 5: Generate deliverable
- Console.WriteLine("\n📝 Step 4: Generating deliverable...");
- using var detailsDoc = JsonDocument.Parse(templateDetails);
- var templateInfo = detailsDoc.RootElement.GetProperty("data").GetProperty("results");
-
- var deliverable = await GenerateDeliverable(
- templateInfo.GetProperty("id").GetString(),
- deliverableName,
- $"Generated from existing template: {templateInfo.GetProperty("name").GetString()}"
- );
-
- Console.WriteLine("\n✅ PATH B COMPLETE!");
- Console.WriteLine($"Template ID: {templateInfo.GetProperty("id").GetString()}");
-
- using var deliverableDoc = JsonDocument.Parse(deliverable);
- var deliverableInfo = deliverableDoc.RootElement.GetProperty("data").GetProperty("results").GetProperty("deliverable");
- Console.WriteLine($"Deliverable ID: {deliverableInfo.GetProperty("id").GetString()}");
- Console.WriteLine($"PDF Preview: {pdfPreview}");
-
- // Download the generated file
- Console.WriteLine("\n📥 Step 5: Downloading file...");
- await DownloadDeliverable(
- deliverableInfo.GetProperty("id").GetString(),
- $"{deliverableInfo.GetProperty("name").GetString()}.docx"
- );
-
- return new TemplateWorkflowResult(templateDetails, deliverable, pdfPreview);
- }
- catch (Exception ex)
- {
- Console.WriteLine($"❌ Path B failed: {ex.Message}");
- throw;
- }
- }
-
- private async Task BrowseTemplates(string query)
- {
- var queryParams = "limit=25&offset=0&showTags=true";
-
- if (!string.IsNullOrEmpty(query))
- {
- queryParams += $"&query={HttpUtility.UrlEncode(query)}";
- }
-
- var response = await client.GetAsync($"{BASE_URL}/template-item?{queryParams}");
-
- if (!response.IsSuccessStatusCode)
- {
- var errorContent = await response.Content.ReadAsStringAsync();
- throw new HttpRequestException($"Browse failed: {response.StatusCode} - {errorContent}");
- }
-
- var result = await response.Content.ReadAsStringAsync();
-
- using var document = JsonDocument.Parse(result);
- var totalRecords = document.RootElement.GetProperty("data").GetProperty("totalRecords").GetInt32();
- Console.WriteLine($"🔍 Found {totalRecords} templates/folders");
-
- return result;
- }
-
- private async Task GetTemplateDetails(string templateId)
- {
- var response = await client.GetAsync($"{BASE_URL}/template/{templateId}");
-
- if (!response.IsSuccessStatusCode)
- {
- var errorContent = await response.Content.ReadAsStringAsync();
- throw new HttpRequestException($"Template details failed: {response.StatusCode} - {errorContent}");
- }
-
- var result = await response.Content.ReadAsStringAsync();
-
- using var document = JsonDocument.Parse(result);
- var template = document.RootElement.GetProperty("data").GetProperty("results");
-
- var variableCount = 0;
- if (template.TryGetProperty("variables", out var variables) && variables.ValueKind != JsonValueKind.Null)
- {
- variableCount = variables.GetArrayLength();
- }
- Console.WriteLine($"📊 Variables: {variableCount}");
-
- var defaultFont = template.TryGetProperty("defaultFont", out var font) ? font.GetString() : "N/A";
- Console.WriteLine($"🔤 Default font: {defaultFont}");
-
- return result;
- }
-
- private async Task GetTemplatePDFPreview(string templateId)
- {
- var response = await client.GetAsync($"{BASE_URL}/template/{templateId}/previewpdflink");
-
- if (!response.IsSuccessStatusCode)
- {
- var errorContent = await response.Content.ReadAsStringAsync();
- throw new HttpRequestException($"PDF preview failed: {response.StatusCode} - {errorContent}");
- }
-
- var result = await response.Content.ReadAsStringAsync();
-
- using var document = JsonDocument.Parse(result);
- var pdfUrl = document.RootElement.GetProperty("results").GetString();
-
- Console.WriteLine($"🖼️ PDF Preview available: {pdfUrl}");
-
- return pdfUrl;
- }
-
- // ===============================
- // COMMON: Generate Deliverable
- // ===============================
-
- private async Task GenerateDeliverable(string templateId, string name, string description)
+ // Step 2: Generate deliverable with simple variables
+ public async Task GenerateDeliverable(string templateId)
{
var payload = $$"""
{
"templateId": "{{templateId}}",
- "name": "{{name}}",
- "description": "{{description}}",
+ "name": "Generated Document",
+ "description": "Simple document example",
"variables": [
{
"mimeType": "text",
- "name": "Sample Variable",
- "placeholder": "{SampleVariable}",
- "text": "Sample Content from C# Workflow",
- "allowRichTextInjection": 0,
- "autogenerated": false,
- "count": 1,
- "order": 1,
- "subvariables": [],
- "metadata": {
- "generatedBy": "C# Workflow"
- },
- "aiPrompt": ""
+ "name": "Company Name",
+ "placeholder": "{CompanyName}",
+ "text": "Acme Corporation"
+ },
+ {
+ "mimeType": "text",
+ "name": "Employee Name",
+ "placeholder": "{EmployeeName}",
+ "text": "John Smith"
+ },
+ {
+ "mimeType": "text",
+ "name": "Date",
+ "placeholder": "{Date}",
+ "text": "January 15, 2024"
}
- ],
- "tags": ["api-generated"],
- "fonts": "[]",
- "defaultFont": "Arial",
- "replaceFonts": true,
- "metadata": {
- "sessions": [
- {
- "id": "{{Guid.NewGuid()}}",
- "starttime": "{{DateTime.UtcNow:yyyy-MM-ddTHH:mm:ss.fffZ}}",
- "endtime": "{{DateTime.UtcNow:yyyy-MM-ddTHH:mm:ss.fffZ}}"
- }
- ],
- "workflow": "C# Complete Workflow",
- "generated": "{{DateTime.UtcNow:yyyy-MM-ddTHH:mm:ss.fffZ}}"
- }
+ ]
}
""";
@@ -364,26 +115,21 @@ private async Task GenerateDeliverable(string templateId, string name, s
if (!response.IsSuccessStatusCode)
{
- var errorContent = await response.Content.ReadAsStringAsync();
- throw new HttpRequestException($"Deliverable generation failed: {response.StatusCode} - {errorContent}");
+ throw new HttpRequestException($"Generation failed: {response.StatusCode}");
}
var result = await response.Content.ReadAsStringAsync();
-
using var document = JsonDocument.Parse(result);
var deliverable = document.RootElement.GetProperty("data").GetProperty("results").GetProperty("deliverable");
- Console.WriteLine($"✅ Generated: {deliverable.GetProperty("name").GetString()}");
- Console.WriteLine($"📄 Created by: {deliverable.GetProperty("createdBy").GetString()}");
- Console.WriteLine($"📅 Created on: {deliverable.GetProperty("createdOn").GetString()}");
+ Console.WriteLine($"✅ Document generated: {deliverable.GetProperty("name").GetString()} ({deliverable.GetProperty("id").GetString()})");
- return result;
+ return deliverable;
}
- private async Task DownloadDeliverable(string deliverableId, string filename)
+ // Step 3: Download generated file
+ public async Task DownloadFile(string deliverableId, string filename)
{
- Console.WriteLine($"📥 Downloading file: {filename}");
-
var response = await client.GetAsync($"{BASE_URL}/deliverable/file/{deliverableId}");
if (!response.IsSuccessStatusCode)
@@ -393,76 +139,32 @@ private async Task DownloadDeliverable(string deliverableId, string filename)
Console.WriteLine($"✅ File ready for download: {filename}");
- var contentType = response.Content.Headers.ContentType?.ToString() ?? "N/A";
- var contentLength = response.Content.Headers.ContentLength?.ToString() ?? "N/A";
-
- Console.WriteLine($"📁 Content-Type: {contentType}");
- Console.WriteLine($"📊 Content-Length: {contentLength} bytes");
-
- // In a real application, you would save the file
+ // In a real application, you would save the file:
// var fileBytes = await response.Content.ReadAsByteArrayAsync();
// await File.WriteAllBytesAsync(filename, fileBytes);
}
- // ===============================
- // DEMO FUNCTIONS
- // ===============================
-
- public async Task DemoPathA(string templateFilePath)
- {
- Console.WriteLine("🚀 DEMO: Path A - Upload New Template Workflow");
- Console.WriteLine(new string('=', 45));
- Console.WriteLine();
-
- return await PathA_UploadAndGenerate(templateFilePath, "Contract Generated via Path A - API Upload");
- }
-
- public async Task DemoPathB()
+ // Complete workflow: Upload → Generate → Download
+ public async Task CompleteWorkflow(string templateFilePath)
{
- Console.WriteLine("🚀 DEMO: Path B - Browse Existing Template Workflow");
- Console.WriteLine(new string('=', 51));
- Console.WriteLine();
+ Console.WriteLine("🚀 Starting complete workflow...");
- return await PathB_BrowseAndGenerate("contract", "Contract Generated via Path B - Browse & Select");
- }
-
- public async Task DemoComparison()
- {
- Console.WriteLine("🚀 DEMO: Complete Workflow Comparison");
- Console.WriteLine(new string('=', 36));
- Console.WriteLine();
-
- try
- {
- Console.WriteLine("Testing both paths with the same template type...\n");
-
- // Run Path B first (browse existing)
- var pathBResult = await DemoPathB();
-
- Console.WriteLine("\n" + new string('=', 60) + "\n");
+ // Step 1: Upload template
+ Console.WriteLine("\n📤 Step 1: Uploading template...");
+ var template = await UploadTemplate(templateFilePath);
- // For Path A, we'd need a template file
- Console.WriteLine("📝 Path A requires a template file to upload.");
- Console.WriteLine(" Example: await workflow.DemoPathA(\"./contract-template.docx\")");
- }
- catch (Exception ex)
- {
- Console.WriteLine($"Demo comparison failed: {ex.Message}");
- }
- }
+ // Step 2: Generate deliverable
+ Console.WriteLine("\n📝 Step 2: Generating document...");
+ var deliverable = await GenerateDeliverable(template.GetProperty("id").GetString());
- // Result container class
- public class TemplateWorkflowResult
- {
- public string Template { get; }
- public string Deliverable { get; }
- public string PdfPreview { get; }
+ // Step 3: Download file
+ Console.WriteLine("\n📥 Step 3: Downloading file...");
+ string filename = deliverable.GetProperty("name").GetString() + ".docx";
+ await DownloadFile(deliverable.GetProperty("id").GetString(), filename);
- public TemplateWorkflowResult(string template, string deliverable, string pdfPreview)
- {
- Template = template;
- Deliverable = deliverable;
- PdfPreview = pdfPreview;
- }
+ Console.WriteLine("\n✅ Workflow complete!");
+ Console.WriteLine($"Template: {template.GetProperty("id").GetString()}");
+ Console.WriteLine($"Document: {deliverable.GetProperty("id").GetString()}");
+ Console.WriteLine($"File: {filename}");
}
}
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/curl.sh b/static/scripts/templates/api/complete-workflows/curl.sh
index 8080ae2..9538d29 100644
--- a/static/scripts/templates/api/complete-workflows/curl.sh
+++ b/static/scripts/templates/api/complete-workflows/curl.sh
@@ -5,393 +5,118 @@ API_TOKEN="YOUR_API_TOKEN"
ORG_ID="YOUR_ORGANIZATION_ID"
BASE_URL="https://api.turbodocx.com"
-# Colors for output formatting
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-BLUE='\033[0;34m'
-YELLOW='\033[1;33m'
-NC='\033[0m' # No Color
+# Complete Workflow: Upload → Generate → Download
+# Simple 3-step process for document generation
-echo -e "${BLUE}🚀 COMPLETE TEMPLATE GENERATION WORKFLOWS${NC}"
-echo -e "${BLUE}===========================================${NC}"
-echo
-
-# Function to generate session ID
-generate_session_id() {
- echo "session-$(date +%s)-$(shuf -i 1000-9999 -n 1)"
-}
-
-# Function to get current timestamp
-get_timestamp() {
- date -u +"%Y-%m-%dT%H:%M:%S.%3NZ"
-}
-
-# Function to download deliverable file
-download_deliverable() {
- local deliverable_id="$1"
- local filename="$2"
-
- echo "Downloading file: $filename"
-
- DOWNLOAD_RESPONSE=$(curl -s -X GET "$BASE_URL/deliverable/file/$deliverable_id" \
- -H "Authorization: Bearer $API_TOKEN" \
- -H "x-rapiddocx-org-id: $ORG_ID" \
- -H "User-Agent: TurboDocx API Client" \
- --output "$filename" \
- --write-out "HTTP_CODE:%{http_code};CONTENT_TYPE:%{content_type};SIZE:%{size_download}")
-
- HTTP_CODE=$(echo "$DOWNLOAD_RESPONSE" | grep -o 'HTTP_CODE:[0-9]*' | cut -d: -f2)
- CONTENT_TYPE=$(echo "$DOWNLOAD_RESPONSE" | grep -o 'CONTENT_TYPE:[^;]*' | cut -d: -f2)
- FILE_SIZE=$(echo "$DOWNLOAD_RESPONSE" | grep -o 'SIZE:[0-9]*' | cut -d: -f2)
-
- if [ "$HTTP_CODE" = "200" ]; then
- echo -e "${GREEN}✅ File downloaded successfully: $filename${NC}"
- echo -e "${GREEN}📁 Content-Type: $CONTENT_TYPE${NC}"
- echo -e "${GREEN}📊 File Size: $FILE_SIZE bytes${NC}"
- else
- echo -e "${RED}❌ Download failed with HTTP $HTTP_CODE${NC}"
- return 1
- fi
-}
-
-# ===============================
-# PATH A: Upload New Template
-# ===============================
-
-path_a_upload_and_generate() {
- local template_file="$1"
- local deliverable_name="$2"
-
- echo -e "${YELLOW}🔄 PATH A: Upload New Template → Generate Deliverable${NC}"
- echo -e "${YELLOW}================================================${NC}"
- echo
-
- if [ ! -f "$template_file" ]; then
- echo -e "${RED}❌ Error: Template file '$template_file' not found${NC}"
- echo "Please provide a valid .docx or .pptx file path"
- return 1
- fi
-
- # Step 1: Upload and create template
- echo -e "${BLUE}📤 Step 1: Uploading template...${NC}"
-
- UPLOAD_RESPONSE=$(curl -s -X POST "$BASE_URL/template/upload-and-create" \
- -H "Authorization: Bearer $API_TOKEN" \
- -H "x-rapiddocx-org-id: $ORG_ID" \
- -H "User-Agent: TurboDocx API Client" \
- -F "templateFile=@$template_file" \
- -F "name=API Upload Template" \
- -F "description=Template uploaded via API for testing" \
- -F 'variables=[]' \
- -F 'tags=["api", "test", "upload"]')
-
- if [ $? -ne 0 ]; then
- echo -e "${RED}❌ Template upload failed${NC}"
- return 1
- fi
-
- echo "Upload Response:"
- echo "$UPLOAD_RESPONSE" | jq '.'
-
- # Extract template ID and details
- TEMPLATE_ID=$(echo "$UPLOAD_RESPONSE" | jq -r '.data.results.template.id')
- TEMPLATE_NAME=$(echo "$UPLOAD_RESPONSE" | jq -r '.data.results.template.name')
- VARIABLE_COUNT=$(echo "$UPLOAD_RESPONSE" | jq '.data.results.template.variables | length // 0')
- DEFAULT_FONT=$(echo "$UPLOAD_RESPONSE" | jq -r '.data.results.template.defaultFont')
- FONT_COUNT=$(echo "$UPLOAD_RESPONSE" | jq '.data.results.template.fonts | length // 0')
-
- if [ "$TEMPLATE_ID" = "null" ] || [ -z "$TEMPLATE_ID" ]; then
- echo -e "${RED}❌ Failed to extract template ID from upload response${NC}"
- return 1
- fi
-
- echo -e "${GREEN}✅ Template uploaded: $TEMPLATE_NAME ($TEMPLATE_ID)${NC}"
- echo -e "${GREEN}📊 Variables extracted: $VARIABLE_COUNT${NC}"
- echo -e "${GREEN}🔤 Default font: $DEFAULT_FONT${NC}"
- echo -e "${GREEN}📝 Fonts used: $FONT_COUNT${NC}"
-
- # Step 2: Generate deliverable using uploaded template
- echo -e "\n${BLUE}📝 Step 2: Generating deliverable...${NC}"
-
- GENERATE_RESPONSE=$(curl -s -X POST "$BASE_URL/deliverable" \
- -H "Authorization: Bearer $API_TOKEN" \
- -H "x-rapiddocx-org-id: $ORG_ID" \
- -H "User-Agent: TurboDocx API Client" \
- -H "Content-Type: application/json" \
- -d '{
- "templateId": "'$TEMPLATE_ID'",
- "name": "'$deliverable_name'",
- "description": "Generated from uploaded template: '$TEMPLATE_NAME'",
- "variables": [
- {
- "mimeType": "text",
- "name": "Sample Variable",
- "placeholder": "{SampleVariable}",
- "text": "Sample Content from Path A",
- "allowRichTextInjection": 0,
- "autogenerated": false,
- "count": 1,
- "order": 1,
- "subvariables": [],
- "metadata": {
- "generatedBy": "Path A Workflow"
- },
- "aiPrompt": ""
- }
- ],
- "tags": ["api-generated", "path-a"],
- "fonts": "[]",
- "defaultFont": "Arial",
- "replaceFonts": true,
- "metadata": {
- "sessions": [
- {
- "id": "'$(generate_session_id)'",
- "starttime": "'$(get_timestamp)'",
- "endtime": "'$(get_timestamp)'"
- }
- ],
- "workflow": "Path A - Upload and Generate",
- "generated": "'$(get_timestamp)'"
- }
- }')
-
- echo "Generation Response:"
- echo "$GENERATE_RESPONSE" | jq '.'
-
- # Extract deliverable details
- DELIVERABLE_ID=$(echo "$GENERATE_RESPONSE" | jq -r '.data.results.deliverable.id')
- DELIVERABLE_NAME=$(echo "$GENERATE_RESPONSE" | jq -r '.data.results.deliverable.name')
- CREATED_BY=$(echo "$GENERATE_RESPONSE" | jq -r '.data.results.deliverable.createdBy')
-
- echo -e "\n${GREEN}✅ PATH A COMPLETE!${NC}"
- echo -e "${GREEN}Template ID: $TEMPLATE_ID${NC}"
- echo -e "${GREEN}Deliverable ID: $DELIVERABLE_ID${NC}"
- echo -e "${GREEN}Created by: $CREATED_BY${NC}"
-
- # Download the generated file
- echo -e "\n${BLUE}📥 Step 3: Downloading file...${NC}"
- download_deliverable "$DELIVERABLE_ID" "$DELIVERABLE_NAME.docx"
-}
-
-# ===============================
-# PATH B: Browse and Select
-# ===============================
-
-path_b_browse_and_generate() {
- local search_query="$1"
- local deliverable_name="$2"
-
- echo -e "${YELLOW}🔍 PATH B: Browse Existing Templates → Generate Deliverable${NC}"
- echo -e "${YELLOW}======================================================${NC}"
- echo
-
- # Step 1: Browse templates
- echo -e "${BLUE}🔍 Step 1: Browsing templates...${NC}"
-
- BROWSE_RESPONSE=$(curl -s -X GET "$BASE_URL/template-item?limit=10&offset=0&query=$search_query&showTags=true" \
- -H "Authorization: Bearer $API_TOKEN" \
- -H "x-rapiddocx-org-id: $ORG_ID" \
- -H "User-Agent: TurboDocx API Client")
-
- echo "Browse Results:"
- echo "$BROWSE_RESPONSE" | jq '.'
+echo "🚀 Starting complete workflow..."
- # Extract first template ID
- TEMPLATE_ID=$(echo "$BROWSE_RESPONSE" | jq -r '.data.results[] | select(.type == "template") | .id' | head -1)
-
- if [ "$TEMPLATE_ID" = "null" ] || [ -z "$TEMPLATE_ID" ]; then
- echo -e "${RED}❌ No templates found in browse results${NC}"
- return 1
- fi
-
- TEMPLATE_NAME=$(echo "$BROWSE_RESPONSE" | jq -r '.data.results[] | select(.id == "'$TEMPLATE_ID'") | .name')
- echo -e "${GREEN}📋 Selected: $TEMPLATE_NAME ($TEMPLATE_ID)${NC}"
-
- # Step 2: Get template details
- echo -e "\n${BLUE}📖 Step 2: Getting template details...${NC}"
-
- TEMPLATE_DETAILS=$(curl -s -X GET "$BASE_URL/template/$TEMPLATE_ID" \
- -H "Authorization: Bearer $API_TOKEN" \
- -H "x-rapiddocx-org-id: $ORG_ID" \
- -H "User-Agent: TurboDocx API Client")
-
- echo "Template Details:"
- echo "$TEMPLATE_DETAILS" | jq '.'
-
- VARIABLE_COUNT=$(echo "$TEMPLATE_DETAILS" | jq '.data.results.variables | length')
- DEFAULT_FONT=$(echo "$TEMPLATE_DETAILS" | jq -r '.data.results.defaultFont // "N/A"')
-
- echo -e "${GREEN}📊 Variables: $VARIABLE_COUNT${NC}"
- echo -e "${GREEN}🔤 Default font: $DEFAULT_FONT${NC}"
-
- # Step 3: Get PDF preview (optional)
- echo -e "\n${BLUE}🖼️ Step 3: Getting PDF preview...${NC}"
-
- PDF_PREVIEW=$(curl -s -X GET "$BASE_URL/template/$TEMPLATE_ID/previewpdflink" \
- -H "Authorization: Bearer $API_TOKEN" \
- -H "x-rapiddocx-org-id: $ORG_ID" \
- -H "User-Agent: TurboDocx API Client")
-
- echo "PDF Preview Response:"
- echo "$PDF_PREVIEW" | jq '.'
-
- PDF_URL=$(echo "$PDF_PREVIEW" | jq -r '.results')
- echo -e "${GREEN}🖼️ PDF Preview available: $PDF_URL${NC}"
-
- # Step 4: Generate deliverable
- echo -e "\n${BLUE}📝 Step 4: Generating deliverable...${NC}"
-
- GENERATE_RESPONSE=$(curl -s -X POST "$BASE_URL/deliverable" \
- -H "Authorization: Bearer $API_TOKEN" \
- -H "x-rapiddocx-org-id: $ORG_ID" \
- -H "User-Agent: TurboDocx API Client" \
- -H "Content-Type: application/json" \
- -d '{
- "templateId": "'$TEMPLATE_ID'",
- "name": "'$deliverable_name'",
- "description": "Generated from existing template: '$TEMPLATE_NAME'",
- "variables": [
- {
- "mimeType": "text",
- "name": "Sample Variable",
- "placeholder": "{SampleVariable}",
- "text": "Sample Content from Path B",
- "allowRichTextInjection": 0,
- "autogenerated": false,
- "count": 1,
- "order": 1,
- "subvariables": [
- {
- "placeholder": "{SampleVariable.SubItem}",
- "text": "Sub-content from browse workflow"
- }
- ],
- "metadata": {
- "generatedBy": "Path B Workflow",
- "sourceTemplate": "'$TEMPLATE_NAME'"
- },
- "aiPrompt": "Generate content appropriate for this selected template"
- }
- ],
- "tags": ["api-generated", "path-b", "browse-selected"],
- "fonts": "[]",
- "defaultFont": "'$DEFAULT_FONT'",
- "replaceFonts": true,
- "metadata": {
- "sessions": [
- {
- "id": "'$(generate_session_id)'",
- "starttime": "'$(get_timestamp)'",
- "endtime": "'$(get_timestamp)'"
- }
- ],
- "workflow": "Path B - Browse and Generate",
- "generated": "'$(get_timestamp)'",
- "pdfPreview": "'$PDF_URL'"
- }
- }')
-
- echo "Generation Response:"
- echo "$GENERATE_RESPONSE" | jq '.'
-
- # Extract deliverable details
- DELIVERABLE_ID=$(echo "$GENERATE_RESPONSE" | jq -r '.data.results.deliverable.id')
- DELIVERABLE_NAME=$(echo "$GENERATE_RESPONSE" | jq -r '.data.results.deliverable.name')
- CREATED_BY=$(echo "$GENERATE_RESPONSE" | jq -r '.data.results.deliverable.createdBy')
-
- echo -e "\n${GREEN}✅ PATH B COMPLETE!${NC}"
- echo -e "${GREEN}Template ID: $TEMPLATE_ID${NC}"
- echo -e "${GREEN}Deliverable ID: $DELIVERABLE_ID${NC}"
- echo -e "${GREEN}Created by: $CREATED_BY${NC}"
- echo -e "${GREEN}PDF Preview: $PDF_URL${NC}"
-
- # Download the generated file
- echo -e "\n${BLUE}📥 Step 5: Downloading file...${NC}"
- download_deliverable "$DELIVERABLE_ID" "$DELIVERABLE_NAME.docx"
-}
-
-# ===============================
-# DEMO FUNCTIONS
-# ===============================
-
-demo_path_a() {
- local template_file="$1"
- echo -e "${BLUE}🚀 DEMO: Path A - Upload New Template Workflow${NC}"
- echo -e "${BLUE}==============================================${NC}"
- echo
-
- if [ -z "$template_file" ]; then
- echo -e "${YELLOW}📝 Path A requires a template file to upload.${NC}"
- echo "Usage: demo_path_a './path/to/your/template.docx'"
- echo "Example: demo_path_a './contract-template.docx'"
- return 1
- fi
-
- path_a_upload_and_generate "$template_file" "Contract Generated via Path A - API Upload"
-}
-
-demo_path_b() {
- echo -e "${BLUE}🚀 DEMO: Path B - Browse Existing Template Workflow${NC}"
- echo -e "${BLUE}==================================================${NC}"
- echo
-
- path_b_browse_and_generate "contract" "Contract Generated via Path B - Browse & Select"
-}
-
-demo_comparison() {
- echo -e "${BLUE}🚀 DEMO: Complete Workflow Comparison${NC}"
- echo -e "${BLUE}====================================${NC}"
- echo
-
- echo "Testing both paths with the same template type..."
- echo
-
- # Run Path B first (browse existing)
- demo_path_b
+# Step 1: Upload template file
+echo
+echo "📤 Step 1: Uploading template..."
+
+TEMPLATE_FILE="./template.docx"
+
+if [ ! -f "$TEMPLATE_FILE" ]; then
+ echo "❌ Template file not found: $TEMPLATE_FILE"
+ echo "Please provide a valid template file path"
+ exit 1
+fi
+
+# Upload template
+UPLOAD_RESPONSE=$(curl -s -X POST "$BASE_URL/template/upload-and-create" \
+ -H "Authorization: Bearer $API_TOKEN" \
+ -H "x-rapiddocx-org-id: $ORG_ID" \
+ -H "User-Agent: TurboDocx API Client" \
+ -F "templateFile=@$TEMPLATE_FILE" \
+ -F "name=Simple Template" \
+ -F "description=Template uploaded for document generation")
+
+# Check if upload was successful
+if [ $? -ne 0 ]; then
+ echo "❌ Upload failed"
+ exit 1
+fi
+
+# Extract template ID
+TEMPLATE_ID=$(echo "$UPLOAD_RESPONSE" | jq -r '.data.results.template.id')
+TEMPLATE_NAME=$(echo "$UPLOAD_RESPONSE" | jq -r '.data.results.template.name')
+
+if [ "$TEMPLATE_ID" == "null" ] || [ -z "$TEMPLATE_ID" ]; then
+ echo "❌ Failed to extract template ID from response"
+ exit 1
+fi
+
+echo "✅ Template uploaded: $TEMPLATE_NAME ($TEMPLATE_ID)"
+
+# Step 2: Generate deliverable with simple variables
+echo
+echo "📝 Step 2: Generating document..."
+
+DELIVERABLE_RESPONSE=$(curl -s -X POST "$BASE_URL/deliverable" \
+ -H "Authorization: Bearer $API_TOKEN" \
+ -H "x-rapiddocx-org-id: $ORG_ID" \
+ -H "User-Agent: TurboDocx API Client" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "templateId": "'$TEMPLATE_ID'",
+ "name": "Generated Document",
+ "description": "Simple document example",
+ "variables": [
+ {
+ "mimeType": "text",
+ "name": "Company Name",
+ "placeholder": "{CompanyName}",
+ "text": "Acme Corporation"
+ },
+ {
+ "mimeType": "text",
+ "name": "Employee Name",
+ "placeholder": "{EmployeeName}",
+ "text": "John Smith"
+ },
+ {
+ "mimeType": "text",
+ "name": "Date",
+ "placeholder": "{Date}",
+ "text": "January 15, 2024"
+ }
+ ]
+ }')
+
+# Extract deliverable ID
+DELIVERABLE_ID=$(echo "$DELIVERABLE_RESPONSE" | jq -r '.data.results.deliverable.id')
+DELIVERABLE_NAME=$(echo "$DELIVERABLE_RESPONSE" | jq -r '.data.results.deliverable.name')
+
+if [ "$DELIVERABLE_ID" == "null" ] || [ -z "$DELIVERABLE_ID" ]; then
+ echo "❌ Failed to generate document"
+ echo "Response: $DELIVERABLE_RESPONSE"
+ exit 1
+fi
+
+echo "✅ Document generated: $DELIVERABLE_NAME ($DELIVERABLE_ID)"
+
+# Step 3: Download generated file
+echo
+echo "📥 Step 3: Downloading file..."
- echo
- echo -e "${BLUE}${'='*60}${NC}"
- echo
+DOWNLOAD_FILE="${DELIVERABLE_NAME}.docx"
- # For Path A, we'd need a template file
- echo -e "${YELLOW}📝 Path A requires a template file to upload.${NC}"
- echo " Example: demo_path_a './contract-template.docx'"
- echo
- echo "To test Path A, run:"
- echo " $0 path-a ./path/to/your/template.docx"
-}
+curl -s -X GET "$BASE_URL/deliverable/file/$DELIVERABLE_ID" \
+ -H "Authorization: Bearer $API_TOKEN" \
+ -H "x-rapiddocx-org-id: $ORG_ID" \
+ -H "User-Agent: TurboDocx API Client" \
+ --output "$DOWNLOAD_FILE" \
+ --write-out "Downloaded: %{filename_effective} (%{size_download} bytes)\n"
-# ===============================
-# MAIN EXECUTION
-# ===============================
+if [ $? -eq 0 ]; then
+ echo "✅ File ready for download: $DOWNLOAD_FILE"
+else
+ echo "❌ Download failed"
+ exit 1
+fi
-case "${1:-demo}" in
- "path-a")
- demo_path_a "$2"
- ;;
- "path-b")
- demo_path_b
- ;;
- "comparison")
- demo_comparison
- ;;
- "demo"|*)
- echo -e "${BLUE}Template Generation API - Complete Workflows${NC}"
- echo -e "${BLUE}===========================================${NC}"
- echo
- echo "Available commands:"
- echo " $0 path-a - Demo Path A (upload new template)"
- echo " $0 path-b - Demo Path B (browse existing templates)"
- echo " $0 comparison - Compare both workflows"
- echo
- echo "Examples:"
- echo " $0 path-a ./contract-template.docx"
- echo " $0 path-b"
- echo " $0 comparison"
- echo
- echo "Running Path B demo by default..."
- echo
- demo_path_b
- ;;
-esac
\ No newline at end of file
+echo
+echo "✅ Workflow complete!"
+echo "Template: $TEMPLATE_ID"
+echo "Document: $DELIVERABLE_ID"
+echo "File: $DOWNLOAD_FILE"
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/fastify.js b/static/scripts/templates/api/complete-workflows/fastify.js
index d091c78..f8dfcf8 100644
--- a/static/scripts/templates/api/complete-workflows/fastify.js
+++ b/static/scripts/templates/api/complete-workflows/fastify.js
@@ -1,9 +1,6 @@
-const fastify = require('fastify')({ logger: true });
-const fs = require('fs');
-const path = require('path');
const FormData = require('form-data');
-const axios = require('axios');
-const { v4: uuidv4 } = require('uuid');
+const fs = require('fs');
+const fetch = require('node-fetch');
// Configuration - Update these values
const API_TOKEN = "YOUR_API_TOKEN";
@@ -11,546 +8,169 @@ const ORG_ID = "YOUR_ORGANIZATION_ID";
const BASE_URL = "https://api.turbodocx.com";
/**
- * Complete Template Workflow Manager
- * Demonstrates both upload and browse/select paths
+ * Complete Workflow: Upload → Generate → Download
+ * Simple 3-step process for document generation
*/
-class TemplateWorkflowManager {
- constructor(apiToken, orgId, baseUrl) {
- this.apiToken = apiToken;
- this.orgId = orgId;
- this.baseUrl = baseUrl;
- console.log('=== TurboDocx Template Generation Workflow Manager ===');
- }
-
- async demonstrateCompleteWorkflow() {
- console.log('\nSelect workflow path:');
- console.log('A) Upload new template');
- console.log('B) Browse and select existing template');
-
- // For this example, we'll demonstrate both paths
- console.log('\n=== Demonstrating Path A: Upload Template ===');
- const templateIdA = await this.demonstrateUploadWorkflow();
-
- console.log('\n=== Demonstrating Path B: Browse Templates ===');
- const templateIdB = await this.demonstrateBrowseWorkflow();
-
- // Generate deliverables for both templates if successful
- if (templateIdA) {
- console.log('\n=== Generating Deliverable from Uploaded Template ===');
- await this.generateAndDownloadDeliverable(templateIdA, 'A');
- }
-
- if (templateIdB) {
- console.log('\n=== Generating Deliverable from Selected Template ===');
- await this.generateAndDownloadDeliverable(templateIdB, 'B');
- }
-
- return {
- uploadedTemplateId: templateIdA,
- selectedTemplateId: templateIdB
- };
- }
-
- async demonstrateUploadWorkflow() {
- try {
- console.log('\n--- Path A: Upload and Create Template ---');
-
- // Check for template file
- const templateFile = './contract-template.docx';
- if (!fs.existsSync(templateFile)) {
- console.log(`⚠️ Template file not found: ${templateFile}`);
- console.log('Creating a placeholder message for demonstration');
- return null;
- }
-
- const result = await this.uploadTemplate(templateFile);
- const template = result.data.results.template;
-
- console.log('✅ Upload workflow completed');
- console.log(`Template ID: ${template.id}`);
- console.log('Ready for deliverable generation');
-
- return template.id;
- } catch (error) {
- console.error(`❌ Upload workflow failed: ${error.message}`);
- return null;
- }
- }
-
- async demonstrateBrowseWorkflow() {
- try {
- console.log('\n--- Path B: Browse and Select Template ---');
-
- // Browse templates
- const browseResult = await this.browseTemplates(10, 0, 'contract', true);
-
- // Find first template (not folder)
- const selectedTemplate = browseResult.results.find(item => item.type === 'template');
-
- if (!selectedTemplate) {
- console.log('⚠️ No templates found in browse results');
- return null;
- }
-
- console.log(`Selected: ${selectedTemplate.name}`);
-
- // Get detailed information
- const templateDetails = await this.getTemplateDetails(selectedTemplate.id);
-
- // Optionally get PDF preview
- const pdfPreview = await this.getTemplatePdfPreview(selectedTemplate.id);
-
- console.log('✅ Browse workflow completed');
- console.log(`Template ID: ${templateDetails.id}`);
- console.log(`PDF Preview: ${pdfPreview}`);
- console.log('Ready for deliverable generation');
-
- return templateDetails.id;
- } catch (error) {
- console.error(`❌ Browse workflow failed: ${error.message}`);
- return null;
- }
- }
-
- async generateAndDownloadDeliverable(templateId, pathLabel) {
- try {
- console.log(`\n--- Generating Deliverable (Path ${pathLabel}) ---`);
-
- const deliverableData = this.createDeliverableData(templateId, pathLabel);
- const deliverable = await this.generateDeliverable(templateId, deliverableData);
-
- // Download the file
- const downloadResult = await this.downloadDeliverable(
- deliverable.id,
- `${deliverable.name}_path_${pathLabel}.docx`
- );
-
- console.log(`✅ Complete workflow finished successfully for Path ${pathLabel}`);
- console.log(`Deliverable ID: ${deliverable.id}`);
- console.log(`Download info: ${JSON.stringify(downloadResult, null, 2)}`);
-
- return {
- deliverable,
- downloadResult
- };
- } catch (error) {
- console.error(`❌ Deliverable generation failed for Path ${pathLabel}: ${error.message}`);
- throw error;
- }
- }
-
- async uploadTemplate(templateFilePath) {
- const url = `${this.baseUrl}/template/upload-and-create`;
-
- // Create form data
- const form = new FormData();
-
- // Add template file
- form.append('templateFile', fs.createReadStream(templateFilePath), {
- filename: path.basename(templateFilePath),
- contentType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- });
-
- // Add metadata fields
- form.append('name', 'Employee Contract Template');
- form.append('description', 'Standard employee contract with variable placeholders');
- form.append('variables', '[]');
- form.append('tags', '["hr", "contract", "template"]');
-
- const response = await axios.post(url, form, {
- headers: {
- 'Authorization': `Bearer ${this.apiToken}`,
- 'x-rapiddocx-org-id': this.orgId,
- 'User-Agent': 'TurboDocx API Client',
- ...form.getHeaders()
- }
- });
-
- return response.data;
- }
-
- async browseTemplates(limit, offset, query, showTags) {
- // Build query parameters
- const params = new URLSearchParams({
- limit: limit.toString(),
- offset: offset.toString(),
- showTags: showTags.toString()
- });
-
- if (query) {
- params.append('query', query);
- }
-
- const url = `${this.baseUrl}/template-item?${params.toString()}`;
-
- const response = await axios.get(url, {
- headers: {
- 'Authorization': `Bearer ${this.apiToken}`,
- 'x-rapiddocx-org-id': this.orgId,
- 'User-Agent': 'TurboDocx API Client'
- }
- });
-
- return response.data.data;
- }
-
- async getTemplateDetails(templateId) {
- const url = `${this.baseUrl}/template/${templateId}`;
-
- const response = await axios.get(url, {
- headers: {
- 'Authorization': `Bearer ${this.apiToken}`,
- 'x-rapiddocx-org-id': this.orgId,
- 'User-Agent': 'TurboDocx API Client'
- }
- });
-
- return response.data.data.results;
- }
-
- async getTemplatePdfPreview(templateId) {
- const url = `${this.baseUrl}/template/${templateId}/previewpdflink`;
-
- const response = await axios.get(url, {
- headers: {
- 'Authorization': `Bearer ${this.apiToken}`,
- 'x-rapiddocx-org-id': this.orgId,
- 'User-Agent': 'TurboDocx API Client'
- }
- });
-
- return response.data.results;
- }
-
- async generateDeliverable(templateId, deliverableData) {
- const url = `${this.baseUrl}/deliverable`;
-
- console.log('Generating deliverable...');
- console.log(`Template ID: ${templateId}`);
- console.log(`Deliverable Name: ${deliverableData.name}`);
- console.log(`Variables: ${deliverableData.variables.length}`);
-
- const response = await axios.post(url, deliverableData, {
- headers: {
- 'Authorization': `Bearer ${this.apiToken}`,
- 'x-rapiddocx-org-id': this.orgId,
- 'User-Agent': 'TurboDocx API Client',
- 'Content-Type': 'application/json'
- }
- });
-
- // Parse JSON response
- const deliverable = response.data.data.results.deliverable;
+// Step 1: Upload template file
+async function uploadTemplate(templateFilePath) {
+ const formData = new FormData();
+ formData.append('templateFile', fs.createReadStream(templateFilePath));
+ formData.append('name', 'Simple Template');
+ formData.append('description', 'Template uploaded for document generation');
+
+ const response = await fetch(`${BASE_URL}/template/upload-and-create`, {
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${API_TOKEN}`,
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client',
+ ...formData.getHeaders()
+ },
+ body: formData
+ });
+
+ if (!response.ok) {
+ throw new Error(`Upload failed: ${response.status}`);
+ }
+
+ const result = await response.json();
+ const template = result.data.results.template;
+
+ console.log(`✅ Template uploaded: ${template.name} (${template.id})`);
+ return template;
+}
- console.log('✅ Deliverable generated successfully!');
- console.log(`Deliverable ID: ${deliverable.id}`);
- console.log(`Created by: ${deliverable.createdBy}`);
- console.log(`Created on: ${deliverable.createdOn}`);
- console.log(`Template ID: ${deliverable.templateId}`);
+// Step 2: Generate deliverable with simple variables
+async function generateDeliverable(templateId) {
+ const variables = [
+ {
+ mimeType: "text",
+ name: "Company Name",
+ placeholder: "{CompanyName}",
+ text: "Acme Corporation"
+ },
+ {
+ mimeType: "text",
+ name: "Employee Name",
+ placeholder: "{EmployeeName}",
+ text: "John Smith"
+ },
+ {
+ mimeType: "text",
+ name: "Date",
+ placeholder: "{Date}",
+ text: "January 15, 2024"
+ }
+ ];
+
+ const payload = {
+ templateId: templateId,
+ name: "Generated Document",
+ description: "Simple document example",
+ variables: variables
+ };
+
+ const response = await fetch(`${BASE_URL}/deliverable`, {
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${API_TOKEN}`,
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(payload)
+ });
+
+ if (!response.ok) {
+ throw new Error(`Generation failed: ${response.status}`);
+ }
+
+ const result = await response.json();
+ const deliverable = result.data.results.deliverable;
+
+ console.log(`✅ Document generated: ${deliverable.name} (${deliverable.id})`);
+ return deliverable;
+}
- return deliverable;
+// Step 3: Download generated file
+async function downloadFile(deliverableId, filename) {
+ const response = await fetch(`${BASE_URL}/deliverable/file/${deliverableId}`, {
+ method: 'GET',
+ headers: {
+ 'Authorization': `Bearer ${API_TOKEN}`,
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client'
}
+ });
- async downloadDeliverable(deliverableId, filename) {
- console.log(`Downloading file: ${filename}`);
+ if (!response.ok) {
+ throw new Error(`Download failed: ${response.status}`);
+ }
- const url = `${this.baseUrl}/deliverable/file/${deliverableId}`;
+ console.log(`✅ File ready for download: ${filename}`);
- const response = await axios.get(url, {
- headers: {
- 'Authorization': `Bearer ${this.apiToken}`,
- 'x-rapiddocx-org-id': this.orgId,
- 'User-Agent': 'TurboDocx API Client'
- },
- responseType: 'stream'
- });
+ // In a real application, you would save the file:
+ // const buffer = await response.buffer();
+ // fs.writeFileSync(filename, buffer);
- console.log(`✅ File ready for download: ${filename}`);
-
- const contentType = response.headers['content-type'] || 'N/A';
- const contentLength = response.headers['content-length'] || 'N/A';
-
- console.log(`📁 Content-Type: ${contentType}`);
- console.log(`📊 Content-Length: ${contentLength} bytes`);
-
- // In a real application, you would save the file
- // const writer = fs.createWriteStream(filename);
- // response.data.pipe(writer);
-
- return {
- filename,
- contentType,
- contentLength
- };
- }
-
- createDeliverableData(templateId, pathLabel) {
- const now = new Date().toISOString();
-
- return {
- templateId,
- name: `Contract Document - Path ${pathLabel}`,
- description: `Employment contract generated via workflow path ${pathLabel}`,
- variables: this.createComplexVariables(),
- tags: ['hr', 'contract', 'employee', 'engineering'],
- fonts: '[{"name":"Arial","usage":269}]',
- defaultFont: 'Arial',
- replaceFonts: true,
- metadata: {
- sessions: [
- {
- id: uuidv4(),
- starttime: now,
- endtime: now
- }
- ],
- createdBy: 'Node.js Workflow Manager',
- documentType: 'Employment Contract',
- version: 'v1.0',
- workflowPath: pathLabel
- }
- };
- }
-
- createComplexVariables() {
- return [
- {
- mimeType: 'text',
- name: 'Employee Name',
- placeholder: '{EmployeeName}',
- text: 'John Smith',
- allowRichTextInjection: 0,
- autogenerated: false,
- count: 1,
- order: 1,
- subvariables: [
- {
- placeholder: '{EmployeeName.Title}',
- text: 'Senior Software Engineer'
- },
- {
- placeholder: '{EmployeeName.StartDate}',
- text: 'January 15, 2024'
- }
- ],
- metadata: {
- department: 'Engineering',
- level: 'Senior'
- },
- aiPrompt: 'Generate a professional job description for a senior software engineer role'
- },
- {
- mimeType: 'text',
- name: 'Company Information',
- placeholder: '{CompanyInfo}',
- text: 'TechCorp Solutions Inc.',
- allowRichTextInjection: 1,
- autogenerated: false,
- count: 1,
- order: 2,
- subvariables: [
- {
- placeholder: '{CompanyInfo.Address}',
- text: '123 Innovation Drive, Tech City, TC 12345'
- },
- {
- placeholder: '{CompanyInfo.Phone}',
- text: '(555) 123-4567'
- }
- ],
- metadata: {},
- aiPrompt: ''
- }
- ];
- }
+ return {
+ filename,
+ contentType: response.headers.get('content-type'),
+ contentLength: response.headers.get('content-length')
+ };
}
-// Fastify route handlers
-async function registerRoutes() {
- // Complete workflow demonstration route
- fastify.post('/complete-workflow', async (request, reply) => {
- try {
- console.log('Starting complete workflow demonstration...');
-
- const workflowManager = new TemplateWorkflowManager(API_TOKEN, ORG_ID, BASE_URL);
- const result = await workflowManager.demonstrateCompleteWorkflow();
+// Complete workflow: Upload → Generate → Download
+async function completeWorkflow(templateFilePath) {
+ try {
+ console.log('🚀 Starting complete workflow...');
- reply.send({
- success: true,
- message: 'Complete workflow demonstration finished',
- data: result
- });
- } catch (error) {
- console.error('Error in complete workflow:', error);
- reply.code(500).send({
- error: 'Complete workflow failed',
- message: error.message
- });
- }
- });
+ // Step 1: Upload template
+ console.log('\n📤 Step 1: Uploading template...');
+ const template = await uploadTemplate(templateFilePath);
- // Individual workflow paths
- fastify.post('/upload-workflow', async (request, reply) => {
- try {
- const { templateFilePath } = request.body;
+ // Step 2: Generate deliverable
+ console.log('\n📝 Step 2: Generating document...');
+ const deliverable = await generateDeliverable(template.id);
- if (!templateFilePath) {
- return reply.code(400).send({
- error: 'templateFilePath is required'
- });
- }
+ // Step 3: Download file
+ console.log('\n📥 Step 3: Downloading file...');
+ const downloadInfo = await downloadFile(deliverable.id, `${deliverable.name}.docx`);
- const workflowManager = new TemplateWorkflowManager(API_TOKEN, ORG_ID, BASE_URL);
- const templateId = await workflowManager.demonstrateUploadWorkflow();
+ console.log('\n✅ Workflow complete!');
+ console.log(`Template: ${template.id}`);
+ console.log(`Document: ${deliverable.id}`);
+ console.log(`File: ${downloadInfo.filename}`);
- if (!templateId) {
- return reply.code(404).send({
- error: 'Upload workflow failed',
- message: 'Template file not found or upload failed'
- });
- }
+ return { template, deliverable, downloadInfo };
- // Generate deliverable
- const deliverableResult = await workflowManager.generateAndDownloadDeliverable(templateId, 'Upload');
-
- reply.send({
- success: true,
- message: 'Upload workflow completed successfully',
- data: {
- templateId,
- ...deliverableResult
- }
- });
- } catch (error) {
- console.error('Error in upload workflow:', error);
- reply.code(500).send({
- error: 'Upload workflow failed',
- message: error.message
- });
- }
- });
-
- fastify.post('/browse-workflow', async (request, reply) => {
- try {
- const workflowManager = new TemplateWorkflowManager(API_TOKEN, ORG_ID, BASE_URL);
- const templateId = await workflowManager.demonstrateBrowseWorkflow();
-
- if (!templateId) {
- return reply.code(404).send({
- error: 'Browse workflow failed',
- message: 'No templates found or selection failed'
- });
- }
-
- // Generate deliverable
- const deliverableResult = await workflowManager.generateAndDownloadDeliverable(templateId, 'Browse');
-
- reply.send({
- success: true,
- message: 'Browse workflow completed successfully',
- data: {
- templateId,
- ...deliverableResult
- }
- });
- } catch (error) {
- console.error('Error in browse workflow:', error);
- reply.code(500).send({
- error: 'Browse workflow failed',
- message: error.message
- });
- }
- });
-
- // Health check route
- fastify.get('/health', async (request, reply) => {
- reply.send({ status: 'healthy', service: 'workflow-manager' });
- });
-
- // Service info route
- fastify.get('/workflow-info', async (request, reply) => {
- reply.send({
- service: 'TurboDocx Complete Workflow Manager Service',
- endpoints: {
- 'POST /complete-workflow': 'Demonstrate both upload and browse workflows',
- 'POST /upload-workflow': 'Execute upload workflow only',
- 'POST /browse-workflow': 'Execute browse workflow only',
- 'GET /health': 'Service health check',
- 'GET /workflow-info': 'Service information'
- },
- configuration: {
- baseUrl: BASE_URL,
- hasToken: !!API_TOKEN && API_TOKEN !== 'YOUR_API_TOKEN',
- hasOrgId: !!ORG_ID && ORG_ID !== 'YOUR_ORGANIZATION_ID'
- },
- description: 'Complete workflow manager that demonstrates both template upload and browse/select paths, followed by deliverable generation and download.'
- });
- });
+ } catch (error) {
+ console.error('❌ Workflow failed:', error.message);
+ throw error;
+ }
}
-// Example usage function
-async function demonstrateCompleteWorkflow() {
- try {
- console.log('=== Complete Template Workflow Demonstration ===');
-
- const workflowManager = new TemplateWorkflowManager(API_TOKEN, ORG_ID, BASE_URL);
- const result = await workflowManager.demonstrateCompleteWorkflow();
-
- console.log('\n=== Workflow Demonstration Complete ===');
- console.log('Both upload and browse/select paths have been demonstrated.');
- console.log('Choose the appropriate path for your use case:');
- console.log('- Upload path: When you have new templates to create');
- console.log('- Browse path: When you want to use existing templates');
-
- return result;
- } catch (error) {
- console.error('Workflow demonstration failed:', error.message);
- process.exit(1);
- }
+// Example usage
+async function example() {
+ try {
+ // Replace with your template file path
+ const templatePath = './template.docx';
+ await completeWorkflow(templatePath);
+ } catch (error) {
+ console.error('Example failed:', error.message);
+ }
}
-// Server startup
-async function startServer() {
- try {
- await registerRoutes();
-
- const port = process.env.PORT || 3004;
- const host = process.env.HOST || '0.0.0.0';
-
- await fastify.listen({ port, host });
-
- console.log('🚀 TurboDocx Complete Workflow Manager Service started');
- console.log(`📡 Server listening on http://${host}:${port}`);
- console.log('\nAvailable endpoints:');
- console.log(` POST http://${host}:${port}/complete-workflow`);
- console.log(` POST http://${host}:${port}/upload-workflow`);
- console.log(` POST http://${host}:${port}/browse-workflow`);
- console.log(` GET http://${host}:${port}/health`);
- console.log(` GET http://${host}:${port}/workflow-info`);
-
- } catch (error) {
- fastify.log.error(error);
- process.exit(1);
- }
-}
+// Export functions
+module.exports = {
+ uploadTemplate,
+ generateDeliverable,
+ downloadFile,
+ completeWorkflow
+};
-// Check if this file is being run directly
+// Run example if script is executed directly
if (require.main === module) {
- const args = process.argv.slice(2);
-
- if (args.includes('--demo')) {
- // Run demonstration
- demonstrateCompleteWorkflow();
- } else {
- // Start server
- startServer();
- }
-}
-
-module.exports = {
- TemplateWorkflowManager,
- demonstrateCompleteWorkflow,
- startServer,
- fastify
-};
\ No newline at end of file
+ example();
+}
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/go.go b/static/scripts/templates/api/complete-workflows/go.go
index fd6a16e..cfca9a6 100644
--- a/static/scripts/templates/api/complete-workflows/go.go
+++ b/static/scripts/templates/api/complete-workflows/go.go
@@ -7,9 +7,7 @@ import (
"io"
"mime/multipart"
"net/http"
- "net/url"
"os"
- "time"
)
// Configuration - Update these values
@@ -19,168 +17,70 @@ const (
BASE_URL = "https://api.turbodocx.com"
)
-// Response structures
-type UploadResponse struct {
- Data struct {
- Results struct {
- Template struct {
- ID string `json:"id"`
- Name string `json:"name"`
- DefaultFont string `json:"defaultFont"`
- Variables []struct {
- Name string `json:"name"`
- } `json:"variables"`
- Fonts []struct {
- Name string `json:"name"`
- } `json:"fonts"`
- } `json:"template"`
- } `json:"results"`
- } `json:"data"`
+// Complete Workflow: Upload → Generate → Download
+// Simple 3-step process for document generation
+
+type Variable struct {
+ MimeType string `json:"mimeType"`
+ Name string `json:"name"`
+ Placeholder string `json:"placeholder"`
+ Text string `json:"text"`
}
-type BrowseResponse struct {
- Data struct {
- Results []struct {
- ID string `json:"id"`
- Name string `json:"name"`
- Type string `json:"type"`
- } `json:"results"`
- TotalRecords int `json:"totalRecords"`
- } `json:"data"`
+type Template struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
}
-type TemplateDetailsResponse struct {
+type Deliverable struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+}
+
+type UploadResponse struct {
Data struct {
Results struct {
- ID string `json:"id"`
- Name string `json:"name"`
- Variables []struct {
- Name string `json:"name"`
- } `json:"variables"`
- DefaultFont string `json:"defaultFont"`
+ Template Template `json:"template"`
} `json:"results"`
} `json:"data"`
}
-type PDFPreviewResponse struct {
- Results string `json:"results"`
-}
-
type DeliverableResponse struct {
Data struct {
Results struct {
- Deliverable struct {
- ID string `json:"id"`
- Name string `json:"name"`
- CreatedBy string `json:"createdBy"`
- CreatedOn string `json:"createdOn"`
- } `json:"deliverable"`
+ Deliverable Deliverable `json:"deliverable"`
} `json:"results"`
} `json:"data"`
}
-/**
- * Complete Template Generation Workflows
- * Demonstrates both Path A (Upload) and Path B (Browse/Select) followed by generation
- */
-type TemplateWorkflowManager struct {
- client *http.Client
-}
-
-func NewTemplateWorkflowManager() *TemplateWorkflowManager {
- return &TemplateWorkflowManager{
- client: &http.Client{},
- }
-}
-
-func main() {
- workflow := NewTemplateWorkflowManager()
-
- // Demo Path B (Browse existing templates)
- err := workflow.DemoPathB()
- if err != nil {
- fmt.Printf("Workflow demo failed: %v\n", err)
- return
- }
-
- // Uncomment to demo Path A (requires template file):
- // err = workflow.DemoPathA("./path/to/your/template.docx")
-
- // Uncomment to run full comparison:
- // err = workflow.DemoComparison()
-}
-
-// ===============================
-// PATH A: Upload New Template
-// ===============================
-
-/**
- * Complete Path A workflow: Upload → Generate
- */
-func (tm *TemplateWorkflowManager) PathA_UploadAndGenerate(templateFilePath, deliverableName string) error {
- fmt.Println("🔄 PATH A: Upload New Template → Generate Deliverable")
- fmt.Println(fmt.Sprintf("%s", fmt.Sprintf("%48s", "").ReplaceAll(" ", "=")))
-
- // Step 1: Upload and create template
- fmt.Println("\n📤 Step 1: Uploading template...")
- template, err := tm.uploadTemplate(templateFilePath)
- if err != nil {
- fmt.Printf("❌ Path A failed: %v\n", err)
- return err
- }
-
- // Step 2: Generate deliverable using uploaded template
- fmt.Println("\n📝 Step 2: Generating deliverable...")
- deliverable, err := tm.generateDeliverable(template.Data.Results.Template.ID, deliverableName,
- fmt.Sprintf("Generated from uploaded template: %s", template.Data.Results.Template.Name))
- if err != nil {
- fmt.Printf("❌ Path A failed: %v\n", err)
- return err
- }
-
- fmt.Println("\n✅ PATH A COMPLETE!")
- fmt.Printf("Template ID: %s\n", template.Data.Results.Template.ID)
- fmt.Printf("Deliverable ID: %s\n", deliverable.Data.Results.Deliverable.ID)
-
- // Download the generated file
- return tm.downloadDeliverable(deliverable.Data.Results.Deliverable.ID,
- deliverable.Data.Results.Deliverable.Name+".docx")
-}
-
-func (tm *TemplateWorkflowManager) uploadTemplate(templateFilePath string) (*UploadResponse, error) {
- if _, err := os.Stat(templateFilePath); os.IsNotExist(err) {
- return nil, fmt.Errorf("template file not found: %s", templateFilePath)
- }
-
+// Step 1: Upload template file
+func uploadTemplate(templateFilePath string) (*Template, error) {
var buf bytes.Buffer
writer := multipart.NewWriter(&buf)
file, err := os.Open(templateFilePath)
if err != nil {
- return nil, fmt.Errorf("failed to open file: %v", err)
+ return nil, fmt.Errorf("failed to open template file: %w", err)
}
defer file.Close()
part, err := writer.CreateFormFile("templateFile", templateFilePath)
if err != nil {
- return nil, fmt.Errorf("failed to create form file: %v", err)
+ return nil, err
}
_, err = io.Copy(part, file)
if err != nil {
- return nil, fmt.Errorf("failed to copy file: %v", err)
+ return nil, err
}
- writer.WriteField("name", "API Upload Template")
- writer.WriteField("description", "Template uploaded via API for testing")
- writer.WriteField("variables", "[]")
- writer.WriteField("tags", `["api", "test", "upload"]`)
-
+ writer.WriteField("name", "Simple Template")
+ writer.WriteField("description", "Template uploaded for document generation")
writer.Close()
req, err := http.NewRequest("POST", BASE_URL+"/template/upload-and-create", &buf)
if err != nil {
- return nil, fmt.Errorf("failed to create request: %v", err)
+ return nil, err
}
req.Header.Set("Authorization", "Bearer "+API_TOKEN)
@@ -188,311 +88,66 @@ func (tm *TemplateWorkflowManager) uploadTemplate(templateFilePath string) (*Upl
req.Header.Set("User-Agent", "TurboDocx API Client")
req.Header.Set("Content-Type", writer.FormDataContentType())
- resp, err := tm.client.Do(req)
+ client := &http.Client{}
+ resp, err := client.Do(req)
if err != nil {
- return nil, fmt.Errorf("failed to make request: %v", err)
+ return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
- body, _ := io.ReadAll(resp.Body)
- return nil, fmt.Errorf("upload failed: %d - %s", resp.StatusCode, string(body))
- }
-
- body, err := io.ReadAll(resp.Body)
- if err != nil {
- return nil, fmt.Errorf("failed to read response: %v", err)
+ return nil, fmt.Errorf("upload failed: %d", resp.StatusCode)
}
var result UploadResponse
- err = json.Unmarshal(body, &result)
- if err != nil {
- return nil, fmt.Errorf("failed to parse JSON: %v", err)
+ if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
+ return nil, err
}
template := result.Data.Results.Template
fmt.Printf("✅ Template uploaded: %s (%s)\n", template.Name, template.ID)
- variableCount := 0
- if template.Variables != nil {
- variableCount = len(template.Variables)
- }
- fmt.Printf("📊 Variables extracted: %d\n", variableCount)
-
- fmt.Printf("🔤 Default font: %s\n", template.DefaultFont)
-
- fontCount := 0
- if template.Fonts != nil {
- fontCount = len(template.Fonts)
- }
- fmt.Printf("📝 Fonts used: %d\n", fontCount)
-
- return &result, nil
-}
-
-// ===============================
-// PATH B: Browse and Select
-// ===============================
-
-/**
- * Complete Path B workflow: Browse → Select → Generate
- */
-func (tm *TemplateWorkflowManager) PathB_BrowseAndGenerate(searchQuery, deliverableName string) error {
- fmt.Println("🔍 PATH B: Browse Existing Templates → Generate Deliverable")
- fmt.Println(fmt.Sprintf("%56s", "").ReplaceAll(" ", "="))
-
- // Step 1: Browse templates
- fmt.Println("\n🔍 Step 1: Browsing templates...")
- browseResult, err := tm.browseTemplates(searchQuery)
- if err != nil {
- fmt.Printf("❌ Path B failed: %v\n", err)
- return err
- }
-
- // Step 2: Select first available template
- var selectedTemplate *struct {
- ID string `json:"id"`
- Name string `json:"name"`
- Type string `json:"type"`
- }
-
- for _, item := range browseResult.Data.Results {
- if item.Type == "template" {
- selectedTemplate = &item
- break
- }
- }
-
- if selectedTemplate == nil {
- err := fmt.Errorf("no templates found in browse results")
- fmt.Printf("❌ Path B failed: %v\n", err)
- return err
- }
-
- fmt.Printf("📋 Selected: %s (%s)\n", selectedTemplate.Name, selectedTemplate.ID)
-
- // Step 3: Get template details
- fmt.Println("\n📖 Step 2: Getting template details...")
- templateDetails, err := tm.getTemplateDetails(selectedTemplate.ID)
- if err != nil {
- fmt.Printf("❌ Path B failed: %v\n", err)
- return err
- }
-
- // Step 4: Get PDF preview (optional)
- fmt.Println("\n🖼️ Step 3: Getting PDF preview...")
- pdfPreview, err := tm.getTemplatePDFPreview(selectedTemplate.ID)
- if err != nil {
- fmt.Printf("❌ Path B failed: %v\n", err)
- return err
- }
-
- // Step 5: Generate deliverable
- fmt.Println("\n📝 Step 4: Generating deliverable...")
- deliverable, err := tm.generateDeliverable(templateDetails.Data.Results.ID, deliverableName,
- fmt.Sprintf("Generated from existing template: %s", templateDetails.Data.Results.Name))
- if err != nil {
- fmt.Printf("❌ Path B failed: %v\n", err)
- return err
- }
-
- fmt.Println("\n✅ PATH B COMPLETE!")
- fmt.Printf("Template ID: %s\n", templateDetails.Data.Results.ID)
- fmt.Printf("Deliverable ID: %s\n", deliverable.Data.Results.Deliverable.ID)
- fmt.Printf("PDF Preview: %s\n", pdfPreview)
-
- // Download the generated file
- fmt.Println("\n📥 Step 5: Downloading file...")
- return tm.downloadDeliverable(deliverable.Data.Results.Deliverable.ID,
- deliverable.Data.Results.Deliverable.Name+".docx")
-}
-
-func (tm *TemplateWorkflowManager) browseTemplates(query string) (*BrowseResponse, error) {
- params := url.Values{}
- params.Set("limit", "25")
- params.Set("offset", "0")
- params.Set("showTags", "true")
-
- if query != "" {
- params.Set("query", query)
- }
-
- requestURL := fmt.Sprintf("%s/template-item?%s", BASE_URL, params.Encode())
-
- req, err := http.NewRequest("GET", requestURL, nil)
- if err != nil {
- return nil, fmt.Errorf("failed to create request: %v", err)
- }
-
- req.Header.Set("Authorization", "Bearer "+API_TOKEN)
- req.Header.Set("x-rapiddocx-org-id", ORG_ID)
- req.Header.Set("User-Agent", "TurboDocx API Client")
-
- resp, err := tm.client.Do(req)
- if err != nil {
- return nil, fmt.Errorf("failed to make request: %v", err)
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != http.StatusOK {
- body, _ := io.ReadAll(resp.Body)
- return nil, fmt.Errorf("browse failed: %d - %s", resp.StatusCode, string(body))
- }
-
- body, err := io.ReadAll(resp.Body)
- if err != nil {
- return nil, fmt.Errorf("failed to read response: %v", err)
- }
-
- var result BrowseResponse
- err = json.Unmarshal(body, &result)
- if err != nil {
- return nil, fmt.Errorf("failed to parse JSON: %v", err)
- }
-
- fmt.Printf("🔍 Found %d templates/folders\n", result.Data.TotalRecords)
-
- return &result, nil
-}
-
-func (tm *TemplateWorkflowManager) getTemplateDetails(templateID string) (*TemplateDetailsResponse, error) {
- req, err := http.NewRequest("GET", BASE_URL+"/template/"+templateID, nil)
- if err != nil {
- return nil, fmt.Errorf("failed to create request: %v", err)
- }
-
- req.Header.Set("Authorization", "Bearer "+API_TOKEN)
- req.Header.Set("x-rapiddocx-org-id", ORG_ID)
- req.Header.Set("User-Agent", "TurboDocx API Client")
-
- resp, err := tm.client.Do(req)
- if err != nil {
- return nil, fmt.Errorf("failed to make request: %v", err)
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != http.StatusOK {
- body, _ := io.ReadAll(resp.Body)
- return nil, fmt.Errorf("template details failed: %d - %s", resp.StatusCode, string(body))
- }
-
- body, err := io.ReadAll(resp.Body)
- if err != nil {
- return nil, fmt.Errorf("failed to read response: %v", err)
- }
-
- var result TemplateDetailsResponse
- err = json.Unmarshal(body, &result)
- if err != nil {
- return nil, fmt.Errorf("failed to parse JSON: %v", err)
- }
-
- template := result.Data.Results
- variableCount := 0
- if template.Variables != nil {
- variableCount = len(template.Variables)
- }
- fmt.Printf("📊 Variables: %d\n", variableCount)
-
- defaultFont := template.DefaultFont
- if defaultFont == "" {
- defaultFont = "N/A"
- }
- fmt.Printf("🔤 Default font: %s\n", defaultFont)
-
- return &result, nil
+ return &template, nil
}
-func (tm *TemplateWorkflowManager) getTemplatePDFPreview(templateID string) (string, error) {
- req, err := http.NewRequest("GET", BASE_URL+"/template/"+templateID+"/previewpdflink", nil)
- if err != nil {
- return "", fmt.Errorf("failed to create request: %v", err)
- }
-
- req.Header.Set("Authorization", "Bearer "+API_TOKEN)
- req.Header.Set("x-rapiddocx-org-id", ORG_ID)
- req.Header.Set("User-Agent", "TurboDocx API Client")
-
- resp, err := tm.client.Do(req)
- if err != nil {
- return "", fmt.Errorf("failed to make request: %v", err)
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != http.StatusOK {
- body, _ := io.ReadAll(resp.Body)
- return "", fmt.Errorf("PDF preview failed: %d - %s", resp.StatusCode, string(body))
- }
-
- body, err := io.ReadAll(resp.Body)
- if err != nil {
- return "", fmt.Errorf("failed to read response: %v", err)
- }
-
- var result PDFPreviewResponse
- err = json.Unmarshal(body, &result)
- if err != nil {
- return "", fmt.Errorf("failed to parse JSON: %v", err)
+// Step 2: Generate deliverable with simple variables
+func generateDeliverable(templateID string) (*Deliverable, error) {
+ variables := []Variable{
+ {
+ MimeType: "text",
+ Name: "Company Name",
+ Placeholder: "{CompanyName}",
+ Text: "Acme Corporation",
+ },
+ {
+ MimeType: "text",
+ Name: "Employee Name",
+ Placeholder: "{EmployeeName}",
+ Text: "John Smith",
+ },
+ {
+ MimeType: "text",
+ Name: "Date",
+ Placeholder: "{Date}",
+ Text: "January 15, 2024",
+ },
}
- fmt.Printf("🖼️ PDF Preview available: %s\n", result.Results)
-
- return result.Results, nil
-}
-
-// ===============================
-// COMMON: Generate Deliverable
-// ===============================
-
-func (tm *TemplateWorkflowManager) generateDeliverable(templateID, name, description string) (*DeliverableResponse, error) {
- now := time.Now().UTC().Format(time.RFC3339)
-
payload := map[string]interface{}{
"templateId": templateID,
- "name": name,
- "description": description,
- "variables": []map[string]interface{}{
- {
- "mimeType": "text",
- "name": "Sample Variable",
- "placeholder": "{SampleVariable}",
- "text": "Sample Content from Go Workflow",
- "allowRichTextInjection": 0,
- "autogenerated": false,
- "count": 1,
- "order": 1,
- "subvariables": []interface{}{},
- "metadata": map[string]interface{}{
- "generatedBy": "Go Workflow",
- },
- "aiPrompt": "",
- },
- },
- "tags": []string{"api-generated"},
- "fonts": "[]",
- "defaultFont": "Arial",
- "replaceFonts": true,
- "metadata": map[string]interface{}{
- "sessions": []map[string]interface{}{
- {
- "id": fmt.Sprintf("go-session-%d", time.Now().Unix()),
- "starttime": now,
- "endtime": now,
- },
- },
- "workflow": "Go Complete Workflow",
- "generated": now,
- },
+ "name": "Generated Document",
+ "description": "Simple document example",
+ "variables": variables,
}
jsonData, err := json.Marshal(payload)
if err != nil {
- return nil, fmt.Errorf("failed to marshal JSON: %v", err)
+ return nil, err
}
req, err := http.NewRequest("POST", BASE_URL+"/deliverable", bytes.NewBuffer(jsonData))
if err != nil {
- return nil, fmt.Errorf("failed to create request: %v", err)
+ return nil, err
}
req.Header.Set("Authorization", "Bearer "+API_TOKEN)
@@ -500,51 +155,43 @@ func (tm *TemplateWorkflowManager) generateDeliverable(templateID, name, descrip
req.Header.Set("User-Agent", "TurboDocx API Client")
req.Header.Set("Content-Type", "application/json")
- resp, err := tm.client.Do(req)
+ client := &http.Client{}
+ resp, err := client.Do(req)
if err != nil {
- return nil, fmt.Errorf("failed to make request: %v", err)
+ return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
- body, _ := io.ReadAll(resp.Body)
- return nil, fmt.Errorf("deliverable generation failed: %d - %s", resp.StatusCode, string(body))
- }
-
- body, err := io.ReadAll(resp.Body)
- if err != nil {
- return nil, fmt.Errorf("failed to read response: %v", err)
+ return nil, fmt.Errorf("generation failed: %d", resp.StatusCode)
}
var result DeliverableResponse
- err = json.Unmarshal(body, &result)
- if err != nil {
- return nil, fmt.Errorf("failed to parse JSON: %v", err)
+ if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
+ return nil, err
}
deliverable := result.Data.Results.Deliverable
- fmt.Printf("✅ Generated: %s\n", deliverable.Name)
- fmt.Printf("📄 Created by: %s\n", deliverable.CreatedBy)
- fmt.Printf("📅 Created on: %s\n", deliverable.CreatedOn)
+ fmt.Printf("✅ Document generated: %s (%s)\n", deliverable.Name, deliverable.ID)
- return &result, nil
+ return &deliverable, nil
}
-func (tm *TemplateWorkflowManager) downloadDeliverable(deliverableID, filename string) error {
- fmt.Printf("📥 Downloading file: %s\n", filename)
-
+// Step 3: Download generated file
+func downloadFile(deliverableID, filename string) error {
req, err := http.NewRequest("GET", BASE_URL+"/deliverable/file/"+deliverableID, nil)
if err != nil {
- return fmt.Errorf("failed to create request: %v", err)
+ return err
}
req.Header.Set("Authorization", "Bearer "+API_TOKEN)
req.Header.Set("x-rapiddocx-org-id", ORG_ID)
req.Header.Set("User-Agent", "TurboDocx API Client")
- resp, err := tm.client.Do(req)
+ client := &http.Client{}
+ resp, err := client.Do(req)
if err != nil {
- return fmt.Errorf("failed to make request: %v", err)
+ return err
}
defer resp.Body.Close()
@@ -554,60 +201,57 @@ func (tm *TemplateWorkflowManager) downloadDeliverable(deliverableID, filename s
fmt.Printf("✅ File ready for download: %s\n", filename)
- contentType := resp.Header.Get("Content-Type")
- if contentType == "" {
- contentType = "N/A"
- }
-
- contentLength := resp.Header.Get("Content-Length")
- if contentLength == "" {
- contentLength = "N/A"
- }
-
- fmt.Printf("📁 Content-Type: %s\n", contentType)
- fmt.Printf("📊 Content-Length: %s bytes\n", contentLength)
+ // In a real application, you would save the file:
+ // file, err := os.Create(filename)
+ // if err != nil {
+ // return err
+ // }
+ // defer file.Close()
+ // _, err = io.Copy(file, resp.Body)
return nil
}
-// ===============================
-// DEMO FUNCTIONS
-// ===============================
-
-func (tm *TemplateWorkflowManager) DemoPathA(templateFilePath string) error {
- fmt.Println("🚀 DEMO: Path A - Upload New Template Workflow")
- fmt.Println(fmt.Sprintf("%45s", "").ReplaceAll(" ", "="))
- fmt.Println()
-
- return tm.PathA_UploadAndGenerate(templateFilePath, "Contract Generated via Path A - API Upload")
-}
-
-func (tm *TemplateWorkflowManager) DemoPathB() error {
- fmt.Println("🚀 DEMO: Path B - Browse Existing Template Workflow")
- fmt.Println(fmt.Sprintf("%51s", "").ReplaceAll(" ", "="))
- fmt.Println()
+// Complete workflow: Upload → Generate → Download
+func completeWorkflow(templateFilePath string) error {
+ fmt.Println("🚀 Starting complete workflow...")
- return tm.PathB_BrowseAndGenerate("contract", "Contract Generated via Path B - Browse & Select")
-}
-
-func (tm *TemplateWorkflowManager) DemoComparison() error {
- fmt.Println("🚀 DEMO: Complete Workflow Comparison")
- fmt.Println(fmt.Sprintf("%36s", "").ReplaceAll(" ", "="))
- fmt.Println()
-
- fmt.Println("Testing both paths with the same template type...\n")
+ // Step 1: Upload template
+ fmt.Println("\n📤 Step 1: Uploading template...")
+ template, err := uploadTemplate(templateFilePath)
+ if err != nil {
+ return fmt.Errorf("upload failed: %w", err)
+ }
- // Run Path B first (browse existing)
- err := tm.DemoPathB()
+ // Step 2: Generate deliverable
+ fmt.Println("\n📝 Step 2: Generating document...")
+ deliverable, err := generateDeliverable(template.ID)
if err != nil {
- return fmt.Errorf("demo comparison failed: %v", err)
+ return fmt.Errorf("generation failed: %w", err)
}
- fmt.Println("\n" + fmt.Sprintf("%60s", "").ReplaceAll(" ", "=") + "\n")
+ // Step 3: Download file
+ fmt.Println("\n📥 Step 3: Downloading file...")
+ filename := deliverable.Name + ".docx"
+ if err := downloadFile(deliverable.ID, filename); err != nil {
+ return fmt.Errorf("download failed: %w", err)
+ }
- // For Path A, we'd need a template file
- fmt.Println("📝 Path A requires a template file to upload.")
- fmt.Println(" Example: workflow.DemoPathA(\"./contract-template.docx\")")
+ fmt.Println("\n✅ Workflow complete!")
+ fmt.Printf("Template: %s\n", template.ID)
+ fmt.Printf("Document: %s\n", deliverable.ID)
+ fmt.Printf("File: %s\n", filename)
return nil
+}
+
+// Example usage
+func main() {
+ // Replace with your template file path
+ templatePath := "./template.docx"
+
+ if err := completeWorkflow(templatePath); err != nil {
+ fmt.Printf("❌ Workflow failed: %v\n", err)
+ os.Exit(1)
+ }
}
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/java.java b/static/scripts/templates/api/complete-workflows/java.java
index ea457f2..8decb86 100644
--- a/static/scripts/templates/api/complete-workflows/java.java
+++ b/static/scripts/templates/api/complete-workflows/java.java
@@ -2,18 +2,15 @@
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
-import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
-import java.time.Instant;
-import java.util.UUID;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
/**
- * Complete Template Generation Workflows
- * Demonstrates both Path A (Upload) and Path B (Browse/Select) followed by generation
+ * Complete Workflow: Upload → Generate → Download
+ * Simple 3-step process for document generation
*/
public class TemplateWorkflowManager {
// Configuration - Update these values
@@ -29,104 +26,43 @@ public TemplateWorkflowManager() {
this.mapper = new ObjectMapper();
}
- public static void main(String[] args) throws Exception {
- TemplateWorkflowManager workflow = new TemplateWorkflowManager();
+ // Step 1: Upload template file
+ public JsonNode uploadTemplate(String templateFilePath) throws Exception {
+ String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
+ byte[] templateBytes = Files.readAllBytes(Paths.get(templateFilePath));
- try {
- // Demo Path B (Browse existing templates)
- workflow.demoPathB();
-
- // Uncomment to demo Path A (requires template file):
- // workflow.demoPathA("./path/to/your/template.docx");
-
- // Uncomment to run full comparison:
- // workflow.demoComparison();
-
- } catch (Exception e) {
- System.err.println("Workflow demo failed: " + e.getMessage());
- e.printStackTrace();
- }
- }
-
- // ===============================
- // PATH A: Upload New Template
- // ===============================
-
- /**
- * Complete Path A workflow: Upload → Generate
- */
- public TemplateWorkflowResult pathA_UploadAndGenerate(String templateFilePath, String deliverableName) throws Exception {
- System.out.println("🔄 PATH A: Upload New Template → Generate Deliverable");
- System.out.println("=".repeat(48));
-
- try {
- // Step 1: Upload and create template
- System.out.println("\n📤 Step 1: Uploading template...");
- JsonNode template = uploadTemplate(templateFilePath);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8), true);
- // Step 2: Generate deliverable using uploaded template
- System.out.println("\n📝 Step 2: Generating deliverable...");
- JsonNode deliverable = generateDeliverable(template.get("id").asText(),
- createDeliverableData(deliverableName, "Generated from uploaded template: " + template.get("name").asText()));
+ // Add template file
+ writer.append("--" + boundary).append("\r\n");
+ writer.append("Content-Disposition: form-data; name=\"templateFile\"; filename=\"template.docx\"").append("\r\n");
+ writer.append("Content-Type: application/octet-stream").append("\r\n\r\n");
+ writer.flush();
+ outputStream.write(templateBytes);
+ writer.append("\r\n");
- System.out.println("\n✅ PATH A COMPLETE!");
- System.out.println("Template ID: " + template.get("id").asText());
- System.out.println("Deliverable ID: " + deliverable.get("id").asText());
+ // Add name field
+ writer.append("--" + boundary).append("\r\n");
+ writer.append("Content-Disposition: form-data; name=\"name\"").append("\r\n\r\n");
+ writer.append("Simple Template").append("\r\n");
- // Download the generated file
- downloadDeliverable(deliverable.get("id").asText(), deliverable.get("name").asText() + ".docx");
+ // Add description field
+ writer.append("--" + boundary).append("\r\n");
+ writer.append("Content-Disposition: form-data; name=\"description\"").append("\r\n\r\n");
+ writer.append("Template uploaded for document generation").append("\r\n");
- return new TemplateWorkflowResult(template, deliverable, null);
-
- } catch (Exception e) {
- System.err.println("❌ Path A failed: " + e.getMessage());
- throw e;
- }
- }
-
- private JsonNode uploadTemplate(String templateFilePath) throws Exception {
- Path filePath = Paths.get(templateFilePath);
- if (!Files.exists(filePath)) {
- throw new FileNotFoundException("Template file not found: " + templateFilePath);
- }
-
- String boundary = "----JavaBoundary" + System.currentTimeMillis();
- byte[] fileBytes = Files.readAllBytes(filePath);
-
- // Build multipart form data
- StringBuilder formData = new StringBuilder();
- formData.append("--").append(boundary).append("\r\n");
- formData.append("Content-Disposition: form-data; name=\"templateFile\"; filename=\"")
- .append(filePath.getFileName().toString()).append("\"\r\n");
- formData.append("Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document\r\n\r\n");
-
- String additionalFields = "\r\n--" + boundary + "\r\n" +
- "Content-Disposition: form-data; name=\"name\"\r\n\r\n" +
- "API Upload Template" +
- "\r\n--" + boundary + "\r\n" +
- "Content-Disposition: form-data; name=\"description\"\r\n\r\n" +
- "Template uploaded via API for testing" +
- "\r\n--" + boundary + "\r\n" +
- "Content-Disposition: form-data; name=\"variables\"\r\n\r\n" +
- "[]" +
- "\r\n--" + boundary + "\r\n" +
- "Content-Disposition: form-data; name=\"tags\"\r\n\r\n" +
- "[\"api\", \"test\", \"upload\"]" +
- "\r\n--" + boundary + "--\r\n";
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- baos.write(formData.toString().getBytes());
- baos.write(fileBytes);
- baos.write(additionalFields.getBytes());
+ writer.append("--" + boundary + "--").append("\r\n");
+ writer.close();
HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(BASE_URL + "/template/upload-and-create"))
- .header("Authorization", "Bearer " + API_TOKEN)
- .header("x-rapiddocx-org-id", ORG_ID)
- .header("User-Agent", "TurboDocx API Client")
- .header("Content-Type", "multipart/form-data; boundary=" + boundary)
- .POST(HttpRequest.BodyPublishers.ofByteArray(baos.toByteArray()))
- .build();
+ .uri(URI.create(BASE_URL + "/template/upload-and-create"))
+ .header("Authorization", "Bearer " + API_TOKEN)
+ .header("x-rapiddocx-org-id", ORG_ID)
+ .header("User-Agent", "TurboDocx API Client")
+ .header("Content-Type", "multipart/form-data; boundary=" + boundary)
+ .POST(HttpRequest.BodyPublishers.ofByteArray(outputStream.toByteArray()))
+ .build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
@@ -137,341 +73,124 @@ private JsonNode uploadTemplate(String templateFilePath) throws Exception {
JsonNode result = mapper.readTree(response.body());
JsonNode template = result.get("data").get("results").get("template");
- System.out.println("✅ Template uploaded: " + template.get("name").asText() + " (" + template.get("id").asText() + ")");
-
- JsonNode variables = template.get("variables");
- int variableCount = (variables != null && !variables.isNull()) ? variables.size() : 0;
- System.out.println("📊 Variables extracted: " + variableCount);
-
- System.out.println("🔤 Default font: " + template.get("defaultFont").asText());
-
- JsonNode fonts = template.get("fonts");
- int fontCount = (fonts != null && !fonts.isNull()) ? fonts.size() : 0;
- System.out.println("📝 Fonts used: " + fontCount);
-
- return template;
- }
-
- // ===============================
- // PATH B: Browse and Select
- // ===============================
-
- /**
- * Complete Path B workflow: Browse → Select → Generate
- */
- public TemplateWorkflowResult pathB_BrowseAndGenerate(String searchQuery, String deliverableName) throws Exception {
- System.out.println("🔍 PATH B: Browse Existing Templates → Generate Deliverable");
- System.out.println("=".repeat(56));
-
- try {
- // Step 1: Browse templates
- System.out.println("\n🔍 Step 1: Browsing templates...");
- JsonNode browseResult = browseTemplates(searchQuery);
-
- // Step 2: Select first available template
- JsonNode selectedTemplate = null;
- for (JsonNode item : browseResult.get("results")) {
- if ("template".equals(item.get("type").asText())) {
- selectedTemplate = item;
- break;
- }
- }
-
- if (selectedTemplate == null) {
- throw new RuntimeException("No templates found in browse results");
- }
-
- System.out.println("📋 Selected: " + selectedTemplate.get("name").asText() +
- " (" + selectedTemplate.get("id").asText() + ")");
-
- // Step 3: Get template details
- System.out.println("\n📖 Step 2: Getting template details...");
- JsonNode templateDetails = getTemplateDetails(selectedTemplate.get("id").asText());
-
- // Step 4: Get PDF preview (optional)
- System.out.println("\n🖼️ Step 3: Getting PDF preview...");
- String pdfPreview = getTemplatePDFPreview(selectedTemplate.get("id").asText());
-
- // Step 5: Generate deliverable
- System.out.println("\n📝 Step 4: Generating deliverable...");
- JsonNode deliverable = generateDeliverable(templateDetails.get("id").asText(),
- createDeliverableData(deliverableName, "Generated from existing template: " + templateDetails.get("name").asText()));
-
- System.out.println("\n✅ PATH B COMPLETE!");
- System.out.println("Template ID: " + templateDetails.get("id").asText());
- System.out.println("Deliverable ID: " + deliverable.get("id").asText());
- System.out.println("PDF Preview: " + pdfPreview);
-
- // Download the generated file
- System.out.println("\n📥 Step 5: Downloading file...");
- downloadDeliverable(deliverable.get("id").asText(), deliverable.get("name").asText() + ".docx");
-
- return new TemplateWorkflowResult(templateDetails, deliverable, pdfPreview);
-
- } catch (Exception e) {
- System.err.println("❌ Path B failed: " + e.getMessage());
- throw e;
- }
- }
-
- private JsonNode browseTemplates(String query) throws Exception {
- StringBuilder params = new StringBuilder();
- params.append("limit=25&offset=0&showTags=true");
-
- if (query != null && !query.isEmpty()) {
- params.append("&query=").append(URLEncoder.encode(query, StandardCharsets.UTF_8));
- }
-
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(BASE_URL + "/template-item?" + params.toString()))
- .header("Authorization", "Bearer " + API_TOKEN)
- .header("x-rapiddocx-org-id", ORG_ID)
- .header("User-Agent", "TurboDocx API Client")
- .GET()
- .build();
-
- HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
-
- if (response.statusCode() != 200) {
- throw new RuntimeException("Browse failed: " + response.statusCode());
- }
-
- JsonNode result = mapper.readTree(response.body());
- JsonNode data = result.get("data");
-
- System.out.println("🔍 Found " + data.get("totalRecords").asInt() + " templates/folders");
-
- return data;
- }
-
- private JsonNode getTemplateDetails(String templateId) throws Exception {
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(BASE_URL + "/template/" + templateId))
- .header("Authorization", "Bearer " + API_TOKEN)
- .header("x-rapiddocx-org-id", ORG_ID)
- .header("User-Agent", "TurboDocx API Client")
- .GET()
- .build();
-
- HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
-
- if (response.statusCode() != 200) {
- throw new RuntimeException("Template details failed: " + response.statusCode());
- }
-
- JsonNode result = mapper.readTree(response.body());
- JsonNode template = result.get("data").get("results");
-
- JsonNode variables = template.get("variables");
- int variableCount = (variables != null && !variables.isNull()) ? variables.size() : 0;
- System.out.println("📊 Variables: " + variableCount);
-
- String defaultFont = template.has("defaultFont") ? template.get("defaultFont").asText() : "N/A";
- System.out.println("🔤 Default font: " + defaultFont);
+ System.out.printf("✅ Template uploaded: %s (%s)%n",
+ template.get("name").asText(), template.get("id").asText());
return template;
}
- private String getTemplatePDFPreview(String templateId) throws Exception {
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(BASE_URL + "/template/" + templateId + "/previewpdflink"))
- .header("Authorization", "Bearer " + API_TOKEN)
- .header("x-rapiddocx-org-id", ORG_ID)
- .header("User-Agent", "TurboDocx API Client")
- .GET()
- .build();
-
- HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
-
- if (response.statusCode() != 200) {
- throw new RuntimeException("PDF preview failed: " + response.statusCode());
- }
-
- JsonNode result = mapper.readTree(response.body());
- String pdfUrl = result.get("results").asText();
-
- System.out.println("🖼️ PDF Preview available: " + pdfUrl);
-
- return pdfUrl;
- }
+ // Step 2: Generate deliverable with simple variables
+ public JsonNode generateDeliverable(String templateId) throws Exception {
+ ArrayNode variables = mapper.createArrayNode();
- // ===============================
- // COMMON: Generate Deliverable
- // ===============================
+ ObjectNode companyVar = mapper.createObjectNode();
+ companyVar.put("mimeType", "text");
+ companyVar.put("name", "Company Name");
+ companyVar.put("placeholder", "{CompanyName}");
+ companyVar.put("text", "Acme Corporation");
+ variables.add(companyVar);
+
+ ObjectNode employeeVar = mapper.createObjectNode();
+ employeeVar.put("mimeType", "text");
+ employeeVar.put("name", "Employee Name");
+ employeeVar.put("placeholder", "{EmployeeName}");
+ employeeVar.put("text", "John Smith");
+ variables.add(employeeVar);
+
+ ObjectNode dateVar = mapper.createObjectNode();
+ dateVar.put("mimeType", "text");
+ dateVar.put("name", "Date");
+ dateVar.put("placeholder", "{Date}");
+ dateVar.put("text", "January 15, 2024");
+ variables.add(dateVar);
- private JsonNode generateDeliverable(String templateId, ObjectNode deliverableData) throws Exception {
ObjectNode payload = mapper.createObjectNode();
payload.put("templateId", templateId);
- payload.put("name", deliverableData.get("name").asText());
- payload.put("description", deliverableData.get("description").asText());
- payload.set("variables", deliverableData.get("variables"));
- payload.set("tags", deliverableData.get("tags"));
- payload.put("fonts", "[]");
- payload.put("defaultFont", "Arial");
- payload.put("replaceFonts", true);
- payload.set("metadata", createMetadata());
-
- String jsonBody = mapper.writeValueAsString(payload);
+ payload.put("name", "Generated Document");
+ payload.put("description", "Simple document example");
+ payload.set("variables", variables);
HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(BASE_URL + "/deliverable"))
- .header("Authorization", "Bearer " + API_TOKEN)
- .header("x-rapiddocx-org-id", ORG_ID)
- .header("User-Agent", "TurboDocx API Client")
- .header("Content-Type", "application/json")
- .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
- .build();
+ .uri(URI.create(BASE_URL + "/deliverable"))
+ .header("Authorization", "Bearer " + API_TOKEN)
+ .header("x-rapiddocx-org-id", ORG_ID)
+ .header("User-Agent", "TurboDocx API Client")
+ .header("Content-Type", "application/json")
+ .POST(HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(payload)))
+ .build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
- throw new RuntimeException("Deliverable generation failed: " + response.statusCode() + " - " + response.body());
+ throw new RuntimeException("Generation failed: " + response.statusCode());
}
JsonNode result = mapper.readTree(response.body());
JsonNode deliverable = result.get("data").get("results").get("deliverable");
- System.out.println("✅ Generated: " + deliverable.get("name").asText());
- System.out.println("📄 Created by: " + deliverable.get("createdBy").asText());
- System.out.println("📅 Created on: " + deliverable.get("createdOn").asText());
+ System.out.printf("✅ Document generated: %s (%s)%n",
+ deliverable.get("name").asText(), deliverable.get("id").asText());
return deliverable;
}
- private void downloadDeliverable(String deliverableId, String filename) throws Exception {
- System.out.println("📥 Downloading file: " + filename);
-
+ // Step 3: Download generated file
+ public void downloadFile(String deliverableId, String filename) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(BASE_URL + "/deliverable/file/" + deliverableId))
- .header("Authorization", "Bearer " + API_TOKEN)
- .header("x-rapiddocx-org-id", ORG_ID)
- .header("User-Agent", "TurboDocx API Client")
- .GET()
- .build();
+ .uri(URI.create(BASE_URL + "/deliverable/file/" + deliverableId))
+ .header("Authorization", "Bearer " + API_TOKEN)
+ .header("x-rapiddocx-org-id", ORG_ID)
+ .header("User-Agent", "TurboDocx API Client")
+ .GET()
+ .build();
- HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
if (response.statusCode() != 200) {
throw new RuntimeException("Download failed: " + response.statusCode());
}
- System.out.println("✅ File ready for download: " + filename);
- String contentType = response.headers().firstValue("content-type").orElse("N/A");
- String contentLength = response.headers().firstValue("content-length").orElse("N/A");
- System.out.println("📁 Content-Type: " + contentType);
- System.out.println("📊 Content-Length: " + contentLength + " bytes");
- }
-
- // ===============================
- // UTILITY FUNCTIONS
- // ===============================
-
- private ObjectNode createDeliverableData(String name, String description) {
- ObjectNode data = mapper.createObjectNode();
- data.put("name", name);
- data.put("description", description);
- data.set("variables", createSampleVariables());
-
- ArrayNode tags = mapper.createArrayNode();
- tags.add("api-generated");
- data.set("tags", tags);
-
- return data;
- }
-
- private ArrayNode createSampleVariables() {
- ArrayNode variables = mapper.createArrayNode();
-
- ObjectNode variable = mapper.createObjectNode();
- variable.put("mimeType", "text");
- variable.put("name", "Sample Variable");
- variable.put("placeholder", "{SampleVariable}");
- variable.put("text", "Sample Content from Java Workflow");
- variable.put("allowRichTextInjection", 0);
- variable.put("autogenerated", false);
- variable.put("count", 1);
- variable.put("order", 1);
- variable.set("subvariables", mapper.createArrayNode());
-
- ObjectNode metadata = mapper.createObjectNode();
- metadata.put("generatedBy", "Java Workflow");
- variable.set("metadata", metadata);
-
- variable.put("aiPrompt", "");
-
- variables.add(variable);
- return variables;
- }
-
- private ObjectNode createMetadata() {
- ObjectNode metadata = mapper.createObjectNode();
-
- ArrayNode sessions = mapper.createArrayNode();
- ObjectNode session = mapper.createObjectNode();
- session.put("id", UUID.randomUUID().toString());
- session.put("starttime", Instant.now().toString());
- session.put("endtime", Instant.now().toString());
- sessions.add(session);
-
- metadata.set("sessions", sessions);
- metadata.put("workflow", "Java Complete Workflow");
- metadata.put("generated", Instant.now().toString());
+ System.out.printf("✅ File ready for download: %s%n", filename);
- return metadata;
+ // In a real application, you would save the file:
+ // Files.write(Paths.get(filename), response.body());
}
- // ===============================
- // DEMO FUNCTIONS
- // ===============================
+ // Complete workflow: Upload → Generate → Download
+ public void completeWorkflow(String templateFilePath) throws Exception {
+ System.out.println("🚀 Starting complete workflow...");
- public TemplateWorkflowResult demoPathA(String templateFilePath) throws Exception {
- System.out.println("🚀 DEMO: Path A - Upload New Template Workflow");
- System.out.println("=".repeat(45));
- System.out.println();
+ // Step 1: Upload template
+ System.out.println("\n📤 Step 1: Uploading template...");
+ JsonNode template = uploadTemplate(templateFilePath);
- return pathA_UploadAndGenerate(templateFilePath, "Contract Generated via Path A - API Upload");
- }
+ // Step 2: Generate deliverable
+ System.out.println("\n📝 Step 2: Generating document...");
+ JsonNode deliverable = generateDeliverable(template.get("id").asText());
- public TemplateWorkflowResult demoPathB() throws Exception {
- System.out.println("🚀 DEMO: Path B - Browse Existing Template Workflow");
- System.out.println("=".repeat(51));
- System.out.println();
+ // Step 3: Download file
+ System.out.println("\n📥 Step 3: Downloading file...");
+ String filename = deliverable.get("name").asText() + ".docx";
+ downloadFile(deliverable.get("id").asText(), filename);
- return pathB_BrowseAndGenerate("contract", "Contract Generated via Path B - Browse & Select");
+ System.out.println("\n✅ Workflow complete!");
+ System.out.printf("Template: %s%n", template.get("id").asText());
+ System.out.printf("Document: %s%n", deliverable.get("id").asText());
+ System.out.printf("File: %s%n", filename);
}
- public void demoComparison() throws Exception {
- System.out.println("🚀 DEMO: Complete Workflow Comparison");
- System.out.println("=".repeat(36));
- System.out.println();
-
+ // Example usage
+ public static void main(String[] args) {
try {
- System.out.println("Testing both paths with the same template type...\\n");
-
- // Run Path B first (browse existing)
- TemplateWorkflowResult pathBResult = demoPathB();
+ TemplateWorkflowManager manager = new TemplateWorkflowManager();
- System.out.println("\\n" + "=".repeat(60) + "\\n");
-
- // For Path A, we'd need a template file
- System.out.println("📝 Path A requires a template file to upload.");
- System.out.println(" Example: workflow.demoPathA(\"./contract-template.docx\")");
+ // Replace with your template file path
+ String templatePath = "./template.docx";
+ manager.completeWorkflow(templatePath);
} catch (Exception e) {
- System.err.println("Demo comparison failed: " + e.getMessage());
- }
- }
-
- // Result container class
- public static class TemplateWorkflowResult {
- public final JsonNode template;
- public final JsonNode deliverable;
- public final String pdfPreview;
-
- public TemplateWorkflowResult(JsonNode template, JsonNode deliverable, String pdfPreview) {
- this.template = template;
- this.deliverable = deliverable;
- this.pdfPreview = pdfPreview;
+ System.err.printf("❌ Workflow failed: %s%n", e.getMessage());
+ e.printStackTrace();
}
}
}
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/nodejs/express.js b/static/scripts/templates/api/complete-workflows/nodejs/express.js
index fa6539e..f8dfcf8 100644
--- a/static/scripts/templates/api/complete-workflows/nodejs/express.js
+++ b/static/scripts/templates/api/complete-workflows/nodejs/express.js
@@ -8,429 +8,169 @@ const ORG_ID = "YOUR_ORGANIZATION_ID";
const BASE_URL = "https://api.turbodocx.com";
/**
- * Complete Template Generation Workflows
- * Demonstrates both Path A (Upload) and Path B (Browse/Select) followed by generation
+ * Complete Workflow: Upload → Generate → Download
+ * Simple 3-step process for document generation
*/
-class TemplateWorkflowManager {
- constructor(apiToken, orgId, baseUrl) {
- this.apiToken = apiToken;
- this.orgId = orgId;
- this.baseUrl = baseUrl;
- this.headers = {
- 'Authorization': `Bearer ${apiToken}`,
- 'x-rapiddocx-org-id': orgId,
- 'User-Agent': 'TurboDocx API Client'
- };
- }
-
- // ===============================
- // PATH A: Upload New Template
- // ===============================
-
- async pathA_UploadAndGenerate(templateFilePath, deliverableName) {
- console.log('🔄 PATH A: Upload New Template → Generate Deliverable');
- console.log('================================');
-
- try {
- // Step 1: Upload and create template
- console.log('\n📤 Step 1: Uploading template...');
- const template = await this.uploadTemplate(templateFilePath);
-
- // Step 2: Generate deliverable using uploaded template
- console.log('\n📝 Step 2: Generating deliverable...');
- const deliverable = await this.generateDeliverable(template.id, {
- name: deliverableName,
- description: `Generated from uploaded template: ${template.name}`,
- variables: this.createVariablesFromTemplate(template.variables)
- });
-
- console.log('\n✅ PATH A COMPLETE!');
- console.log(`Template ID: ${template.id}`);
- console.log(`Deliverable ID: ${deliverable.id}`);
-
- // Download the generated file
- await this.downloadDeliverable(deliverable.id, `${deliverable.name}.docx`);
-
- return { template, deliverable };
-
- } catch (error) {
- console.error('❌ Path A failed:', error.message);
- throw error;
- }
- }
-
- async uploadTemplate(templateFilePath) {
- const formData = new FormData();
- formData.append('templateFile', fs.createReadStream(templateFilePath));
- formData.append('name', 'API Upload Template');
- formData.append('description', 'Template uploaded via API for testing');
- formData.append('variables', '[]');
- formData.append('tags', '["api", "test", "upload"]');
-
- const response = await fetch(`${this.baseUrl}/template/upload-and-create`, {
- method: 'POST',
- headers: {
- ...this.headers,
- ...formData.getHeaders()
- },
- body: formData
- });
-
- if (!response.ok) {
- throw new Error(`Upload failed: ${response.status}`);
- }
-
- const result = await response.json();
- const template = result.data.results.template;
-
- console.log(`✅ Template uploaded: ${template.name} (${template.id})`);
- console.log(`📊 Variables extracted: ${template.variables ? template.variables.length : 0}`);
- console.log(`🔤 Default font: ${template.defaultFont}`);
- console.log(`📝 Fonts used: ${template.fonts ? template.fonts.length : 0}`);
-
- return template;
- }
-
- // ===============================
- // PATH B: Browse and Select
- // ===============================
-
- async pathB_BrowseAndGenerate(searchQuery, deliverableName) {
- console.log('🔍 PATH B: Browse Existing Templates → Generate Deliverable');
- console.log('==================================================');
-
- try {
- // Step 1: Browse templates
- console.log('\n🔍 Step 1: Browsing templates...');
- const browseResult = await this.browseTemplates({ query: searchQuery });
-
- // Step 2: Select first available template
- const selectedTemplate = browseResult.results.find(item => item.type === 'template');
- if (!selectedTemplate) {
- throw new Error('No templates found in browse results');
- }
-
- console.log(`📋 Selected: ${selectedTemplate.name} (${selectedTemplate.id})`);
-
- // Step 3: Get template details
- console.log('\n📖 Step 2: Getting template details...');
- const templateDetails = await this.getTemplateDetails(selectedTemplate.id);
-
- // Step 4: Get PDF preview (optional)
- console.log('\n🖼️ Step 3: Getting PDF preview...');
- const pdfPreview = await this.getTemplatePDFPreview(selectedTemplate.id);
-
- // Step 5: Generate deliverable
- console.log('\n📝 Step 4: Generating deliverable...');
- const deliverable = await this.generateDeliverable(templateDetails.id, {
- name: deliverableName,
- description: `Generated from existing template: ${templateDetails.name}`,
- variables: this.createVariablesFromTemplate(templateDetails.variables)
- });
-
- console.log('\n✅ PATH B COMPLETE!');
- console.log(`Template ID: ${templateDetails.id}`);
- console.log(`Deliverable ID: ${deliverable.id}`);
-
- // Download the generated file
- await this.downloadDeliverable(deliverable.id, `${deliverable.name}.docx`);
-
- return { template: templateDetails, deliverable, pdfPreview };
-
- } catch (error) {
- console.error('❌ Path B failed:', error.message);
- throw error;
- }
- }
-
- async browseTemplates(options = {}) {
- const {
- limit = 25,
- offset = 0,
- query = '',
- showTags = true
- } = options;
-
- const params = new URLSearchParams({
- limit: limit.toString(),
- offset: offset.toString(),
- showTags: showTags.toString()
- });
-
- if (query) params.append('query', query);
-
- const response = await fetch(`${this.baseUrl}/template-item?${params.toString()}`, {
- method: 'GET',
- headers: this.headers
- });
-
- if (!response.ok) {
- throw new Error(`Browse failed: ${response.status}`);
- }
-
- const result = await response.json();
- console.log(`🔍 Found ${result.data.totalRecords} templates/folders`);
-
- return result.data;
- }
-
- async getTemplateDetails(templateId) {
- const response = await fetch(`${this.baseUrl}/template/${templateId}`, {
- method: 'GET',
- headers: this.headers
- });
-
- if (!response.ok) {
- throw new Error(`Template details failed: ${response.status}`);
- }
-
- const result = await response.json();
- const template = result.data.results;
-
- console.log(`📊 Variables: ${template.variables.length}`);
- console.log(`🔤 Default font: ${template.defaultFont || 'N/A'}`);
-
- return template;
- }
-
- async getTemplatePDFPreview(templateId) {
- const response = await fetch(`${this.baseUrl}/template/${templateId}/previewpdflink`, {
- method: 'GET',
- headers: this.headers
- });
-
- if (!response.ok) {
- throw new Error(`PDF preview failed: ${response.status}`);
- }
-
- const result = await response.json();
- console.log(`🖼️ PDF Preview available: ${result.results}`);
-
- return result.results;
- }
-
- // ===============================
- // COMMON: Generate Deliverable
- // ===============================
-
- async generateDeliverable(templateId, deliverableData) {
- const payload = {
- templateId: templateId,
- name: deliverableData.name,
- description: deliverableData.description || '',
- variables: deliverableData.variables,
- tags: deliverableData.tags || ['api-generated'],
- fonts: deliverableData.fonts || '[]',
- defaultFont: deliverableData.defaultFont || 'Arial',
- replaceFonts: deliverableData.replaceFonts !== undefined ? deliverableData.replaceFonts : true,
- metadata: deliverableData.metadata || {
- sessions: [{
- id: this.generateSessionId(),
- starttime: new Date().toISOString(),
- endtime: new Date().toISOString()
- }],
- workflow: 'API Complete Workflow',
- generated: new Date().toISOString()
- }
- };
-
- const response = await fetch(`${this.baseUrl}/deliverable`, {
- method: 'POST',
- headers: {
- ...this.headers,
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify(payload)
- });
-
- if (!response.ok) {
- const errorText = await response.text();
- throw new Error(`Deliverable generation failed: ${response.status} - ${errorText}`);
- }
-
- const result = await response.json();
- const deliverable = result.data.results.deliverable;
-
- console.log(`✅ Generated: ${deliverable.name}`);
- console.log(`📄 Created by: ${deliverable.createdBy}`);
- console.log(`📅 Created on: ${deliverable.createdOn}`);
-
- return deliverable;
- }
-
- // ===============================
- // UTILITY FUNCTIONS
- // ===============================
-
- createVariablesFromTemplate(templateVariables) {
- return templateVariables.map((variable, index) => ({
- mimeType: variable.mimeType || "text",
- name: variable.name,
- placeholder: variable.placeholder,
- text: this.generateSampleText(variable.name),
- allowRichTextInjection: variable.allowRichTextInjection || 0,
- autogenerated: false,
- count: 1,
- order: index + 1,
- subvariables: this.createSampleSubvariables(variable.placeholder),
- metadata: {
- generatedBy: "API Workflow",
- variableType: variable.mimeType || "text"
- },
- aiPrompt: `Generate appropriate content for ${variable.name}`
- }));
- }
-
- generateSampleText(variableName) {
- const sampleData = {
- 'Company': 'TechCorp Solutions Inc.',
- 'Employee': 'John Smith',
- 'Date': new Date().toLocaleDateString(),
- 'Title': 'Senior Software Engineer',
- 'Department': 'Engineering',
- 'Salary': '$95,000',
- 'Address': '123 Main Street, Tech City, TC 12345',
- 'Phone': '(555) 123-4567',
- 'Email': 'john.smith@techcorp.com'
- };
-
- // Find matching sample data or generate generic text
- for (const [key, value] of Object.entries(sampleData)) {
- if (variableName.toLowerCase().includes(key.toLowerCase())) {
- return value;
- }
- }
-
- return `Sample ${variableName} Content`;
- }
+// Step 1: Upload template file
+async function uploadTemplate(templateFilePath) {
+ const formData = new FormData();
+ formData.append('templateFile', fs.createReadStream(templateFilePath));
+ formData.append('name', 'Simple Template');
+ formData.append('description', 'Template uploaded for document generation');
+
+ const response = await fetch(`${BASE_URL}/template/upload-and-create`, {
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${API_TOKEN}`,
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client',
+ ...formData.getHeaders()
+ },
+ body: formData
+ });
+
+ if (!response.ok) {
+ throw new Error(`Upload failed: ${response.status}`);
+ }
+
+ const result = await response.json();
+ const template = result.data.results.template;
+
+ console.log(`✅ Template uploaded: ${template.name} (${template.id})`);
+ return template;
+}
- createSampleSubvariables(placeholder) {
- // Create relevant subvariables based on placeholder name
- if (placeholder.toLowerCase().includes('employee')) {
- return [
- { placeholder: "{Employee.Title}", text: "Senior Software Engineer" },
- { placeholder: "{Employee.StartDate}", text: new Date().toLocaleDateString() }
- ];
- } else if (placeholder.toLowerCase().includes('company')) {
- return [
- { placeholder: "{Company.Address}", text: "123 Main Street, Tech City, TC 12345" },
- { placeholder: "{Company.Phone}", text: "(555) 123-4567" }
- ];
+// Step 2: Generate deliverable with simple variables
+async function generateDeliverable(templateId) {
+ const variables = [
+ {
+ mimeType: "text",
+ name: "Company Name",
+ placeholder: "{CompanyName}",
+ text: "Acme Corporation"
+ },
+ {
+ mimeType: "text",
+ name: "Employee Name",
+ placeholder: "{EmployeeName}",
+ text: "John Smith"
+ },
+ {
+ mimeType: "text",
+ name: "Date",
+ placeholder: "{Date}",
+ text: "January 15, 2024"
}
+ ];
+
+ const payload = {
+ templateId: templateId,
+ name: "Generated Document",
+ description: "Simple document example",
+ variables: variables
+ };
+
+ const response = await fetch(`${BASE_URL}/deliverable`, {
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${API_TOKEN}`,
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(payload)
+ });
+
+ if (!response.ok) {
+ throw new Error(`Generation failed: ${response.status}`);
+ }
+
+ const result = await response.json();
+ const deliverable = result.data.results.deliverable;
+
+ console.log(`✅ Document generated: ${deliverable.name} (${deliverable.id})`);
+ return deliverable;
+}
- return [];
- }
-
- generateSessionId() {
- return Math.random().toString(36).substr(2, 9) + '-' +
- Math.random().toString(36).substr(2, 9) + '-' +
- Math.random().toString(36).substr(2, 9);
- }
-
- async downloadDeliverable(deliverableId, filename) {
- console.log(`\n📥 Downloading file: ${filename}`);
-
- const response = await fetch(`${this.baseUrl}/deliverable/file/${deliverableId}`, {
- method: 'GET',
- headers: this.headers
- });
-
- if (!response.ok) {
- throw new Error(`Download failed: ${response.status}`);
+// Step 3: Download generated file
+async function downloadFile(deliverableId, filename) {
+ const response = await fetch(`${BASE_URL}/deliverable/file/${deliverableId}`, {
+ method: 'GET',
+ headers: {
+ 'Authorization': `Bearer ${API_TOKEN}`,
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client'
}
+ });
- console.log(`✅ File ready for download: ${filename}`);
- console.log(`📁 Content-Type: ${response.headers.get('content-type')}`);
- console.log(`📊 Content-Length: ${response.headers.get('content-length')} bytes`);
-
- // In a real application, you would save the file or return the buffer
- // const buffer = await response.buffer();
- // fs.writeFileSync(filename, buffer);
-
- return {
- filename,
- contentType: response.headers.get('content-type'),
- contentLength: response.headers.get('content-length')
- };
+ if (!response.ok) {
+ throw new Error(`Download failed: ${response.status}`);
}
- // ===============================
- // DEMO FUNCTIONS
- // ===============================
-
- async demoPathA(templateFilePath) {
- console.log('🚀 DEMO: Path A - Upload New Template Workflow');
- console.log('===============================================\n');
+ console.log(`✅ File ready for download: ${filename}`);
- return await this.pathA_UploadAndGenerate(
- templateFilePath,
- 'Contract Generated via Path A - API Upload'
- );
- }
-
- async demoPathB() {
- console.log('🚀 DEMO: Path B - Browse Existing Template Workflow');
- console.log('=================================================\n');
+ // In a real application, you would save the file:
+ // const buffer = await response.buffer();
+ // fs.writeFileSync(filename, buffer);
- return await this.pathB_BrowseAndGenerate(
- 'contract',
- 'Contract Generated via Path B - Browse & Select'
- );
- }
+ return {
+ filename,
+ contentType: response.headers.get('content-type'),
+ contentLength: response.headers.get('content-length')
+ };
+}
- async demoComparison() {
- console.log('🚀 DEMO: Complete Workflow Comparison');
- console.log('====================================\n');
+// Complete workflow: Upload → Generate → Download
+async function completeWorkflow(templateFilePath) {
+ try {
+ console.log('🚀 Starting complete workflow...');
- try {
- console.log('Testing both paths with the same template type...\n');
+ // Step 1: Upload template
+ console.log('\n📤 Step 1: Uploading template...');
+ const template = await uploadTemplate(templateFilePath);
- // Run Path B first (browse existing)
- const pathBResult = await this.demoPathB();
+ // Step 2: Generate deliverable
+ console.log('\n📝 Step 2: Generating document...');
+ const deliverable = await generateDeliverable(template.id);
- console.log('\n' + '='.repeat(60) + '\n');
+ // Step 3: Download file
+ console.log('\n📥 Step 3: Downloading file...');
+ const downloadInfo = await downloadFile(deliverable.id, `${deliverable.name}.docx`);
- // For Path A, we'd need a template file
- console.log('📝 Path A requires a template file to upload.');
- console.log(' Example: await workflow.demoPathA("./contract-template.docx")');
+ console.log('\n✅ Workflow complete!');
+ console.log(`Template: ${template.id}`);
+ console.log(`Document: ${deliverable.id}`);
+ console.log(`File: ${downloadInfo.filename}`);
- return { pathB: pathBResult };
+ return { template, deliverable, downloadInfo };
- } catch (error) {
- console.error('Demo comparison failed:', error.message);
- }
+ } catch (error) {
+ console.error('❌ Workflow failed:', error.message);
+ throw error;
}
}
-// ===============================
-// EXAMPLE USAGE
-// ===============================
-
-async function runExamples() {
- const workflow = new TemplateWorkflowManager(API_TOKEN, ORG_ID, BASE_URL);
-
+// Example usage
+async function example() {
try {
- // Demo Path B (Browse existing templates)
- await workflow.demoPathB();
-
- // Uncomment to demo Path A (requires template file):
- // await workflow.demoPathA('./path/to/your/template.docx');
-
- // Uncomment to run full comparison:
- // await workflow.demoComparison();
-
+ // Replace with your template file path
+ const templatePath = './template.docx';
+ await completeWorkflow(templatePath);
} catch (error) {
- console.error('Workflow demo failed:', error.message);
+ console.error('Example failed:', error.message);
}
}
-// Export for use in other modules
+// Export functions
module.exports = {
- TemplateWorkflowManager
+ uploadTemplate,
+ generateDeliverable,
+ downloadFile,
+ completeWorkflow
};
-// Run examples if script is executed directly
+// Run example if script is executed directly
if (require.main === module) {
- runExamples();
+ example();
}
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/nodejs/fastify.js b/static/scripts/templates/api/complete-workflows/nodejs/fastify.js
index fa6539e..f8dfcf8 100644
--- a/static/scripts/templates/api/complete-workflows/nodejs/fastify.js
+++ b/static/scripts/templates/api/complete-workflows/nodejs/fastify.js
@@ -8,429 +8,169 @@ const ORG_ID = "YOUR_ORGANIZATION_ID";
const BASE_URL = "https://api.turbodocx.com";
/**
- * Complete Template Generation Workflows
- * Demonstrates both Path A (Upload) and Path B (Browse/Select) followed by generation
+ * Complete Workflow: Upload → Generate → Download
+ * Simple 3-step process for document generation
*/
-class TemplateWorkflowManager {
- constructor(apiToken, orgId, baseUrl) {
- this.apiToken = apiToken;
- this.orgId = orgId;
- this.baseUrl = baseUrl;
- this.headers = {
- 'Authorization': `Bearer ${apiToken}`,
- 'x-rapiddocx-org-id': orgId,
- 'User-Agent': 'TurboDocx API Client'
- };
- }
-
- // ===============================
- // PATH A: Upload New Template
- // ===============================
-
- async pathA_UploadAndGenerate(templateFilePath, deliverableName) {
- console.log('🔄 PATH A: Upload New Template → Generate Deliverable');
- console.log('================================');
-
- try {
- // Step 1: Upload and create template
- console.log('\n📤 Step 1: Uploading template...');
- const template = await this.uploadTemplate(templateFilePath);
-
- // Step 2: Generate deliverable using uploaded template
- console.log('\n📝 Step 2: Generating deliverable...');
- const deliverable = await this.generateDeliverable(template.id, {
- name: deliverableName,
- description: `Generated from uploaded template: ${template.name}`,
- variables: this.createVariablesFromTemplate(template.variables)
- });
-
- console.log('\n✅ PATH A COMPLETE!');
- console.log(`Template ID: ${template.id}`);
- console.log(`Deliverable ID: ${deliverable.id}`);
-
- // Download the generated file
- await this.downloadDeliverable(deliverable.id, `${deliverable.name}.docx`);
-
- return { template, deliverable };
-
- } catch (error) {
- console.error('❌ Path A failed:', error.message);
- throw error;
- }
- }
-
- async uploadTemplate(templateFilePath) {
- const formData = new FormData();
- formData.append('templateFile', fs.createReadStream(templateFilePath));
- formData.append('name', 'API Upload Template');
- formData.append('description', 'Template uploaded via API for testing');
- formData.append('variables', '[]');
- formData.append('tags', '["api", "test", "upload"]');
-
- const response = await fetch(`${this.baseUrl}/template/upload-and-create`, {
- method: 'POST',
- headers: {
- ...this.headers,
- ...formData.getHeaders()
- },
- body: formData
- });
-
- if (!response.ok) {
- throw new Error(`Upload failed: ${response.status}`);
- }
-
- const result = await response.json();
- const template = result.data.results.template;
-
- console.log(`✅ Template uploaded: ${template.name} (${template.id})`);
- console.log(`📊 Variables extracted: ${template.variables ? template.variables.length : 0}`);
- console.log(`🔤 Default font: ${template.defaultFont}`);
- console.log(`📝 Fonts used: ${template.fonts ? template.fonts.length : 0}`);
-
- return template;
- }
-
- // ===============================
- // PATH B: Browse and Select
- // ===============================
-
- async pathB_BrowseAndGenerate(searchQuery, deliverableName) {
- console.log('🔍 PATH B: Browse Existing Templates → Generate Deliverable');
- console.log('==================================================');
-
- try {
- // Step 1: Browse templates
- console.log('\n🔍 Step 1: Browsing templates...');
- const browseResult = await this.browseTemplates({ query: searchQuery });
-
- // Step 2: Select first available template
- const selectedTemplate = browseResult.results.find(item => item.type === 'template');
- if (!selectedTemplate) {
- throw new Error('No templates found in browse results');
- }
-
- console.log(`📋 Selected: ${selectedTemplate.name} (${selectedTemplate.id})`);
-
- // Step 3: Get template details
- console.log('\n📖 Step 2: Getting template details...');
- const templateDetails = await this.getTemplateDetails(selectedTemplate.id);
-
- // Step 4: Get PDF preview (optional)
- console.log('\n🖼️ Step 3: Getting PDF preview...');
- const pdfPreview = await this.getTemplatePDFPreview(selectedTemplate.id);
-
- // Step 5: Generate deliverable
- console.log('\n📝 Step 4: Generating deliverable...');
- const deliverable = await this.generateDeliverable(templateDetails.id, {
- name: deliverableName,
- description: `Generated from existing template: ${templateDetails.name}`,
- variables: this.createVariablesFromTemplate(templateDetails.variables)
- });
-
- console.log('\n✅ PATH B COMPLETE!');
- console.log(`Template ID: ${templateDetails.id}`);
- console.log(`Deliverable ID: ${deliverable.id}`);
-
- // Download the generated file
- await this.downloadDeliverable(deliverable.id, `${deliverable.name}.docx`);
-
- return { template: templateDetails, deliverable, pdfPreview };
-
- } catch (error) {
- console.error('❌ Path B failed:', error.message);
- throw error;
- }
- }
-
- async browseTemplates(options = {}) {
- const {
- limit = 25,
- offset = 0,
- query = '',
- showTags = true
- } = options;
-
- const params = new URLSearchParams({
- limit: limit.toString(),
- offset: offset.toString(),
- showTags: showTags.toString()
- });
-
- if (query) params.append('query', query);
-
- const response = await fetch(`${this.baseUrl}/template-item?${params.toString()}`, {
- method: 'GET',
- headers: this.headers
- });
-
- if (!response.ok) {
- throw new Error(`Browse failed: ${response.status}`);
- }
-
- const result = await response.json();
- console.log(`🔍 Found ${result.data.totalRecords} templates/folders`);
-
- return result.data;
- }
-
- async getTemplateDetails(templateId) {
- const response = await fetch(`${this.baseUrl}/template/${templateId}`, {
- method: 'GET',
- headers: this.headers
- });
-
- if (!response.ok) {
- throw new Error(`Template details failed: ${response.status}`);
- }
-
- const result = await response.json();
- const template = result.data.results;
-
- console.log(`📊 Variables: ${template.variables.length}`);
- console.log(`🔤 Default font: ${template.defaultFont || 'N/A'}`);
-
- return template;
- }
-
- async getTemplatePDFPreview(templateId) {
- const response = await fetch(`${this.baseUrl}/template/${templateId}/previewpdflink`, {
- method: 'GET',
- headers: this.headers
- });
-
- if (!response.ok) {
- throw new Error(`PDF preview failed: ${response.status}`);
- }
-
- const result = await response.json();
- console.log(`🖼️ PDF Preview available: ${result.results}`);
-
- return result.results;
- }
-
- // ===============================
- // COMMON: Generate Deliverable
- // ===============================
-
- async generateDeliverable(templateId, deliverableData) {
- const payload = {
- templateId: templateId,
- name: deliverableData.name,
- description: deliverableData.description || '',
- variables: deliverableData.variables,
- tags: deliverableData.tags || ['api-generated'],
- fonts: deliverableData.fonts || '[]',
- defaultFont: deliverableData.defaultFont || 'Arial',
- replaceFonts: deliverableData.replaceFonts !== undefined ? deliverableData.replaceFonts : true,
- metadata: deliverableData.metadata || {
- sessions: [{
- id: this.generateSessionId(),
- starttime: new Date().toISOString(),
- endtime: new Date().toISOString()
- }],
- workflow: 'API Complete Workflow',
- generated: new Date().toISOString()
- }
- };
-
- const response = await fetch(`${this.baseUrl}/deliverable`, {
- method: 'POST',
- headers: {
- ...this.headers,
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify(payload)
- });
-
- if (!response.ok) {
- const errorText = await response.text();
- throw new Error(`Deliverable generation failed: ${response.status} - ${errorText}`);
- }
-
- const result = await response.json();
- const deliverable = result.data.results.deliverable;
-
- console.log(`✅ Generated: ${deliverable.name}`);
- console.log(`📄 Created by: ${deliverable.createdBy}`);
- console.log(`📅 Created on: ${deliverable.createdOn}`);
-
- return deliverable;
- }
-
- // ===============================
- // UTILITY FUNCTIONS
- // ===============================
-
- createVariablesFromTemplate(templateVariables) {
- return templateVariables.map((variable, index) => ({
- mimeType: variable.mimeType || "text",
- name: variable.name,
- placeholder: variable.placeholder,
- text: this.generateSampleText(variable.name),
- allowRichTextInjection: variable.allowRichTextInjection || 0,
- autogenerated: false,
- count: 1,
- order: index + 1,
- subvariables: this.createSampleSubvariables(variable.placeholder),
- metadata: {
- generatedBy: "API Workflow",
- variableType: variable.mimeType || "text"
- },
- aiPrompt: `Generate appropriate content for ${variable.name}`
- }));
- }
-
- generateSampleText(variableName) {
- const sampleData = {
- 'Company': 'TechCorp Solutions Inc.',
- 'Employee': 'John Smith',
- 'Date': new Date().toLocaleDateString(),
- 'Title': 'Senior Software Engineer',
- 'Department': 'Engineering',
- 'Salary': '$95,000',
- 'Address': '123 Main Street, Tech City, TC 12345',
- 'Phone': '(555) 123-4567',
- 'Email': 'john.smith@techcorp.com'
- };
-
- // Find matching sample data or generate generic text
- for (const [key, value] of Object.entries(sampleData)) {
- if (variableName.toLowerCase().includes(key.toLowerCase())) {
- return value;
- }
- }
-
- return `Sample ${variableName} Content`;
- }
+// Step 1: Upload template file
+async function uploadTemplate(templateFilePath) {
+ const formData = new FormData();
+ formData.append('templateFile', fs.createReadStream(templateFilePath));
+ formData.append('name', 'Simple Template');
+ formData.append('description', 'Template uploaded for document generation');
+
+ const response = await fetch(`${BASE_URL}/template/upload-and-create`, {
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${API_TOKEN}`,
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client',
+ ...formData.getHeaders()
+ },
+ body: formData
+ });
+
+ if (!response.ok) {
+ throw new Error(`Upload failed: ${response.status}`);
+ }
+
+ const result = await response.json();
+ const template = result.data.results.template;
+
+ console.log(`✅ Template uploaded: ${template.name} (${template.id})`);
+ return template;
+}
- createSampleSubvariables(placeholder) {
- // Create relevant subvariables based on placeholder name
- if (placeholder.toLowerCase().includes('employee')) {
- return [
- { placeholder: "{Employee.Title}", text: "Senior Software Engineer" },
- { placeholder: "{Employee.StartDate}", text: new Date().toLocaleDateString() }
- ];
- } else if (placeholder.toLowerCase().includes('company')) {
- return [
- { placeholder: "{Company.Address}", text: "123 Main Street, Tech City, TC 12345" },
- { placeholder: "{Company.Phone}", text: "(555) 123-4567" }
- ];
+// Step 2: Generate deliverable with simple variables
+async function generateDeliverable(templateId) {
+ const variables = [
+ {
+ mimeType: "text",
+ name: "Company Name",
+ placeholder: "{CompanyName}",
+ text: "Acme Corporation"
+ },
+ {
+ mimeType: "text",
+ name: "Employee Name",
+ placeholder: "{EmployeeName}",
+ text: "John Smith"
+ },
+ {
+ mimeType: "text",
+ name: "Date",
+ placeholder: "{Date}",
+ text: "January 15, 2024"
}
+ ];
+
+ const payload = {
+ templateId: templateId,
+ name: "Generated Document",
+ description: "Simple document example",
+ variables: variables
+ };
+
+ const response = await fetch(`${BASE_URL}/deliverable`, {
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${API_TOKEN}`,
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(payload)
+ });
+
+ if (!response.ok) {
+ throw new Error(`Generation failed: ${response.status}`);
+ }
+
+ const result = await response.json();
+ const deliverable = result.data.results.deliverable;
+
+ console.log(`✅ Document generated: ${deliverable.name} (${deliverable.id})`);
+ return deliverable;
+}
- return [];
- }
-
- generateSessionId() {
- return Math.random().toString(36).substr(2, 9) + '-' +
- Math.random().toString(36).substr(2, 9) + '-' +
- Math.random().toString(36).substr(2, 9);
- }
-
- async downloadDeliverable(deliverableId, filename) {
- console.log(`\n📥 Downloading file: ${filename}`);
-
- const response = await fetch(`${this.baseUrl}/deliverable/file/${deliverableId}`, {
- method: 'GET',
- headers: this.headers
- });
-
- if (!response.ok) {
- throw new Error(`Download failed: ${response.status}`);
+// Step 3: Download generated file
+async function downloadFile(deliverableId, filename) {
+ const response = await fetch(`${BASE_URL}/deliverable/file/${deliverableId}`, {
+ method: 'GET',
+ headers: {
+ 'Authorization': `Bearer ${API_TOKEN}`,
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client'
}
+ });
- console.log(`✅ File ready for download: ${filename}`);
- console.log(`📁 Content-Type: ${response.headers.get('content-type')}`);
- console.log(`📊 Content-Length: ${response.headers.get('content-length')} bytes`);
-
- // In a real application, you would save the file or return the buffer
- // const buffer = await response.buffer();
- // fs.writeFileSync(filename, buffer);
-
- return {
- filename,
- contentType: response.headers.get('content-type'),
- contentLength: response.headers.get('content-length')
- };
+ if (!response.ok) {
+ throw new Error(`Download failed: ${response.status}`);
}
- // ===============================
- // DEMO FUNCTIONS
- // ===============================
-
- async demoPathA(templateFilePath) {
- console.log('🚀 DEMO: Path A - Upload New Template Workflow');
- console.log('===============================================\n');
+ console.log(`✅ File ready for download: ${filename}`);
- return await this.pathA_UploadAndGenerate(
- templateFilePath,
- 'Contract Generated via Path A - API Upload'
- );
- }
-
- async demoPathB() {
- console.log('🚀 DEMO: Path B - Browse Existing Template Workflow');
- console.log('=================================================\n');
+ // In a real application, you would save the file:
+ // const buffer = await response.buffer();
+ // fs.writeFileSync(filename, buffer);
- return await this.pathB_BrowseAndGenerate(
- 'contract',
- 'Contract Generated via Path B - Browse & Select'
- );
- }
+ return {
+ filename,
+ contentType: response.headers.get('content-type'),
+ contentLength: response.headers.get('content-length')
+ };
+}
- async demoComparison() {
- console.log('🚀 DEMO: Complete Workflow Comparison');
- console.log('====================================\n');
+// Complete workflow: Upload → Generate → Download
+async function completeWorkflow(templateFilePath) {
+ try {
+ console.log('🚀 Starting complete workflow...');
- try {
- console.log('Testing both paths with the same template type...\n');
+ // Step 1: Upload template
+ console.log('\n📤 Step 1: Uploading template...');
+ const template = await uploadTemplate(templateFilePath);
- // Run Path B first (browse existing)
- const pathBResult = await this.demoPathB();
+ // Step 2: Generate deliverable
+ console.log('\n📝 Step 2: Generating document...');
+ const deliverable = await generateDeliverable(template.id);
- console.log('\n' + '='.repeat(60) + '\n');
+ // Step 3: Download file
+ console.log('\n📥 Step 3: Downloading file...');
+ const downloadInfo = await downloadFile(deliverable.id, `${deliverable.name}.docx`);
- // For Path A, we'd need a template file
- console.log('📝 Path A requires a template file to upload.');
- console.log(' Example: await workflow.demoPathA("./contract-template.docx")');
+ console.log('\n✅ Workflow complete!');
+ console.log(`Template: ${template.id}`);
+ console.log(`Document: ${deliverable.id}`);
+ console.log(`File: ${downloadInfo.filename}`);
- return { pathB: pathBResult };
+ return { template, deliverable, downloadInfo };
- } catch (error) {
- console.error('Demo comparison failed:', error.message);
- }
+ } catch (error) {
+ console.error('❌ Workflow failed:', error.message);
+ throw error;
}
}
-// ===============================
-// EXAMPLE USAGE
-// ===============================
-
-async function runExamples() {
- const workflow = new TemplateWorkflowManager(API_TOKEN, ORG_ID, BASE_URL);
-
+// Example usage
+async function example() {
try {
- // Demo Path B (Browse existing templates)
- await workflow.demoPathB();
-
- // Uncomment to demo Path A (requires template file):
- // await workflow.demoPathA('./path/to/your/template.docx');
-
- // Uncomment to run full comparison:
- // await workflow.demoComparison();
-
+ // Replace with your template file path
+ const templatePath = './template.docx';
+ await completeWorkflow(templatePath);
} catch (error) {
- console.error('Workflow demo failed:', error.message);
+ console.error('Example failed:', error.message);
}
}
-// Export for use in other modules
+// Export functions
module.exports = {
- TemplateWorkflowManager
+ uploadTemplate,
+ generateDeliverable,
+ downloadFile,
+ completeWorkflow
};
-// Run examples if script is executed directly
+// Run example if script is executed directly
if (require.main === module) {
- runExamples();
+ example();
}
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/powershell.ps1 b/static/scripts/templates/api/complete-workflows/powershell.ps1
index e05d504..85d845f 100644
--- a/static/scripts/templates/api/complete-workflows/powershell.ps1
+++ b/static/scripts/templates/api/complete-workflows/powershell.ps1
@@ -3,423 +3,186 @@ $API_TOKEN = "YOUR_API_TOKEN"
$ORG_ID = "YOUR_ORGANIZATION_ID"
$BASE_URL = "https://api.turbodocx.com"
-##
-# Complete Template Workflow Manager
-# Demonstrates both upload and browse/select paths
-##
-
-class TemplateWorkflowManager {
- [string]$ApiToken
- [string]$OrgId
- [string]$BaseUrl
-
- TemplateWorkflowManager([string]$apiToken, [string]$orgId, [string]$baseUrl) {
- $this.ApiToken = $apiToken
- $this.OrgId = $orgId
- $this.BaseUrl = $baseUrl
- Write-Host "=== TurboDocx Template Generation Workflow Manager ===" -ForegroundColor Cyan
+<#
+Complete Workflow: Upload → Generate → Download
+Simple 3-step process for document generation
+#>
+
+function Upload-Template {
+ param(
+ [string]$TemplateFilePath
+ )
+
+ if (-not (Test-Path $TemplateFilePath)) {
+ throw "Template file not found: $TemplateFilePath"
}
- [void] DemonstrateCompleteWorkflow() {
- Write-Host "`nSelect workflow path:" -ForegroundColor Yellow
- Write-Host "A) Upload new template"
- Write-Host "B) Browse and select existing template"
-
- # For this example, we'll demonstrate both paths
- Write-Host "`n=== Demonstrating Path A: Upload Template ===" -ForegroundColor Magenta
- $templateIdA = $this.DemonstrateUploadWorkflow()
-
- Write-Host "`n=== Demonstrating Path B: Browse Templates ===" -ForegroundColor Magenta
- $templateIdB = $this.DemonstrateBrowseWorkflow()
-
- # Generate deliverables for both templates if successful
- if ($templateIdA) {
- Write-Host "`n=== Generating Deliverable from Uploaded Template ===" -ForegroundColor Green
- $this.GenerateAndDownloadDeliverable($templateIdA, "A")
- }
-
- if ($templateIdB) {
- Write-Host "`n=== Generating Deliverable from Selected Template ===" -ForegroundColor Green
- $this.GenerateAndDownloadDeliverable($templateIdB, "B")
- }
+ $uri = "$BASE_URL/template/upload-and-create"
+ $boundary = "----PowerShellBoundary$((Get-Random -Maximum 1000000))"
+
+ # Read file content
+ $fileContent = [System.IO.File]::ReadAllBytes($TemplateFilePath)
+ $fileName = [System.IO.Path]::GetFileName($TemplateFilePath)
+
+ # Build multipart form data
+ $bodyLines = @()
+
+ # Template file field
+ $bodyLines += "--$boundary"
+ $bodyLines += "Content-Disposition: form-data; name=`"templateFile`"; filename=`"$fileName`""
+ $bodyLines += "Content-Type: application/octet-stream"
+ $bodyLines += ""
+
+ # Convert file content to string for inclusion
+ $encoding = [System.Text.Encoding]::GetEncoding("ISO-8859-1")
+ $bodyLines += $encoding.GetString($fileContent)
+
+ # Name field
+ $bodyLines += "--$boundary"
+ $bodyLines += "Content-Disposition: form-data; name=`"name`""
+ $bodyLines += ""
+ $bodyLines += "Simple Template"
+
+ # Description field
+ $bodyLines += "--$boundary"
+ $bodyLines += "Content-Disposition: form-data; name=`"description`""
+ $bodyLines += ""
+ $bodyLines += "Template uploaded for document generation"
+
+ $bodyLines += "--$boundary--"
+
+ # Join with CRLF
+ $body = ($bodyLines -join "`r`n")
+ $bodyBytes = $encoding.GetBytes($body)
+
+ # Create headers
+ $headers = @{
+ 'Authorization' = "Bearer $API_TOKEN"
+ 'x-rapiddocx-org-id' = $ORG_ID
+ 'User-Agent' = 'TurboDocx API Client'
+ 'Content-Type' = "multipart/form-data; boundary=$boundary"
}
- [string] DemonstrateUploadWorkflow() {
- try {
- Write-Host "`n--- Path A: Upload and Create Template ---" -ForegroundColor Yellow
-
- # Check for template file
- $templateFile = ".\contract-template.docx"
- if (-not (Test-Path $templateFile)) {
- Write-Host "⚠️ Template file not found: $templateFile" -ForegroundColor Yellow
- Write-Host "Creating a placeholder message for demonstration"
- return $null
- }
-
- $result = $this.UploadTemplate($templateFile)
- $template = $result.data.results.template
+ # Make request
+ $response = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $bodyBytes
+ $template = $response.data.results.template
- Write-Host "✅ Upload workflow completed" -ForegroundColor Green
- Write-Host "Template ID: $($template.id)"
- Write-Host "Ready for deliverable generation"
-
- return $template.id
- }
- catch {
- Write-Host "❌ Upload workflow failed: $($_.Exception.Message)" -ForegroundColor Red
- return $null
- }
- }
-
- [string] DemonstrateBrowseWorkflow() {
- try {
- Write-Host "`n--- Path B: Browse and Select Template ---" -ForegroundColor Yellow
-
- # Browse templates
- $browseResult = $this.BrowseTemplates(10, 0, 'contract', $true)
+ Write-Host "✅ Template uploaded: $($template.name) ($($template.id))"
+ return $template
+}
- # Find first template (not folder)
- $selectedTemplate = $browseResult.results | Where-Object { $_.type -eq 'template' } | Select-Object -First 1
+function Generate-Deliverable {
+ param(
+ [string]$TemplateId
+ )
- if ($null -eq $selectedTemplate) {
- Write-Host "⚠️ No templates found in browse results" -ForegroundColor Yellow
- return $null
+ $payload = @{
+ templateId = $TemplateId
+ name = "Generated Document"
+ description = "Simple document example"
+ variables = @(
+ @{
+ mimeType = "text"
+ name = "Company Name"
+ placeholder = "{CompanyName}"
+ text = "Acme Corporation"
+ },
+ @{
+ mimeType = "text"
+ name = "Employee Name"
+ placeholder = "{EmployeeName}"
+ text = "John Smith"
+ },
+ @{
+ mimeType = "text"
+ name = "Date"
+ placeholder = "{Date}"
+ text = "January 15, 2024"
}
-
- Write-Host "Selected: $($selectedTemplate.name)"
-
- # Get detailed information
- $templateDetails = $this.GetTemplateDetails($selectedTemplate.id)
-
- # Optionally get PDF preview
- $pdfPreview = $this.GetTemplatePdfPreview($selectedTemplate.id)
-
- Write-Host "✅ Browse workflow completed" -ForegroundColor Green
- Write-Host "Template ID: $($templateDetails.id)"
- Write-Host "PDF Preview: $pdfPreview"
- Write-Host "Ready for deliverable generation"
-
- return $templateDetails.id
- }
- catch {
- Write-Host "❌ Browse workflow failed: $($_.Exception.Message)" -ForegroundColor Red
- return $null
- }
- }
-
- [void] GenerateAndDownloadDeliverable([string]$templateId, [string]$pathLabel) {
- try {
- Write-Host "`n--- Generating Deliverable (Path $pathLabel) ---" -ForegroundColor Yellow
-
- $deliverableData = $this.CreateDeliverableData($templateId, $pathLabel)
- $deliverable = $this.GenerateDeliverable($templateId, $deliverableData)
-
- # Download the file
- $downloadResult = $this.DownloadDeliverable(
- $deliverable.id,
- "$($deliverable.name)_path_$pathLabel.docx"
- )
-
- Write-Host "✅ Complete workflow finished successfully for Path $pathLabel" -ForegroundColor Green
- Write-Host "Deliverable ID: $($deliverable.id)"
- Write-Host "Download info: $($downloadResult | ConvertTo-Json -Compress)"
- }
- catch {
- Write-Host "❌ Deliverable generation failed for Path $pathLabel : $($_.Exception.Message)" -ForegroundColor Red
- }
+ )
}
- [hashtable] UploadTemplate([string]$templateFilePath) {
- $uri = "$($this.BaseUrl)/template/upload-and-create"
- $boundary = "----PowerShellBoundary$((Get-Random -Maximum 1000000))"
-
- # Read file content
- $fileContent = [System.IO.File]::ReadAllBytes($templateFilePath)
- $fileName = [System.IO.Path]::GetFileName($templateFilePath)
-
- # Build multipart form data
- $bodyLines = @()
-
- # Template file field
- $bodyLines += "--$boundary"
- $bodyLines += "Content-Disposition: form-data; name=`"templateFile`"; filename=`"$fileName`""
- $bodyLines += "Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document"
- $bodyLines += ""
-
- # Convert file content to string for inclusion
- $encoding = [System.Text.Encoding]::GetEncoding("ISO-8859-1")
- $bodyLines += $encoding.GetString($fileContent)
-
- # Name field
- $bodyLines += "--$boundary"
- $bodyLines += "Content-Disposition: form-data; name=`"name`""
- $bodyLines += ""
- $bodyLines += "Employee Contract Template"
-
- # Description field
- $bodyLines += "--$boundary"
- $bodyLines += "Content-Disposition: form-data; name=`"description`""
- $bodyLines += ""
- $bodyLines += "Standard employee contract with variable placeholders"
-
- # Variables field
- $bodyLines += "--$boundary"
- $bodyLines += "Content-Disposition: form-data; name=`"variables`""
- $bodyLines += ""
- $bodyLines += "[]"
-
- # Tags field
- $bodyLines += "--$boundary"
- $bodyLines += "Content-Disposition: form-data; name=`"tags`""
- $bodyLines += ""
- $bodyLines += '["hr", "contract", "template"]'
-
- $bodyLines += "--$boundary--"
-
- # Join with CRLF
- $body = ($bodyLines -join "`r`n")
- $bodyBytes = $encoding.GetBytes($body)
-
- # Create headers
- $headers = @{
- 'Authorization' = "Bearer $($this.ApiToken)"
- 'x-rapiddocx-org-id' = $this.OrgId
- 'User-Agent' = 'TurboDocx API Client'
- 'Content-Type' = "multipart/form-data; boundary=$boundary"
- }
-
- # Make request
- $response = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $bodyBytes
- return $response
- }
+ $uri = "$BASE_URL/deliverable"
- [hashtable] BrowseTemplates([int]$limit, [int]$offset, [string]$query, [bool]$showTags) {
- # Build query parameters
- $params = @{
- 'limit' = $limit
- 'offset' = $offset
- 'showTags' = $showTags.ToString().ToLower()
- }
-
- if ($query -ne '') {
- $params['query'] = $query
- }
-
- # Build query string
- $queryString = ($params.GetEnumerator() | ForEach-Object {
- "$([System.Web.HttpUtility]::UrlEncode($_.Key))=$([System.Web.HttpUtility]::UrlEncode($_.Value))"
- }) -join '&'
-
- $uri = "$($this.BaseUrl)/template-item?$queryString"
-
- # Create headers
- $headers = @{
- 'Authorization' = "Bearer $($this.ApiToken)"
- 'x-rapiddocx-org-id' = $this.OrgId
- 'User-Agent' = 'TurboDocx API Client'
- }
-
- # Make request
- $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
- return $response.data
+ # Create headers
+ $headers = @{
+ 'Authorization' = "Bearer $API_TOKEN"
+ 'x-rapiddocx-org-id' = $ORG_ID
+ 'User-Agent' = 'TurboDocx API Client'
+ 'Content-Type' = 'application/json'
}
- [hashtable] GetTemplateDetails([string]$templateId) {
- $uri = "$($this.BaseUrl)/template/$templateId"
+ # Convert to JSON
+ $jsonBody = $payload | ConvertTo-Json -Depth 10
- # Create headers
- $headers = @{
- 'Authorization' = "Bearer $($this.ApiToken)"
- 'x-rapiddocx-org-id' = $this.OrgId
- 'User-Agent' = 'TurboDocx API Client'
- }
+ # Make request
+ $response = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $jsonBody
+ $deliverable = $response.data.results.deliverable
- # Make request
- $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
- return $response.data.results
- }
+ Write-Host "✅ Document generated: $($deliverable.name) ($($deliverable.id))"
+ return $deliverable
+}
- [string] GetTemplatePdfPreview([string]$templateId) {
- $uri = "$($this.BaseUrl)/template/$templateId/previewpdflink"
+function Download-File {
+ param(
+ [string]$DeliverableId,
+ [string]$Filename
+ )
- # Create headers
- $headers = @{
- 'Authorization' = "Bearer $($this.ApiToken)"
- 'x-rapiddocx-org-id' = $this.OrgId
- 'User-Agent' = 'TurboDocx API Client'
- }
+ $uri = "$BASE_URL/deliverable/file/$DeliverableId"
- # Make request
- $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
- return $response.results
+ # Create headers
+ $headers = @{
+ 'Authorization' = "Bearer $API_TOKEN"
+ 'x-rapiddocx-org-id' = $ORG_ID
+ 'User-Agent' = 'TurboDocx API Client'
}
- [hashtable] GenerateDeliverable([string]$templateId, [hashtable]$deliverableData) {
- $uri = "$($this.BaseUrl)/deliverable"
-
- Write-Host "Generating deliverable..."
- Write-Host "Template ID: $templateId"
- Write-Host "Deliverable Name: $($deliverableData.name)"
- Write-Host "Variables: $($deliverableData.variables.Count)"
-
- # Create headers
- $headers = @{
- 'Authorization' = "Bearer $($this.ApiToken)"
- 'x-rapiddocx-org-id' = $this.OrgId
- 'User-Agent' = 'TurboDocx API Client'
- 'Content-Type' = 'application/json'
- }
-
- # Convert to JSON
- $jsonBody = $deliverableData | ConvertTo-Json -Depth 10
-
- # Make request
- $response = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $jsonBody
+ # Make request
+ $response = Invoke-WebRequest -Uri $uri -Method Get -Headers $headers
- # Parse JSON response
- $deliverable = $response.data.results.deliverable
-
- Write-Host "✅ Deliverable generated successfully!" -ForegroundColor Green
- Write-Host "Deliverable ID: $($deliverable.id)"
- Write-Host "Created by: $($deliverable.createdBy)"
- Write-Host "Created on: $($deliverable.createdOn)"
- Write-Host "Template ID: $($deliverable.templateId)"
-
- return $deliverable
+ if ($response.StatusCode -ne 200) {
+ throw "Download failed: $($response.StatusCode)"
}
- [hashtable] DownloadDeliverable([string]$deliverableId, [string]$filename) {
- Write-Host "Downloading file: $filename"
-
- $uri = "$($this.BaseUrl)/deliverable/file/$deliverableId"
-
- # Create headers
- $headers = @{
- 'Authorization' = "Bearer $($this.ApiToken)"
- 'x-rapiddocx-org-id' = $this.OrgId
- 'User-Agent' = 'TurboDocx API Client'
- }
-
- # Make request
- $response = Invoke-WebRequest -Uri $uri -Method Get -Headers $headers
-
- if ($response.StatusCode -ne 200) {
- throw "Download failed: $($response.StatusCode)"
- }
+ Write-Host "✅ File ready for download: $Filename"
- Write-Host "✅ File ready for download: $filename" -ForegroundColor Green
+ # In a real application, you would save the file:
+ # [System.IO.File]::WriteAllBytes($Filename, $response.Content)
+}
- $contentType = if ($response.Headers['Content-Type']) { $response.Headers['Content-Type'] } else { 'N/A' }
- $contentLength = if ($response.Headers['Content-Length']) { $response.Headers['Content-Length'] } else { 'N/A' }
+function Complete-Workflow {
+ param(
+ [string]$TemplateFilePath
+ )
- Write-Host "📁 Content-Type: $contentType"
- Write-Host "📊 Content-Length: $contentLength bytes"
+ Write-Host "🚀 Starting complete workflow..."
- # In a real application, you would save the file
- # [System.IO.File]::WriteAllBytes($filename, $response.Content)
+ # Step 1: Upload template
+ Write-Host "`n📤 Step 1: Uploading template..."
+ $template = Upload-Template -TemplateFilePath $TemplateFilePath
- return @{
- 'filename' = $filename
- 'content_type' = $contentType
- 'content_length' = $contentLength
- }
- }
+ # Step 2: Generate deliverable
+ Write-Host "`n📝 Step 2: Generating document..."
+ $deliverable = Generate-Deliverable -TemplateId $template.id
- [hashtable] CreateDeliverableData([string]$templateId, [string]$pathLabel) {
- $now = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ')
-
- return @{
- 'templateId' = $templateId
- 'name' = "Contract Document - Path $pathLabel"
- 'description' = "Employment contract generated via workflow path $pathLabel"
- 'variables' = $this.CreateComplexVariables()
- 'tags' = @('hr', 'contract', 'employee', 'engineering')
- 'fonts' = '[{"name":"Arial","usage":269}]'
- 'defaultFont' = 'Arial'
- 'replaceFonts' = $true
- 'metadata' = @{
- 'sessions' = @(
- @{
- 'id' = [System.Guid]::NewGuid().ToString()
- 'starttime' = $now
- 'endtime' = $now
- }
- )
- 'createdBy' = 'PowerShell Workflow Manager'
- 'documentType' = 'Employment Contract'
- 'version' = 'v1.0'
- 'workflowPath' = $pathLabel
- }
- }
- }
+ # Step 3: Download file
+ Write-Host "`n📥 Step 3: Downloading file..."
+ $filename = "$($deliverable.name).docx"
+ Download-File -DeliverableId $deliverable.id -Filename $filename
- [array] CreateComplexVariables() {
- return @(
- @{
- 'mimeType' = 'text'
- 'name' = 'Employee Name'
- 'placeholder' = '{EmployeeName}'
- 'text' = 'John Smith'
- 'allowRichTextInjection' = 0
- 'autogenerated' = $false
- 'count' = 1
- 'order' = 1
- 'subvariables' = @(
- @{
- 'placeholder' = '{EmployeeName.Title}'
- 'text' = 'Senior Software Engineer'
- },
- @{
- 'placeholder' = '{EmployeeName.StartDate}'
- 'text' = 'January 15, 2024'
- }
- )
- 'metadata' = @{
- 'department' = 'Engineering'
- 'level' = 'Senior'
- }
- 'aiPrompt' = 'Generate a professional job description for a senior software engineer role'
- },
- @{
- 'mimeType' = 'text'
- 'name' = 'Company Information'
- 'placeholder' = '{CompanyInfo}'
- 'text' = 'TechCorp Solutions Inc.'
- 'allowRichTextInjection' = 1
- 'autogenerated' = $false
- 'count' = 1
- 'order' = 2
- 'subvariables' = @(
- @{
- 'placeholder' = '{CompanyInfo.Address}'
- 'text' = '123 Innovation Drive, Tech City, TC 12345'
- },
- @{
- 'placeholder' = '{CompanyInfo.Phone}'
- 'text' = '(555) 123-4567'
- }
- )
- 'metadata' = @{}
- 'aiPrompt' = ''
- }
- )
- }
+ Write-Host "`n✅ Workflow complete!"
+ Write-Host "Template: $($template.id)"
+ Write-Host "Document: $($deliverable.id)"
+ Write-Host "File: $filename"
}
# Example usage
try {
- Add-Type -AssemblyName System.Web
-
- $workflowManager = [TemplateWorkflowManager]::new($API_TOKEN, $ORG_ID, $BASE_URL)
- $workflowManager.DemonstrateCompleteWorkflow()
-
- Write-Host "`n=== Workflow Demonstration Complete ===" -ForegroundColor Green
- Write-Host "Both upload and browse/select paths have been demonstrated."
- Write-Host "Choose the appropriate path for your use case:"
- Write-Host "- Upload path: When you have new templates to create"
- Write-Host "- Browse path: When you want to use existing templates"
+ # Replace with your template file path
+ $templatePath = "./template.docx"
+ Complete-Workflow -TemplateFilePath $templatePath
}
catch {
- Write-Error "Workflow demonstration failed: $($_.Exception.Message)"
- exit 1
+ Write-Host "❌ Workflow failed: $($_.Exception.Message)" -ForegroundColor Red
}
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/python/fastapi.py b/static/scripts/templates/api/complete-workflows/python/fastapi.py
index 634dff5..cd972fc 100644
--- a/static/scripts/templates/api/complete-workflows/python/fastapi.py
+++ b/static/scripts/templates/api/complete-workflows/python/fastapi.py
@@ -1,418 +1,157 @@
import requests
-import json
-import uuid
import os
-from datetime import datetime
-from urllib.parse import urlencode
# Configuration - Update these values
API_TOKEN = "YOUR_API_TOKEN"
ORG_ID = "YOUR_ORGANIZATION_ID"
BASE_URL = "https://api.turbodocx.com"
-class TemplateWorkflowManager:
- """
- Complete Template Generation Workflows
- Demonstrates both Path A (Upload) and Path B (Browse/Select) followed by generation
- """
+"""
+Complete Workflow: Upload → Generate → Download
+Simple 3-step process for document generation
+"""
- def __init__(self, api_token, org_id, base_url):
- self.api_token = api_token
- self.org_id = org_id
- self.base_url = base_url
- self.headers = {
- 'Authorization': f'Bearer {api_token}',
- 'x-rapiddocx-org-id': org_id,
- 'User-Agent': 'TurboDocx API Client'
- }
-
- # ===============================
- # PATH A: Upload New Template
- # ===============================
-
- def path_a_upload_and_generate(self, template_file_path, deliverable_name):
- """Complete Path A workflow: Upload → Generate"""
- print("🔄 PATH A: Upload New Template → Generate Deliverable")
- print("=" * 48)
-
- try:
- # Step 1: Upload and create template
- print("\n📤 Step 1: Uploading template...")
- template = self.upload_template(template_file_path)
-
- # Step 2: Generate deliverable using uploaded template
- print("\n📝 Step 2: Generating deliverable...")
- deliverable = self.generate_deliverable(template['id'], {
- 'name': deliverable_name,
- 'description': f"Generated from uploaded template: {template['name']}",
- 'variables': self.create_variables_from_template(template['variables'])
- })
-
- print("\n✅ PATH A COMPLETE!")
- print(f"Template ID: {template['id']}")
- print(f"Deliverable ID: {deliverable['id']}")
-
- # Download the generated file
- self.download_deliverable(deliverable['id'], f"{deliverable['name']}.docx")
-
- return {'template': template, 'deliverable': deliverable}
-
- except Exception as error:
- print(f"❌ Path A failed: {error}")
- raise
+# Step 1: Upload template file
+def upload_template(template_file_path):
+ url = f"{BASE_URL}/template/upload-and-create"
- def upload_template(self, template_file_path):
- """Upload a template file and create template record"""
- if not os.path.exists(template_file_path):
- raise FileNotFoundError(f"Template file not found: {template_file_path}")
-
- url = f"{self.base_url}/template/upload-and-create"
-
- files = {
- 'templateFile': (
- os.path.basename(template_file_path),
- open(template_file_path, 'rb'),
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- )
- }
+ headers = {
+ 'Authorization': f'Bearer {API_TOKEN}',
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client'
+ }
+ with open(template_file_path, 'rb') as file:
+ files = {'templateFile': file}
data = {
- 'name': 'API Upload Template',
- 'description': 'Template uploaded via API for testing',
- 'variables': '[]',
- 'tags': '["api", "test", "upload"]'
- }
-
- try:
- response = requests.post(url, headers=self.headers, files=files, data=data)
- response.raise_for_status()
-
- result = response.json()
- template = result['data']['results']['template']
-
- print(f"✅ Template uploaded: {template['name']} ({template['id']})")
- print(f"📊 Variables extracted: {len(template['variables']) if template['variables'] else 0}")
- print(f"🔤 Default font: {template['defaultFont']}")
- print(f"📝 Fonts used: {len(template['fonts']) if template['fonts'] else 0}")
-
- return template
-
- finally:
- files['templateFile'][1].close()
-
- # ===============================
- # PATH B: Browse and Select
- # ===============================
-
- def path_b_browse_and_generate(self, search_query, deliverable_name):
- """Complete Path B workflow: Browse → Select → Generate"""
- print("🔍 PATH B: Browse Existing Templates → Generate Deliverable")
- print("=" * 56)
-
- try:
- # Step 1: Browse templates
- print("\n🔍 Step 1: Browsing templates...")
- browse_result = self.browse_templates({'query': search_query})
-
- # Step 2: Select first available template
- selected_template = None
- for item in browse_result['results']:
- if item['type'] == 'template':
- selected_template = item
- break
-
- if not selected_template:
- raise Exception('No templates found in browse results')
-
- print(f"📋 Selected: {selected_template['name']} ({selected_template['id']})")
-
- # Step 3: Get template details
- print("\n📖 Step 2: Getting template details...")
- template_details = self.get_template_details(selected_template['id'])
-
- # Step 4: Get PDF preview (optional)
- print("\n🖼️ Step 3: Getting PDF preview...")
- pdf_preview = self.get_template_pdf_preview(selected_template['id'])
-
- # Step 5: Generate deliverable
- print("\n📝 Step 4: Generating deliverable...")
- deliverable = self.generate_deliverable(template_details['id'], {
- 'name': deliverable_name,
- 'description': f"Generated from existing template: {template_details['name']}",
- 'variables': self.create_variables_from_template(template_details['variables'])
- })
-
- print("\n✅ PATH B COMPLETE!")
- print(f"Template ID: {template_details['id']}")
- print(f"Deliverable ID: {deliverable['id']}")
-
- # Download the generated file
- self.download_deliverable(deliverable['id'], f"{deliverable['name']}.docx")
-
- return {
- 'template': template_details,
- 'deliverable': deliverable,
- 'pdf_preview': pdf_preview
- }
-
- except Exception as error:
- print(f"❌ Path B failed: {error}")
- raise
-
- def browse_templates(self, options=None):
- """Browse available templates and folders"""
- if options is None:
- options = {}
-
- params = {
- 'limit': options.get('limit', 25),
- 'offset': options.get('offset', 0),
- 'showTags': str(options.get('show_tags', True)).lower()
+ 'name': 'Simple Template',
+ 'description': 'Template uploaded for document generation'
}
- query = options.get('query', '')
- if query:
- params['query'] = query
-
- url = f"{self.base_url}/template-item?{urlencode(params)}"
-
- response = requests.get(url, headers=self.headers)
- response.raise_for_status()
-
- result = response.json()
- data = result['data']
-
- print(f"🔍 Found {data['totalRecords']} templates/folders")
-
- return data
-
- def get_template_details(self, template_id):
- """Get detailed template information"""
- url = f"{self.base_url}/template/{template_id}"
-
- response = requests.get(url, headers=self.headers)
- response.raise_for_status()
-
- result = response.json()
- template = result['data']['results']
-
- print(f"📊 Variables: {len(template['variables'])}")
- print(f"🔤 Default font: {template.get('defaultFont', 'N/A')}")
-
- return template
-
- def get_template_pdf_preview(self, template_id):
- """Get PDF preview URL for template"""
- url = f"{self.base_url}/template/{template_id}/previewpdflink"
-
- response = requests.get(url, headers=self.headers)
- response.raise_for_status()
-
- result = response.json()
- pdf_url = result['results']
-
- print(f"🖼️ PDF Preview available: {pdf_url}")
-
- return pdf_url
-
- # ===============================
- # COMMON: Generate Deliverable
- # ===============================
-
- def generate_deliverable(self, template_id, deliverable_data):
- """Generate a deliverable document from template"""
- payload = {
- "templateId": template_id,
- "name": deliverable_data['name'],
- "description": deliverable_data.get('description', ''),
- "variables": deliverable_data['variables'],
- "tags": deliverable_data.get('tags', ['api-generated']),
- "fonts": deliverable_data.get('fonts', '[]'),
- "defaultFont": deliverable_data.get('defaultFont', 'Arial'),
- "replaceFonts": deliverable_data.get('replaceFonts', True),
- "metadata": deliverable_data.get('metadata', {
- "sessions": [{
- "id": self.generate_session_id(),
- "starttime": datetime.utcnow().isoformat() + "Z",
- "endtime": datetime.utcnow().isoformat() + "Z"
- }],
- "workflow": "API Complete Workflow",
- "generated": datetime.utcnow().isoformat() + "Z"
- })
+ response = requests.post(url, headers=headers, files=files, data=data)
+
+ if not response.ok:
+ raise Exception(f"Upload failed: {response.status_code}")
+
+ result = response.json()
+ template = result['data']['results']['template']
+
+ print(f"✅ Template uploaded: {template['name']} ({template['id']})")
+ return template
+
+# Step 2: Generate deliverable with simple variables
+def generate_deliverable(template_id):
+ variables = [
+ {
+ "mimeType": "text",
+ "name": "Company Name",
+ "placeholder": "{CompanyName}",
+ "text": "Acme Corporation"
+ },
+ {
+ "mimeType": "text",
+ "name": "Employee Name",
+ "placeholder": "{EmployeeName}",
+ "text": "John Smith"
+ },
+ {
+ "mimeType": "text",
+ "name": "Date",
+ "placeholder": "{Date}",
+ "text": "January 15, 2024"
}
+ ]
- url = f"{self.base_url}/deliverable"
- headers = {**self.headers, 'Content-Type': 'application/json'}
+ payload = {
+ "templateId": template_id,
+ "name": "Generated Document",
+ "description": "Simple document example",
+ "variables": variables
+ }
- response = requests.post(url, headers=headers, json=payload)
- response.raise_for_status()
+ headers = {
+ 'Authorization': f'Bearer {API_TOKEN}',
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client',
+ 'Content-Type': 'application/json'
+ }
- result = response.json()
- deliverable = result['data']['results']['deliverable']
+ response = requests.post(f"{BASE_URL}/deliverable", headers=headers, json=payload)
- print(f"✅ Generated: {deliverable['name']}")
- print(f"📄 Created by: {deliverable['createdBy']}")
- print(f"📅 Created on: {deliverable['createdOn']}")
+ if not response.ok:
+ raise Exception(f"Generation failed: {response.status_code}")
- return deliverable
+ result = response.json()
+ deliverable = result['data']['results']['deliverable']
- # ===============================
- # UTILITY FUNCTIONS
- # ===============================
+ print(f"✅ Document generated: {deliverable['name']} ({deliverable['id']})")
+ return deliverable
- def create_variables_from_template(self, template_variables):
- """Create variable payload from template variable definitions"""
- return [
- {
- "mimeType": variable.get('mimeType', 'text'),
- "name": variable['name'],
- "placeholder": variable['placeholder'],
- "text": self.generate_sample_text(variable['name']),
- "allowRichTextInjection": variable.get('allowRichTextInjection', 0),
- "autogenerated": False,
- "count": 1,
- "order": index + 1,
- "subvariables": self.create_sample_subvariables(variable['placeholder']),
- "metadata": {
- "generatedBy": "API Workflow",
- "variableType": variable.get('mimeType', 'text')
- },
- "aiPrompt": f"Generate appropriate content for {variable['name']}"
- }
- for index, variable in enumerate(template_variables)
- ]
+# Step 3: Download generated file
+def download_file(deliverable_id, filename):
+ headers = {
+ 'Authorization': f'Bearer {API_TOKEN}',
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client'
+ }
- def generate_sample_text(self, variable_name):
- """Generate sample text based on variable name"""
- sample_data = {
- 'company': 'TechCorp Solutions Inc.',
- 'employee': 'John Smith',
- 'date': datetime.now().strftime('%B %d, %Y'),
- 'title': 'Senior Software Engineer',
- 'department': 'Engineering',
- 'salary': '$95,000',
- 'address': '123 Main Street, Tech City, TC 12345',
- 'phone': '(555) 123-4567',
- 'email': 'john.smith@techcorp.com'
- }
-
- # Find matching sample data or generate generic text
- for key, value in sample_data.items():
- if key.lower() in variable_name.lower():
- return value
+ response = requests.get(f"{BASE_URL}/deliverable/file/{deliverable_id}", headers=headers)
- return f"Sample {variable_name} Content"
+ if not response.ok:
+ raise Exception(f"Download failed: {response.status_code}")
- def create_sample_subvariables(self, placeholder):
- """Create relevant subvariables based on placeholder name"""
- placeholder_lower = placeholder.lower()
+ print(f"✅ File ready for download: {filename}")
- if 'employee' in placeholder_lower:
- return [
- {"placeholder": "{Employee.Title}", "text": "Senior Software Engineer"},
- {"placeholder": "{Employee.StartDate}", "text": datetime.now().strftime('%B %d, %Y')}
- ]
- elif 'company' in placeholder_lower:
- return [
- {"placeholder": "{Company.Address}", "text": "123 Main Street, Tech City, TC 12345"},
- {"placeholder": "{Company.Phone}", "text": "(555) 123-4567"}
- ]
+ # In a real application, you would save the file:
+ # with open(filename, 'wb') as f:
+ # f.write(response.content)
- return []
+ return {
+ 'filename': filename,
+ 'content_type': response.headers.get('content-type'),
+ 'content_length': response.headers.get('content-length')
+ }
- def generate_session_id(self):
- """Generate a unique session ID"""
- return str(uuid.uuid4())
-
- def download_deliverable(self, deliverable_id, filename):
- """Download the generated deliverable file"""
- print(f"\n📥 Downloading file: {filename}")
+# Complete workflow: Upload → Generate → Download
+def complete_workflow(template_file_path):
+ try:
+ print("🚀 Starting complete workflow...")
- url = f"{self.base_url}/deliverable/file/{deliverable_id}"
+ # Step 1: Upload template
+ print("\n📤 Step 1: Uploading template...")
+ template = upload_template(template_file_path)
- response = requests.get(url, headers=self.headers)
- response.raise_for_status()
+ # Step 2: Generate deliverable
+ print("\n📝 Step 2: Generating document...")
+ deliverable = generate_deliverable(template['id'])
- print(f"✅ File ready for download: {filename}")
- print(f"📁 Content-Type: {response.headers.get('content-type')}")
- print(f"📊 Content-Length: {response.headers.get('content-length')} bytes")
+ # Step 3: Download file
+ print("\n📥 Step 3: Downloading file...")
+ download_info = download_file(deliverable['id'], f"{deliverable['name']}.docx")
- # In a real application, you would save the file
- # with open(filename, 'wb') as f:
- # f.write(response.content)
+ print("\n✅ Workflow complete!")
+ print(f"Template: {template['id']}")
+ print(f"Document: {deliverable['id']}")
+ print(f"File: {download_info['filename']}")
return {
- 'filename': filename,
- 'content_type': response.headers.get('content-type'),
- 'content_length': response.headers.get('content-length')
+ 'template': template,
+ 'deliverable': deliverable,
+ 'download_info': download_info
}
- # ===============================
- # DEMO FUNCTIONS
- # ===============================
-
- def demo_path_a(self, template_file_path):
- """Demo Path A workflow"""
- print("🚀 DEMO: Path A - Upload New Template Workflow")
- print("=" * 45)
- print()
-
- return self.path_a_upload_and_generate(
- template_file_path,
- 'Contract Generated via Path A - API Upload'
- )
-
- def demo_path_b(self):
- """Demo Path B workflow"""
- print("🚀 DEMO: Path B - Browse Existing Template Workflow")
- print("=" * 51)
- print()
-
- return self.path_b_browse_and_generate(
- 'contract',
- 'Contract Generated via Path B - Browse & Select'
- )
-
- def demo_comparison(self):
- """Demo comparison of both workflows"""
- print("🚀 DEMO: Complete Workflow Comparison")
- print("=" * 36)
- print()
-
- try:
- print("Testing both paths with the same template type...\n")
-
- # Run Path B first (browse existing)
- path_b_result = self.demo_path_b()
-
- print("\n" + "=" * 60 + "\n")
-
- # For Path A, we'd need a template file
- print("📝 Path A requires a template file to upload.")
- print(" Example: workflow.demo_path_a('./contract-template.docx')")
-
- return {'path_b': path_b_result}
-
- except Exception as error:
- print(f"Demo comparison failed: {error}")
-
-def run_examples():
- """Run example workflows"""
- workflow = TemplateWorkflowManager(API_TOKEN, ORG_ID, BASE_URL)
+ except Exception as error:
+ print(f"❌ Workflow failed: {error}")
+ raise
+# Example usage
+def example():
try:
- # Demo Path B (Browse existing templates)
- workflow.demo_path_b()
-
- # Uncomment to demo Path A (requires template file):
- # workflow.demo_path_a('./path/to/your/template.docx')
-
- # Uncomment to run full comparison:
- # workflow.demo_comparison()
-
+ # Replace with your template file path
+ template_path = './template.docx'
+ complete_workflow(template_path)
except Exception as error:
- print(f"Workflow demo failed: {error}")
+ print(f"Example failed: {error}")
-# Example usage
if __name__ == "__main__":
- run_examples()
\ No newline at end of file
+ example()
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/python/flask.py b/static/scripts/templates/api/complete-workflows/python/flask.py
index 634dff5..cd972fc 100644
--- a/static/scripts/templates/api/complete-workflows/python/flask.py
+++ b/static/scripts/templates/api/complete-workflows/python/flask.py
@@ -1,418 +1,157 @@
import requests
-import json
-import uuid
import os
-from datetime import datetime
-from urllib.parse import urlencode
# Configuration - Update these values
API_TOKEN = "YOUR_API_TOKEN"
ORG_ID = "YOUR_ORGANIZATION_ID"
BASE_URL = "https://api.turbodocx.com"
-class TemplateWorkflowManager:
- """
- Complete Template Generation Workflows
- Demonstrates both Path A (Upload) and Path B (Browse/Select) followed by generation
- """
+"""
+Complete Workflow: Upload → Generate → Download
+Simple 3-step process for document generation
+"""
- def __init__(self, api_token, org_id, base_url):
- self.api_token = api_token
- self.org_id = org_id
- self.base_url = base_url
- self.headers = {
- 'Authorization': f'Bearer {api_token}',
- 'x-rapiddocx-org-id': org_id,
- 'User-Agent': 'TurboDocx API Client'
- }
-
- # ===============================
- # PATH A: Upload New Template
- # ===============================
-
- def path_a_upload_and_generate(self, template_file_path, deliverable_name):
- """Complete Path A workflow: Upload → Generate"""
- print("🔄 PATH A: Upload New Template → Generate Deliverable")
- print("=" * 48)
-
- try:
- # Step 1: Upload and create template
- print("\n📤 Step 1: Uploading template...")
- template = self.upload_template(template_file_path)
-
- # Step 2: Generate deliverable using uploaded template
- print("\n📝 Step 2: Generating deliverable...")
- deliverable = self.generate_deliverable(template['id'], {
- 'name': deliverable_name,
- 'description': f"Generated from uploaded template: {template['name']}",
- 'variables': self.create_variables_from_template(template['variables'])
- })
-
- print("\n✅ PATH A COMPLETE!")
- print(f"Template ID: {template['id']}")
- print(f"Deliverable ID: {deliverable['id']}")
-
- # Download the generated file
- self.download_deliverable(deliverable['id'], f"{deliverable['name']}.docx")
-
- return {'template': template, 'deliverable': deliverable}
-
- except Exception as error:
- print(f"❌ Path A failed: {error}")
- raise
+# Step 1: Upload template file
+def upload_template(template_file_path):
+ url = f"{BASE_URL}/template/upload-and-create"
- def upload_template(self, template_file_path):
- """Upload a template file and create template record"""
- if not os.path.exists(template_file_path):
- raise FileNotFoundError(f"Template file not found: {template_file_path}")
-
- url = f"{self.base_url}/template/upload-and-create"
-
- files = {
- 'templateFile': (
- os.path.basename(template_file_path),
- open(template_file_path, 'rb'),
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- )
- }
+ headers = {
+ 'Authorization': f'Bearer {API_TOKEN}',
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client'
+ }
+ with open(template_file_path, 'rb') as file:
+ files = {'templateFile': file}
data = {
- 'name': 'API Upload Template',
- 'description': 'Template uploaded via API for testing',
- 'variables': '[]',
- 'tags': '["api", "test", "upload"]'
- }
-
- try:
- response = requests.post(url, headers=self.headers, files=files, data=data)
- response.raise_for_status()
-
- result = response.json()
- template = result['data']['results']['template']
-
- print(f"✅ Template uploaded: {template['name']} ({template['id']})")
- print(f"📊 Variables extracted: {len(template['variables']) if template['variables'] else 0}")
- print(f"🔤 Default font: {template['defaultFont']}")
- print(f"📝 Fonts used: {len(template['fonts']) if template['fonts'] else 0}")
-
- return template
-
- finally:
- files['templateFile'][1].close()
-
- # ===============================
- # PATH B: Browse and Select
- # ===============================
-
- def path_b_browse_and_generate(self, search_query, deliverable_name):
- """Complete Path B workflow: Browse → Select → Generate"""
- print("🔍 PATH B: Browse Existing Templates → Generate Deliverable")
- print("=" * 56)
-
- try:
- # Step 1: Browse templates
- print("\n🔍 Step 1: Browsing templates...")
- browse_result = self.browse_templates({'query': search_query})
-
- # Step 2: Select first available template
- selected_template = None
- for item in browse_result['results']:
- if item['type'] == 'template':
- selected_template = item
- break
-
- if not selected_template:
- raise Exception('No templates found in browse results')
-
- print(f"📋 Selected: {selected_template['name']} ({selected_template['id']})")
-
- # Step 3: Get template details
- print("\n📖 Step 2: Getting template details...")
- template_details = self.get_template_details(selected_template['id'])
-
- # Step 4: Get PDF preview (optional)
- print("\n🖼️ Step 3: Getting PDF preview...")
- pdf_preview = self.get_template_pdf_preview(selected_template['id'])
-
- # Step 5: Generate deliverable
- print("\n📝 Step 4: Generating deliverable...")
- deliverable = self.generate_deliverable(template_details['id'], {
- 'name': deliverable_name,
- 'description': f"Generated from existing template: {template_details['name']}",
- 'variables': self.create_variables_from_template(template_details['variables'])
- })
-
- print("\n✅ PATH B COMPLETE!")
- print(f"Template ID: {template_details['id']}")
- print(f"Deliverable ID: {deliverable['id']}")
-
- # Download the generated file
- self.download_deliverable(deliverable['id'], f"{deliverable['name']}.docx")
-
- return {
- 'template': template_details,
- 'deliverable': deliverable,
- 'pdf_preview': pdf_preview
- }
-
- except Exception as error:
- print(f"❌ Path B failed: {error}")
- raise
-
- def browse_templates(self, options=None):
- """Browse available templates and folders"""
- if options is None:
- options = {}
-
- params = {
- 'limit': options.get('limit', 25),
- 'offset': options.get('offset', 0),
- 'showTags': str(options.get('show_tags', True)).lower()
+ 'name': 'Simple Template',
+ 'description': 'Template uploaded for document generation'
}
- query = options.get('query', '')
- if query:
- params['query'] = query
-
- url = f"{self.base_url}/template-item?{urlencode(params)}"
-
- response = requests.get(url, headers=self.headers)
- response.raise_for_status()
-
- result = response.json()
- data = result['data']
-
- print(f"🔍 Found {data['totalRecords']} templates/folders")
-
- return data
-
- def get_template_details(self, template_id):
- """Get detailed template information"""
- url = f"{self.base_url}/template/{template_id}"
-
- response = requests.get(url, headers=self.headers)
- response.raise_for_status()
-
- result = response.json()
- template = result['data']['results']
-
- print(f"📊 Variables: {len(template['variables'])}")
- print(f"🔤 Default font: {template.get('defaultFont', 'N/A')}")
-
- return template
-
- def get_template_pdf_preview(self, template_id):
- """Get PDF preview URL for template"""
- url = f"{self.base_url}/template/{template_id}/previewpdflink"
-
- response = requests.get(url, headers=self.headers)
- response.raise_for_status()
-
- result = response.json()
- pdf_url = result['results']
-
- print(f"🖼️ PDF Preview available: {pdf_url}")
-
- return pdf_url
-
- # ===============================
- # COMMON: Generate Deliverable
- # ===============================
-
- def generate_deliverable(self, template_id, deliverable_data):
- """Generate a deliverable document from template"""
- payload = {
- "templateId": template_id,
- "name": deliverable_data['name'],
- "description": deliverable_data.get('description', ''),
- "variables": deliverable_data['variables'],
- "tags": deliverable_data.get('tags', ['api-generated']),
- "fonts": deliverable_data.get('fonts', '[]'),
- "defaultFont": deliverable_data.get('defaultFont', 'Arial'),
- "replaceFonts": deliverable_data.get('replaceFonts', True),
- "metadata": deliverable_data.get('metadata', {
- "sessions": [{
- "id": self.generate_session_id(),
- "starttime": datetime.utcnow().isoformat() + "Z",
- "endtime": datetime.utcnow().isoformat() + "Z"
- }],
- "workflow": "API Complete Workflow",
- "generated": datetime.utcnow().isoformat() + "Z"
- })
+ response = requests.post(url, headers=headers, files=files, data=data)
+
+ if not response.ok:
+ raise Exception(f"Upload failed: {response.status_code}")
+
+ result = response.json()
+ template = result['data']['results']['template']
+
+ print(f"✅ Template uploaded: {template['name']} ({template['id']})")
+ return template
+
+# Step 2: Generate deliverable with simple variables
+def generate_deliverable(template_id):
+ variables = [
+ {
+ "mimeType": "text",
+ "name": "Company Name",
+ "placeholder": "{CompanyName}",
+ "text": "Acme Corporation"
+ },
+ {
+ "mimeType": "text",
+ "name": "Employee Name",
+ "placeholder": "{EmployeeName}",
+ "text": "John Smith"
+ },
+ {
+ "mimeType": "text",
+ "name": "Date",
+ "placeholder": "{Date}",
+ "text": "January 15, 2024"
}
+ ]
- url = f"{self.base_url}/deliverable"
- headers = {**self.headers, 'Content-Type': 'application/json'}
+ payload = {
+ "templateId": template_id,
+ "name": "Generated Document",
+ "description": "Simple document example",
+ "variables": variables
+ }
- response = requests.post(url, headers=headers, json=payload)
- response.raise_for_status()
+ headers = {
+ 'Authorization': f'Bearer {API_TOKEN}',
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client',
+ 'Content-Type': 'application/json'
+ }
- result = response.json()
- deliverable = result['data']['results']['deliverable']
+ response = requests.post(f"{BASE_URL}/deliverable", headers=headers, json=payload)
- print(f"✅ Generated: {deliverable['name']}")
- print(f"📄 Created by: {deliverable['createdBy']}")
- print(f"📅 Created on: {deliverable['createdOn']}")
+ if not response.ok:
+ raise Exception(f"Generation failed: {response.status_code}")
- return deliverable
+ result = response.json()
+ deliverable = result['data']['results']['deliverable']
- # ===============================
- # UTILITY FUNCTIONS
- # ===============================
+ print(f"✅ Document generated: {deliverable['name']} ({deliverable['id']})")
+ return deliverable
- def create_variables_from_template(self, template_variables):
- """Create variable payload from template variable definitions"""
- return [
- {
- "mimeType": variable.get('mimeType', 'text'),
- "name": variable['name'],
- "placeholder": variable['placeholder'],
- "text": self.generate_sample_text(variable['name']),
- "allowRichTextInjection": variable.get('allowRichTextInjection', 0),
- "autogenerated": False,
- "count": 1,
- "order": index + 1,
- "subvariables": self.create_sample_subvariables(variable['placeholder']),
- "metadata": {
- "generatedBy": "API Workflow",
- "variableType": variable.get('mimeType', 'text')
- },
- "aiPrompt": f"Generate appropriate content for {variable['name']}"
- }
- for index, variable in enumerate(template_variables)
- ]
+# Step 3: Download generated file
+def download_file(deliverable_id, filename):
+ headers = {
+ 'Authorization': f'Bearer {API_TOKEN}',
+ 'x-rapiddocx-org-id': ORG_ID,
+ 'User-Agent': 'TurboDocx API Client'
+ }
- def generate_sample_text(self, variable_name):
- """Generate sample text based on variable name"""
- sample_data = {
- 'company': 'TechCorp Solutions Inc.',
- 'employee': 'John Smith',
- 'date': datetime.now().strftime('%B %d, %Y'),
- 'title': 'Senior Software Engineer',
- 'department': 'Engineering',
- 'salary': '$95,000',
- 'address': '123 Main Street, Tech City, TC 12345',
- 'phone': '(555) 123-4567',
- 'email': 'john.smith@techcorp.com'
- }
-
- # Find matching sample data or generate generic text
- for key, value in sample_data.items():
- if key.lower() in variable_name.lower():
- return value
+ response = requests.get(f"{BASE_URL}/deliverable/file/{deliverable_id}", headers=headers)
- return f"Sample {variable_name} Content"
+ if not response.ok:
+ raise Exception(f"Download failed: {response.status_code}")
- def create_sample_subvariables(self, placeholder):
- """Create relevant subvariables based on placeholder name"""
- placeholder_lower = placeholder.lower()
+ print(f"✅ File ready for download: {filename}")
- if 'employee' in placeholder_lower:
- return [
- {"placeholder": "{Employee.Title}", "text": "Senior Software Engineer"},
- {"placeholder": "{Employee.StartDate}", "text": datetime.now().strftime('%B %d, %Y')}
- ]
- elif 'company' in placeholder_lower:
- return [
- {"placeholder": "{Company.Address}", "text": "123 Main Street, Tech City, TC 12345"},
- {"placeholder": "{Company.Phone}", "text": "(555) 123-4567"}
- ]
+ # In a real application, you would save the file:
+ # with open(filename, 'wb') as f:
+ # f.write(response.content)
- return []
+ return {
+ 'filename': filename,
+ 'content_type': response.headers.get('content-type'),
+ 'content_length': response.headers.get('content-length')
+ }
- def generate_session_id(self):
- """Generate a unique session ID"""
- return str(uuid.uuid4())
-
- def download_deliverable(self, deliverable_id, filename):
- """Download the generated deliverable file"""
- print(f"\n📥 Downloading file: {filename}")
+# Complete workflow: Upload → Generate → Download
+def complete_workflow(template_file_path):
+ try:
+ print("🚀 Starting complete workflow...")
- url = f"{self.base_url}/deliverable/file/{deliverable_id}"
+ # Step 1: Upload template
+ print("\n📤 Step 1: Uploading template...")
+ template = upload_template(template_file_path)
- response = requests.get(url, headers=self.headers)
- response.raise_for_status()
+ # Step 2: Generate deliverable
+ print("\n📝 Step 2: Generating document...")
+ deliverable = generate_deliverable(template['id'])
- print(f"✅ File ready for download: {filename}")
- print(f"📁 Content-Type: {response.headers.get('content-type')}")
- print(f"📊 Content-Length: {response.headers.get('content-length')} bytes")
+ # Step 3: Download file
+ print("\n📥 Step 3: Downloading file...")
+ download_info = download_file(deliverable['id'], f"{deliverable['name']}.docx")
- # In a real application, you would save the file
- # with open(filename, 'wb') as f:
- # f.write(response.content)
+ print("\n✅ Workflow complete!")
+ print(f"Template: {template['id']}")
+ print(f"Document: {deliverable['id']}")
+ print(f"File: {download_info['filename']}")
return {
- 'filename': filename,
- 'content_type': response.headers.get('content-type'),
- 'content_length': response.headers.get('content-length')
+ 'template': template,
+ 'deliverable': deliverable,
+ 'download_info': download_info
}
- # ===============================
- # DEMO FUNCTIONS
- # ===============================
-
- def demo_path_a(self, template_file_path):
- """Demo Path A workflow"""
- print("🚀 DEMO: Path A - Upload New Template Workflow")
- print("=" * 45)
- print()
-
- return self.path_a_upload_and_generate(
- template_file_path,
- 'Contract Generated via Path A - API Upload'
- )
-
- def demo_path_b(self):
- """Demo Path B workflow"""
- print("🚀 DEMO: Path B - Browse Existing Template Workflow")
- print("=" * 51)
- print()
-
- return self.path_b_browse_and_generate(
- 'contract',
- 'Contract Generated via Path B - Browse & Select'
- )
-
- def demo_comparison(self):
- """Demo comparison of both workflows"""
- print("🚀 DEMO: Complete Workflow Comparison")
- print("=" * 36)
- print()
-
- try:
- print("Testing both paths with the same template type...\n")
-
- # Run Path B first (browse existing)
- path_b_result = self.demo_path_b()
-
- print("\n" + "=" * 60 + "\n")
-
- # For Path A, we'd need a template file
- print("📝 Path A requires a template file to upload.")
- print(" Example: workflow.demo_path_a('./contract-template.docx')")
-
- return {'path_b': path_b_result}
-
- except Exception as error:
- print(f"Demo comparison failed: {error}")
-
-def run_examples():
- """Run example workflows"""
- workflow = TemplateWorkflowManager(API_TOKEN, ORG_ID, BASE_URL)
+ except Exception as error:
+ print(f"❌ Workflow failed: {error}")
+ raise
+# Example usage
+def example():
try:
- # Demo Path B (Browse existing templates)
- workflow.demo_path_b()
-
- # Uncomment to demo Path A (requires template file):
- # workflow.demo_path_a('./path/to/your/template.docx')
-
- # Uncomment to run full comparison:
- # workflow.demo_comparison()
-
+ # Replace with your template file path
+ template_path = './template.docx'
+ complete_workflow(template_path)
except Exception as error:
- print(f"Workflow demo failed: {error}")
+ print(f"Example failed: {error}")
-# Example usage
if __name__ == "__main__":
- run_examples()
\ No newline at end of file
+ example()
\ No newline at end of file
diff --git a/static/scripts/templates/api/complete-workflows/ruby.rb b/static/scripts/templates/api/complete-workflows/ruby.rb
index fa14b81..6da68e1 100644
--- a/static/scripts/templates/api/complete-workflows/ruby.rb
+++ b/static/scripts/templates/api/complete-workflows/ruby.rb
@@ -1,10 +1,6 @@
require 'net/http'
require 'uri'
require 'json'
-require 'cgi'
-require 'securerandom'
-require 'time'
-require 'mime/types'
# Configuration - Update these values
API_TOKEN = "YOUR_API_TOKEN"
@@ -12,8 +8,8 @@
BASE_URL = "https://api.turbodocx.com"
##
-# Complete Template Workflow Manager
-# Demonstrates both upload and browse/select paths
+# Complete Workflow: Upload → Generate → Download
+# Simple 3-step process for document generation
##
class TemplateWorkflowManager
@@ -21,116 +17,12 @@ def initialize
puts "=== TurboDocx Template Generation Workflow Manager ==="
end
- def demonstrate_complete_workflow
- puts "\nSelect workflow path:"
- puts "A) Upload new template"
- puts "B) Browse and select existing template"
-
- # For this example, we'll demonstrate both paths
- puts "\n=== Demonstrating Path A: Upload Template ==="
- template_id_a = demonstrate_upload_workflow
-
- puts "\n=== Demonstrating Path B: Browse Templates ==="
- template_id_b = demonstrate_browse_workflow
-
- # Generate deliverables for both templates if successful
- if template_id_a
- puts "\n=== Generating Deliverable from Uploaded Template ==="
- generate_and_download_deliverable(template_id_a, "A")
- end
-
- if template_id_b
- puts "\n=== Generating Deliverable from Selected Template ==="
- generate_and_download_deliverable(template_id_b, "B")
- end
- end
-
- private
-
- def demonstrate_upload_workflow
- begin
- puts "\n--- Path A: Upload and Create Template ---"
-
- # Check for template file
- template_file = "./contract-template.docx"
- unless File.exist?(template_file)
- puts "⚠️ Template file not found: #{template_file}"
- puts "Creating a placeholder message for demonstration"
- return nil
- end
-
- result = upload_template(template_file)
- template = result['data']['results']['template']
-
- puts "✅ Upload workflow completed"
- puts "Template ID: #{template['id']}"
- puts "Ready for deliverable generation"
-
- template['id']
- rescue => e
- puts "❌ Upload workflow failed: #{e.message}"
- nil
- end
- end
-
- def demonstrate_browse_workflow
- begin
- puts "\n--- Path B: Browse and Select Template ---"
-
- # Browse templates
- browse_result = browse_templates(10, 0, 'contract', true)
-
- # Find first template (not folder)
- selected_template = browse_result['results'].find { |item| item['type'] == 'template' }
-
- if selected_template.nil?
- puts "⚠️ No templates found in browse results"
- return nil
- end
-
- puts "Selected: #{selected_template['name']}"
-
- # Get detailed information
- template_details = get_template_details(selected_template['id'])
-
- # Optionally get PDF preview
- pdf_preview = get_template_pdf_preview(selected_template['id'])
-
- puts "✅ Browse workflow completed"
- puts "Template ID: #{template_details['id']}"
- puts "PDF Preview: #{pdf_preview}"
- puts "Ready for deliverable generation"
-
- template_details['id']
- rescue => e
- puts "❌ Browse workflow failed: #{e.message}"
- nil
- end
- end
-
- def generate_and_download_deliverable(template_id, path_label)
- begin
- puts "\n--- Generating Deliverable (Path #{path_label}) ---"
-
- deliverable_data = create_deliverable_data(template_id, path_label)
- deliverable = generate_deliverable(template_id, deliverable_data)
-
- # Download the file
- download_result = download_deliverable(
- deliverable['id'],
- "#{deliverable['name']}_path_#{path_label}.docx"
- )
-
- puts "✅ Complete workflow finished successfully for Path #{path_label}"
- puts "Deliverable ID: #{deliverable['id']}"
- puts "Download info: #{download_result}"
-
- rescue => e
- puts "❌ Deliverable generation failed for Path #{path_label}: #{e.message}"
+ # Step 1: Upload template file
+ def upload_template(template_file_path)
+ unless File.exist?(template_file_path)
+ raise "Template file not found: #{template_file_path}"
end
- end
- def upload_template(template_file_path)
uri = URI("#{BASE_URL}/template/upload-and-create")
boundary = "----RubyBoundary#{rand(1000000)}"
@@ -139,29 +31,19 @@ def upload_template(template_file_path)
# Template file field
form_data << "--#{boundary}\r\n"
- form_data << "Content-Disposition: form-data; name=\"templateFile\"; filename=\"#{File.basename(template_file_path)}\"\r\n"
- form_data << "Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document\r\n\r\n"
+ form_data << "Content-Disposition: form-data; name=\"templateFile\"; filename=\"template.docx\"\r\n"
+ form_data << "Content-Type: application/octet-stream\r\n\r\n"
form_data << File.read(template_file_path)
# Name field
form_data << "\r\n--#{boundary}\r\n"
form_data << "Content-Disposition: form-data; name=\"name\"\r\n\r\n"
- form_data << "Employee Contract Template"
+ form_data << "Simple Template"
# Description field
form_data << "\r\n--#{boundary}\r\n"
form_data << "Content-Disposition: form-data; name=\"description\"\r\n\r\n"
- form_data << "Standard employee contract with variable placeholders"
-
- # Variables field
- form_data << "\r\n--#{boundary}\r\n"
- form_data << "Content-Disposition: form-data; name=\"variables\"\r\n\r\n"
- form_data << "[]"
-
- # Tags field
- form_data << "\r\n--#{boundary}\r\n"
- form_data << "Content-Disposition: form-data; name=\"tags\"\r\n\r\n"
- form_data << '["hr", "contract", "template"]'
+ form_data << "Template uploaded for document generation"
form_data << "\r\n--#{boundary}--\r\n"
@@ -181,99 +63,46 @@ def upload_template(template_file_path)
response = http.request(request)
unless response.code == '200'
- raise "HTTP error #{response.code}: #{response.body}"
- end
-
- JSON.parse(response.body)
- end
-
- def browse_templates(limit = 25, offset = 0, query = '', show_tags = true, selected_tags = nil)
- # Build query parameters
- params = {
- 'limit' => limit.to_s,
- 'offset' => offset.to_s,
- 'showTags' => show_tags.to_s
- }
-
- params['query'] = query unless query.empty?
-
- if selected_tags
- selected_tags.each do |tag|
- params["selectedTags[]"] = tag
- end
+ raise "Upload failed: #{response.code}"
end
- query_string = params.map { |k, v| "#{CGI.escape(k)}=#{CGI.escape(v)}" }.join('&')
- uri = URI("#{BASE_URL}/template-item?#{query_string}")
-
- # Create HTTP connection
- http = Net::HTTP.new(uri.host, uri.port)
- http.use_ssl = true
-
- # Create request
- request = Net::HTTP::Get.new(uri)
- request['Authorization'] = "Bearer #{API_TOKEN}"
- request['x-rapiddocx-org-id'] = ORG_ID
- request['User-Agent'] = 'TurboDocx API Client'
-
- # Make request
- response = http.request(request)
-
- unless response.code == '200'
- raise "HTTP error #{response.code}: #{response.body}"
- end
-
- JSON.parse(response.body)['data']
- end
-
- def get_template_details(template_id)
- uri = URI("#{BASE_URL}/template/#{template_id}")
-
- http = Net::HTTP.new(uri.host, uri.port)
- http.use_ssl = true
-
- request = Net::HTTP::Get.new(uri)
- request['Authorization'] = "Bearer #{API_TOKEN}"
- request['x-rapiddocx-org-id'] = ORG_ID
- request['User-Agent'] = 'TurboDocx API Client'
-
- response = http.request(request)
-
- unless response.code == '200'
- raise "HTTP error #{response.code}: #{response.body}"
- end
+ result = JSON.parse(response.body)
+ template = result['data']['results']['template']
- JSON.parse(response.body)['data']['results']
+ puts "✅ Template uploaded: #{template['name']} (#{template['id']})"
+ template
end
- def get_template_pdf_preview(template_id)
- uri = URI("#{BASE_URL}/template/#{template_id}/previewpdflink")
-
- http = Net::HTTP.new(uri.host, uri.port)
- http.use_ssl = true
-
- request = Net::HTTP::Get.new(uri)
- request['Authorization'] = "Bearer #{API_TOKEN}"
- request['x-rapiddocx-org-id'] = ORG_ID
- request['User-Agent'] = 'TurboDocx API Client'
-
- response = http.request(request)
-
- unless response.code == '200'
- raise "HTTP error #{response.code}: #{response.body}"
- end
-
- JSON.parse(response.body)['results']
- end
+ # Step 2: Generate deliverable with simple variables
+ def generate_deliverable(template_id)
+ payload = {
+ 'templateId' => template_id,
+ 'name' => 'Generated Document',
+ 'description' => 'Simple document example',
+ 'variables' => [
+ {
+ 'mimeType' => 'text',
+ 'name' => 'Company Name',
+ 'placeholder' => '{CompanyName}',
+ 'text' => 'Acme Corporation'
+ },
+ {
+ 'mimeType' => 'text',
+ 'name' => 'Employee Name',
+ 'placeholder' => '{EmployeeName}',
+ 'text' => 'John Smith'
+ },
+ {
+ 'mimeType' => 'text',
+ 'name' => 'Date',
+ 'placeholder' => '{Date}',
+ 'text' => 'January 15, 2024'
+ }
+ ]
+ }
- def generate_deliverable(template_id, deliverable_data)
uri = URI("#{BASE_URL}/deliverable")
- puts "Generating deliverable..."
- puts "Template ID: #{template_id}"
- puts "Deliverable Name: #{deliverable_data['name']}"
- puts "Variables: #{deliverable_data['variables'].length}"
-
# Create HTTP connection
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
@@ -284,33 +113,24 @@ def generate_deliverable(template_id, deliverable_data)
request['x-rapiddocx-org-id'] = ORG_ID
request['User-Agent'] = 'TurboDocx API Client'
request['Content-Type'] = 'application/json'
-
- # Set request body
- request.body = deliverable_data.to_json
+ request.body = payload.to_json
# Make request
response = http.request(request)
unless response.code == '200'
- raise "HTTP error #{response.code}: #{response.body}"
+ raise "Generation failed: #{response.code}"
end
- # Parse JSON response
result = JSON.parse(response.body)
deliverable = result['data']['results']['deliverable']
- puts "✅ Deliverable generated successfully!"
- puts "Deliverable ID: #{deliverable['id']}"
- puts "Created by: #{deliverable['createdBy']}"
- puts "Created on: #{deliverable['createdOn']}"
- puts "Template ID: #{deliverable['templateId']}"
-
+ puts "✅ Document generated: #{deliverable['name']} (#{deliverable['id']})"
deliverable
end
- def download_deliverable(deliverable_id, filename)
- puts "Downloading file: #{filename}"
-
+ # Step 3: Download generated file
+ def download_file(deliverable_id, filename)
uri = URI("#{BASE_URL}/deliverable/file/#{deliverable_id}")
http = Net::HTTP.new(uri.host, uri.port)
@@ -329,115 +149,43 @@ def download_deliverable(deliverable_id, filename)
puts "✅ File ready for download: #{filename}"
- content_type = response['Content-Type'] || 'N/A'
- content_length = response['Content-Length'] || 'N/A'
-
- puts "📁 Content-Type: #{content_type}"
- puts "📊 Content-Length: #{content_length} bytes"
-
- # In a real application, you would save the file
+ # In a real application, you would save the file:
# File.write(filename, response.body)
-
- {
- 'filename' => filename,
- 'content_type' => content_type,
- 'content_length' => content_length
- }
end
- def create_deliverable_data(template_id, path_label)
- now = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S.%3NZ')
+ # Complete workflow: Upload → Generate → Download
+ def complete_workflow(template_file_path)
+ puts "🚀 Starting complete workflow..."
- {
- 'templateId' => template_id,
- 'name' => "Contract Document - Path #{path_label}",
- 'description' => "Employment contract generated via workflow path #{path_label}",
- 'variables' => create_complex_variables,
- 'tags' => ['hr', 'contract', 'employee', 'engineering'],
- 'fonts' => '[{"name":"Arial","usage":269}]',
- 'defaultFont' => 'Arial',
- 'replaceFonts' => true,
- 'metadata' => {
- 'sessions' => [
- {
- 'id' => SecureRandom.uuid,
- 'starttime' => now,
- 'endtime' => now
- }
- ],
- 'createdBy' => 'Ruby Workflow Manager',
- 'documentType' => 'Employment Contract',
- 'version' => 'v1.0',
- 'workflowPath' => path_label
- }
- }
- end
+ # Step 1: Upload template
+ puts "\n📤 Step 1: Uploading template..."
+ template = upload_template(template_file_path)
- def create_complex_variables
- [
- {
- 'mimeType' => 'text',
- 'name' => 'Employee Name',
- 'placeholder' => '{EmployeeName}',
- 'text' => 'John Smith',
- 'allowRichTextInjection' => 0,
- 'autogenerated' => false,
- 'count' => 1,
- 'order' => 1,
- 'subvariables' => [
- {
- 'placeholder' => '{EmployeeName.Title}',
- 'text' => 'Senior Software Engineer'
- },
- {
- 'placeholder' => '{EmployeeName.StartDate}',
- 'text' => 'January 15, 2024'
- }
- ],
- 'metadata' => {
- 'department' => 'Engineering',
- 'level' => 'Senior'
- },
- 'aiPrompt' => 'Generate a professional job description for a senior software engineer role'
- },
- {
- 'mimeType' => 'text',
- 'name' => 'Company Information',
- 'placeholder' => '{CompanyInfo}',
- 'text' => 'TechCorp Solutions Inc.',
- 'allowRichTextInjection' => 1,
- 'autogenerated' => false,
- 'count' => 1,
- 'order' => 2,
- 'subvariables' => [
- {
- 'placeholder' => '{CompanyInfo.Address}',
- 'text' => '123 Innovation Drive, Tech City, TC 12345'
- },
- {
- 'placeholder' => '{CompanyInfo.Phone}',
- 'text' => '(555) 123-4567'
- }
- ],
- 'metadata' => {},
- 'aiPrompt' => ''
- }
- ]
+ # Step 2: Generate deliverable
+ puts "\n📝 Step 2: Generating document..."
+ deliverable = generate_deliverable(template['id'])
+
+ # Step 3: Download file
+ puts "\n📥 Step 3: Downloading file..."
+ filename = "#{deliverable['name']}.docx"
+ download_file(deliverable['id'], filename)
+
+ puts "\n✅ Workflow complete!"
+ puts "Template: #{template['id']}"
+ puts "Document: #{deliverable['id']}"
+ puts "File: #{filename}"
end
end
# Example usage
begin
workflow_manager = TemplateWorkflowManager.new
- workflow_manager.demonstrate_complete_workflow
- puts "\n=== Workflow Demonstration Complete ==="
- puts "Both upload and browse/select paths have been demonstrated."
- puts "Choose the appropriate path for your use case:"
- puts "- Upload path: When you have new templates to create"
- puts "- Browse path: When you want to use existing templates"
+ # Replace with your template file path
+ template_path = "./template.docx"
+ workflow_manager.complete_workflow(template_path)
rescue => e
- puts "Workflow demonstration failed: #{e.message}"
+ puts "❌ Workflow failed: #{e.message}"
exit 1
end
\ No newline at end of file
diff --git a/static/scripts/templates/api/file-attachment-examples/csharp/controller.cs b/static/scripts/templates/api/file-attachment-examples/csharp/controller.cs
new file mode 100644
index 0000000..2557c5d
--- /dev/null
+++ b/static/scripts/templates/api/file-attachment-examples/csharp/controller.cs
@@ -0,0 +1,373 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System.Text.Json;
+
+namespace TurboDocxFileAttachment.Controllers
+{
+ [ApiController]
+ [Route("api/[controller]")]
+ public class TemplateUploadController : ControllerBase
+ {
+ // Configuration - Update these values
+ private const string API_TOKEN = "YOUR_API_TOKEN";
+ private const string ORG_ID = "YOUR_ORGANIZATION_ID";
+ private const string BASE_URL = "https://api.turbodocx.com";
+
+ private readonly HttpClient _httpClient;
+ private readonly ILogger _logger;
+
+ public TemplateUploadController(HttpClient httpClient, ILogger logger)
+ {
+ _httpClient = httpClient;
+ _logger = logger;
+
+ // Configure HTTP client
+ _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {API_TOKEN}");
+ _httpClient.DefaultRequestHeaders.Add("x-rapiddocx-org-id", ORG_ID);
+ _httpClient.DefaultRequestHeaders.Add("User-Agent", "TurboDocx C# Controller Client");
+ }
+
+ ///
+ /// Upload template with Excel data file attachment and sheet selection
+ ///
+ [HttpPost("upload-with-data")]
+ public async Task UploadTemplateWithDataFile(
+ [FromForm] IFormFile templateFile,
+ [FromForm] IFormFile dataFile,
+ [FromForm] string templateName = "C# Controller Template",
+ [FromForm] string templateDescription = "Template uploaded via C# Controller",
+ [FromForm] string selectedSheet = "Sheet1",
+ [FromForm] string dataRange = "A1:F50",
+ [FromForm] string aiHint = "")
+ {
+ try
+ {
+ // Validate input
+ if (templateFile == null || dataFile == null)
+ {
+ return BadRequest(new { error = "Both templateFile and dataFile are required" });
+ }
+
+ if (templateFile.Length == 0 || dataFile.Length == 0)
+ {
+ return BadRequest(new { error = "Both files must have content" });
+ }
+
+ // Generate unique data file ID
+ var dataFileId = $"controller-data-{Math.Abs(dataFile.FileName.GetHashCode() % 10000)}";
+
+ // Prepare multipart form content
+ using var formContent = new MultipartFormDataContent();
+
+ // Add template file
+ var templateContent = new StreamContent(templateFile.OpenReadStream());
+ templateContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(
+ templateFile.ContentType ?? "application/octet-stream");
+ formContent.Add(templateContent, "templateFile", templateFile.FileName);
+
+ // Add data file
+ var dataContent = new StreamContent(dataFile.OpenReadStream());
+ dataContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(
+ dataFile.ContentType ?? "application/octet-stream");
+ formContent.Add(dataContent, $"FileResource-{dataFileId}", dataFile.FileName);
+
+ // Sheet selection and data range metadata
+ var fileMetadata = new Dictionary
+ {
+ [dataFileId] = new
+ {
+ selectedSheet = selectedSheet,
+ hasMultipleSheets = true,
+ dataRange = dataRange,
+ description = "C# Controller uploaded data source"
+ }
+ };
+
+ // Add form fields
+ formContent.Add(new StringContent(templateName), "name");
+ formContent.Add(new StringContent(templateDescription), "description");
+ formContent.Add(new StringContent(JsonSerializer.Serialize(fileMetadata)), "fileResourceMetadata");
+ formContent.Add(new StringContent(JsonSerializer.Serialize(new[] { "csharp-controller", "data-enhanced", "file-attachment" })), "tags");
+
+ // Add variables if AI hint is provided
+ if (!string.IsNullOrEmpty(aiHint))
+ {
+ var variables = new[]
+ {
+ new
+ {
+ name = "Controller Generated Content",
+ placeholder = "{ControllerContent}",
+ aiHint = aiHint,
+ dataSourceId = dataFileId
+ },
+ new
+ {
+ name = "Spreadsheet Analysis",
+ placeholder = "{SpreadsheetAnalysis}",
+ aiHint = $"Analyze spreadsheet data from {selectedSheet} sheet, range {dataRange}",
+ dataSourceId = dataFileId
+ }
+ };
+ formContent.Add(new StringContent(JsonSerializer.Serialize(variables)), "variables");
+ }
+
+ _logger.LogInformation("Controller: Uploading template {TemplateFileName}", templateFile.FileName);
+ _logger.LogInformation("Controller: Data source {DataFileName} (Sheet: {SelectedSheet})",
+ dataFile.FileName, selectedSheet);
+ _logger.LogInformation("Controller: Data range: {DataRange}", dataRange);
+
+ // Upload to TurboDocx API
+ var response = await _httpClient.PostAsync($"{BASE_URL}/template/upload-and-create", formContent);
+
+ if (!response.IsSuccessStatusCode)
+ {
+ var errorContent = await response.Content.ReadAsStringAsync();
+ _logger.LogError("TurboDocx API error: {StatusCode} - {ErrorContent}",
+ response.StatusCode, errorContent);
+
+ return StatusCode((int)response.StatusCode, new
+ {
+ error = "TurboDocx API error",
+ detail = errorContent
+ });
+ }
+
+ var resultJson = await response.Content.ReadAsStringAsync();
+ using var document = JsonDocument.Parse(resultJson);
+ var template = document.RootElement.GetProperty("data").GetProperty("results").GetProperty("template");
+
+ var result = new
+ {
+ success = true,
+ message = "Template with data file uploaded successfully via C# Controller",
+ template = new
+ {
+ id = template.GetProperty("id").GetString(),
+ name = template.GetProperty("name").GetString(),
+ variables_count = template.TryGetProperty("variables", out var vars) ? vars.GetArrayLength() : 0,
+ data_sources_count = template.TryGetProperty("dataSources", out var sources) ? sources.GetArrayLength() : 0,
+ default_font = template.TryGetProperty("defaultFont", out var font) ? font.GetString() : "N/A",
+ fonts_count = template.TryGetProperty("fonts", out var fonts) ? fonts.GetArrayLength() : 0
+ },
+ data_source = new
+ {
+ filename = dataFile.FileName,
+ selected_sheet = selectedSheet,
+ data_range = dataRange,
+ file_size_mb = Math.Round(dataFile.Length / 1024.0 / 1024.0, 2)
+ },
+ redirect_url = document.RootElement.GetProperty("data").GetProperty("results").GetProperty("redirectUrl").GetString()
+ };
+
+ _logger.LogInformation("Template uploaded successfully: {TemplateId}", result.template.id);
+ return Ok(result);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error uploading template with data file");
+ return StatusCode(500, new { error = "Upload failed", detail = ex.Message });
+ }
+ }
+
+ ///
+ /// Upload template with multiple sheets from the same Excel file
+ ///
+ [HttpPost("upload-multi-sheet")]
+ public async Task UploadTemplateWithMultipleSheets(
+ [FromForm] IFormFile templateFile,
+ [FromForm] IFormFile dataFile,
+ [FromForm] string templateName = "Multi-Sheet Controller Template",
+ [FromForm] string primarySheet = "Summary",
+ [FromForm] string alternativeSheets = "Revenue,Expenses,Projections")
+ {
+ try
+ {
+ if (templateFile == null || dataFile == null)
+ {
+ return BadRequest(new { error = "Both templateFile and dataFile are required" });
+ }
+
+ // Parse alternative sheets
+ var alternativeSheetsArray = alternativeSheets.Split(',')
+ .Select(s => s.Trim())
+ .Where(s => !string.IsNullOrEmpty(s))
+ .ToArray();
+
+ var dataFileId = $"controller-multisheet-{Math.Abs(dataFile.FileName.GetHashCode() % 10000)}";
+
+ using var formContent = new MultipartFormDataContent();
+
+ // Add files
+ var templateContent = new StreamContent(templateFile.OpenReadStream());
+ templateContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(
+ templateFile.ContentType ?? "application/octet-stream");
+ formContent.Add(templateContent, "templateFile", templateFile.FileName);
+
+ var dataContent = new StreamContent(dataFile.OpenReadStream());
+ dataContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(
+ dataFile.ContentType ?? "application/octet-stream");
+ formContent.Add(dataContent, $"FileResource-{dataFileId}", dataFile.FileName);
+
+ // Define multiple sheet usage
+ var fileMetadata = new Dictionary
+ {
+ [dataFileId] = new
+ {
+ selectedSheet = primarySheet,
+ hasMultipleSheets = true,
+ alternativeSheets = alternativeSheetsArray,
+ dataRange = "A1:Z100",
+ description = "C# Controller multi-sheet data source"
+ }
+ };
+
+ // Variables that reference different sheets
+ var variables = new List