New article to detail how to attach pdf files to a given record (#17128)

- added article to detail how to attach a pdf to a given record
- added link in another article
- updated the english section of the docs.json to have the file appear
in the left menu
- updated the 2 navigation files

---------

Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
StephanieJoly4
2026-01-13 23:49:51 +01:00
committed by GitHub
parent b79056b3a2
commit 25a9d49ff1
5 changed files with 260 additions and 16 deletions
+28 -14
View File
@@ -183,7 +183,8 @@
"user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -624,7 +625,8 @@
"l/fr/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/fr/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/fr/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/fr/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/fr/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/fr/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -1065,7 +1067,8 @@
"l/ar/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/ar/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/ar/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/ar/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/ar/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/ar/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -1506,7 +1509,8 @@
"l/cs/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/cs/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/cs/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/cs/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/cs/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/cs/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -1947,7 +1951,8 @@
"l/de/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/de/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/de/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/de/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/de/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/de/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -2388,7 +2393,8 @@
"l/es/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/es/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/es/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/es/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/es/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/es/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -2829,7 +2835,8 @@
"l/it/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/it/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/it/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/it/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/it/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/it/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -3270,7 +3277,8 @@
"l/ja/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/ja/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/ja/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/ja/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/ja/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/ja/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -3711,7 +3719,8 @@
"l/ko/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/ko/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/ko/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/ko/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/ko/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/ko/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -4152,7 +4161,8 @@
"l/pt/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/pt/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/pt/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/pt/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/pt/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/pt/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -4593,7 +4603,8 @@
"l/ro/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/ro/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/ro/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/ro/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/ro/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/ro/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -5034,7 +5045,8 @@
"l/ru/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/ru/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/ru/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/ru/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/ru/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/ru/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -5475,7 +5487,8 @@
"l/tr/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/tr/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/tr/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/tr/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/tr/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/tr/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -5916,7 +5929,8 @@
"l/zh/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"l/zh/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"l/zh/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"l/zh/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"l/zh/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"l/zh/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -166,7 +166,8 @@
"user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -166,7 +166,8 @@
"user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger",
"user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty",
"user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty",
"user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty"
"user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty",
"user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty"
]
},
{
@@ -0,0 +1,227 @@
---
title: Generate a PDF from Twenty
description: Create a workflow to generate and attach a PDF (such as a quote) to a record.
---
Automatically generate or fetch a PDF and attach it to a record in Twenty. This is commonly used to create quotes, invoices, or reports that are linked to Companies, Opportunities, or other objects.
## Overview
This workflow uses a **Manual Trigger** so users can generate a PDF on demand for any selected record. A **Serverless Function** handles:
1. Downloading the PDF from a URL (from a PDF generation service)
2. Uploading the file to Twenty
3. Creating an Attachment linked to the record
## Prerequisites
Before setting up the workflow:
1. **Create an API Key**: Go to **Settings → APIs** and create a new API key. You'll need this token for the serverless function.
2. **Set up a PDF generation service** (optional): If you want to dynamically generate PDFs (e.g., quotes), use a service like Carbone, PDFMonkey, or DocuSeal to create the PDF and get a download URL.
## Step-by-Step Setup
### Step 1: Configure the Trigger
1. Go to **Workflows** and create a new workflow
2. Select **Manual Trigger**
3. Choose the object you want to attach PDFs to (e.g., **Company** or **Opportunity**)
<Tip>
With a Manual Trigger, users can run this workflow using a button that appears on the top right once a record is selected, to generate and attach a PDF.
</Tip>
### Step 2: Add a Serverless Function
1. Add a **Serverless Function** action
2. Create a new function with the code below
3. Configure the input parameters
#### Input Parameters
| Parameter | Value |
|-----------|-------|
| `companyId` | `{{trigger.object.id}}` |
<Note>
If attaching to a different object (Person, Opportunity, etc.), rename the parameter accordingly (e.g., `personId`, `opportunityId`) and update the serverless function.
</Note>
#### Serverless Function Code
```typescript
export const main = async (
params: { companyId: string },
) => {
const { companyId } = params;
// Replace with your Twenty GraphQL endpoint
// Cloud: https://api.twenty.com/graphql
// Self-hosted: https://your-domain.com/graphql
const graphqlEndpoint = 'https://api.twenty.com/graphql';
// Replace with your API key from Settings → APIs
const authToken = 'YOUR_API_KEY';
// Replace with your PDF URL
// This could be from a PDF generation service or a static URL
const pdfUrl = 'https://your-pdf-service.com/generated-quote.pdf';
const filename = 'quote.pdf';
// Step 1: Download the PDF file
const pdfResponse = await fetch(pdfUrl);
if (!pdfResponse.ok) {
throw new Error(`Failed to download PDF: ${pdfResponse.status}`);
}
const pdfBlob = await pdfResponse.blob();
const pdfFile = new File([pdfBlob], filename, { type: 'application/pdf' });
// Step 2: Upload the file via GraphQL multipart upload
const uploadMutation = `
mutation UploadFile($file: Upload!, $fileFolder: FileFolder) {
uploadFile(file: $file, fileFolder: $fileFolder) {
path
}
}
`;
const uploadForm = new FormData();
uploadForm.append('operations', JSON.stringify({
query: uploadMutation,
variables: { file: null, fileFolder: 'Attachment' },
}));
uploadForm.append('map', JSON.stringify({ '0': ['variables.file'] }));
uploadForm.append('0', pdfFile);
const uploadResponse = await fetch(graphqlEndpoint, {
method: 'POST',
headers: { Authorization: `Bearer ${authToken}` },
body: uploadForm,
});
const uploadResult = await uploadResponse.json();
if (uploadResult.errors?.length) {
throw new Error(`Upload failed: ${uploadResult.errors[0].message}`);
}
const filePath = uploadResult.data?.uploadFile?.path;
if (!filePath) {
throw new Error('No file path returned from upload');
}
// Step 3: Create the attachment linked to the company
const attachmentMutation = `
mutation CreateAttachment($data: AttachmentCreateInput!) {
createAttachment(data: $data) {
id
name
}
}
`;
const attachmentResponse = await fetch(graphqlEndpoint, {
method: 'POST',
headers: {
Authorization: `Bearer ${authToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: attachmentMutation,
variables: {
data: {
name: filename,
fullPath: filePath,
companyId,
},
},
}),
});
const attachmentResult = await attachmentResponse.json();
if (attachmentResult.errors?.length) {
throw new Error(`Attachment creation failed: ${attachmentResult.errors[0].message}`);
}
return attachmentResult.data?.createAttachment;
};
```
### Step 3: Customize for Your Use Case
#### To attach to a different object
Replace `companyId` with the appropriate field:
| Object | Field Name |
|--------|------------|
| Company | `companyId` |
| Person | `personId` |
| Opportunity | `opportunityId` |
| Custom Object | `yourCustomObjectId` |
Update both the function parameter and the `variables.data` object in the attachment mutation.
#### To use a dynamic PDF URL
If using a PDF generation service, you can:
1. First make an HTTP Request action to generate the PDF
2. Pass the returned PDF URL to the serverless function as a parameter
```typescript
export const main = async (
params: { companyId: string; pdfUrl: string; filename: string },
) => {
const { companyId, pdfUrl, filename } = params;
// ... rest of the function
};
```
### Step 4: Test and Activate
1. Save the workflow
2. Navigate to a Company record
3. Click the **⋮** menu and select your workflow
4. Check the **Attachments** section on the record to verify the PDF was attached
5. Activate the workflow
## Combining with PDF Generation Services
For creating dynamic quotes or invoices:
### Example: Generate Quote → Attach PDF
| Step | Action | Purpose |
|------|--------|---------|
| 1 | Manual Trigger (Company) | User initiates on a record |
| 2 | Search Record | Get Opportunity or line item details |
| 3 | HTTP Request | Call PDF generation API with record data |
| 4 | Serverless Function | Download and attach the generated PDF |
### Popular PDF Generation Services
- **Carbone** - Template-based document generation
- **PDFMonkey** - Dynamic PDF creation from templates
- **DocuSeal** - Document automation platform
- **Documint** - API-first document generation
Each service provides an API that returns a PDF URL, which you can then pass to the serverless function.
## Troubleshooting
| Issue | Solution |
|-------|----------|
| "Failed to download PDF" | Check the PDF URL is accessible and returns a valid PDF |
| "Upload failed" | Verify your API key is valid and has write permissions |
| "Attachment creation failed" | Ensure the object ID field name matches your target object |
## Related
- [Workflow Triggers](/user-guide/workflows/capabilities/workflow-triggers)
- [Serverless Functions](/user-guide/workflows/capabilities/workflow-actions#serverless-function)
- [Generate a Quote or Invoice from Twenty](/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty)
@@ -138,6 +138,7 @@ Body: {{code.invoice}}
## Related
- [Generate a PDF from Twenty](/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty) — attach generated PDFs to records
- [Workflow Triggers](/user-guide/workflows/capabilities/workflow-triggers)
- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions)
- [Closed Won Automations](/user-guide/workflows/how-tos/crm-automations/closed-won-automations)