Özel entegrasyonlarda dosya desteği
Özel aksiyonlarda ve tetikleyicilerde dosya girdilerini ve çıktılarını yönetin.
1. Aksiyonlarda dosya girişi
Dosya girdileri, kullanıcıların aksiyonunuzun işleyebileceği veya harici API'lere gönderebileceği dosyaları yüklemesine olanak tanır.
1.1 Dosya girdileri ne zaman kullanılır
- Harici araçlara dosya yükleme: Kullanıcıların yüklediği belgeleri API'lere, bulut depolamaya veya e-posta ya da bilet sistemleri gibi harici hizmetlere gönderin.
- Kullanıcı dosyalarını işleme: Kullanıcıların yüklediği dosyaları analiz edin, dönüştürün veya dönüşüme tabi tutun
1.2 Dosya giriş alanları ekleme
Tek dosya girişi
Tek bir dosya kabul etmek için "FILE" türünde bir giriş alanı ekleyin
Birden fazla dosya girişi
Birden fazla dosya için Allow multiple files seçeneğini etkinleştirin:
1.3 Kodda dosya verisine erişim
Yüklenen her dosya tam olarak şu biçimde bir FileData nesnesi olarak teslim edilir:
{
fileName: "Invoice.pdf",
mimeType: "application/pdf",
size: 102400, // bytes
base64: "JVBERi0xLjQK...", // binary content, Base64-encoded
lastModified: "2024-01-15T10:30:00Z" // ISO date string
}Önemli: Dosya girdileri
textözelliği içermez.textkısayolu yalnızca dosya çıktıları için vardır.
Tek dosyaya erişim
// 'document' in this example is the id of the created input field
const document = data.input.document; // FileData object
const buffer = Buffer.from(document.base64, "base64");
ld.log(`Processing ${document.fileName} (${document.size} bytes)`);Birden fazla dosyaya erişim
// 'attachments' in this example is the id of the created input field
const files = data.input.attachments; // FileData[] array
for (const file of files) {
const buffer = Buffer.from(file.base64, "base64");
await processFile(buffer, file.mimeType);
}Veri yapısı: "Allow multiple files" etkinleştirildiğinde
data.input.fieldNamebir dizidir. Aksi halde tek bir nesnedir.
1.4 Yaygın giriş kalıpları
// Gmail-style email with file attachments
const recipient = data.input.mailRecipient;
const subject = data.input.mailSubject;
const body = data.input.mailBody;
const attachments = data.input.attachments || [];
// Build multipart email
let email = `To: ${recipient}\r\nSubject: ${subject}\r\n`;
if (attachments.length > 0) {
const boundary = `boundary_${Date.now()}`;
email += `Content-Type: multipart/mixed; boundary="${boundary}"\r\n\r\n`;
email += `--${boundary}\r\nContent-Type: text/html\r\n\r\n${body}\r\n`;
// Add each attachment
for (const attachment of attachments) {
email += `--${boundary}\r\n`;
email += `Content-Type: ${attachment.mimeType}\r\n`;
email += `Content-Transfer-Encoding: base64\r\n`;
email += `Content-Disposition: attachment; filename="${attachment.fileName}"\r\n`;
email += `\r\n${attachment.base64}\r\n`;
}
email += `--${boundary}--`;
} const document = data.input.document;
// Validate file type
if (!document.mimeType.startsWith('application/pdf')) {
throw new Error('Only PDF files are supported');
}
try {
const response = await ld.request({
method: 'POST',
url: 'https://api.example.com/documents',
headers: {
'Authorization': `Bearer ${data.auth.apiKey}`,
'Content-Type': 'application/json'
},
body: {
filename: document.fileName,
content: document.base64,
mimeType: document.mimeType
}
});
return {
success: true,
documentId: response.json.id,
message: `Uploaded ${document.fileName} successfully`
};
} catch (error) {
return {
success: false,
error: `Failed to upload ${document.fileName}: ${error.message}`
};
} const files = data.input.files || [];
if (files.length === 0) {
return { error: 'No files provided' };
}
const results = [];
for (const file of files) {
try {
const buffer = Buffer.from(file.base64, 'base64');
// Process based on file type
let result;
if (file.mimeType.startsWith('image/')) {
result = await processImage(buffer);
} else if (file.mimeType === 'application/pdf') {
result = await processPDF(buffer);
} else {
throw new Error(`Unsupported file type: ${file.mimeType}`);
}
results.push({
filename: file.fileName,
status: 'success',
result: result
});
ld.log(`Processed ${file.fileName} successfully`);
} catch (error) {
results.push({
filename: file.fileName,
status: 'error',
error: error.message
});
ld.log(`Failed to process ${file.fileName}: ${error.message}`);
}
}
return {
success: true,
processed: results.filter(r => r.status === 'success').length,
failed: results.filter(r => r.status === 'error').length,
results: results
};1.5 Giriş doğrulama ve hata işleme
// Validate file presence
const files = data.input.attachments;
if (!files || files.length === 0) {
return { error: "No files provided. Please attach at least one file." };
}
// Validate file types
const allowedTypes = ["application/pdf", "image/jpeg", "image/png"];
for (const file of files) {
if (!allowedTypes.includes(file.mimeType)) {
return {
error: `Unsupported file type: ${
file.mimeType
}. Allowed: ${allowedTypes.join(", ")}`,
};
}
}
// Log file metadata for debugging
ld.log(
"Processing files:",
files.map((f) => ({
fileName: f.fileName,
mimeType: f.mimeType,
size: f.size,
}))
);2. Aksiyonlarda dosya çıktısı
Dosya çıktıları, aksiyonunuzun kullanıcıların indirebileceği veya sonraki aksiyonlarda kullanabileceği dosyalar üretmesine ve döndürmesine olanak tanır.
2.1 Dosya çıktıları ne zaman kullanılır
- Rapor üretme: Verilerden PDF, elektronik tablo veya belgeler oluşturma
- API'lerden dosya alma: Harici hizmetlerden dosya indirme
- Dosya dönüştürme: Biçimler arasında dönüştürme veya yüklenen dosyaları işleme
- Veri dışa aktarma: CSV dışa aktarımları, yedek dosyaları veya veri dökümleri oluşturma
2.2 Dosya çıktı biçimi
Yanıtınızda dosyaları bir files anahtarı altında döndürün:
// Single file output
return {
files: {
fileName: "report.pdf",
mimeType: "application/pdf",
base64: "JVBERi0xLjQK...", // Base64 encoded content
},
};
// Multiple files output
return {
files: [
{
fileName: "data.csv",
mimeType: "text/csv",
text: "Name,Email\nJohn,john@example.com", // Text shortcut for UTF-8
},
{
fileName: "chart.png",
mimeType: "image/png",
base64: "iVBORw0KGgoAAAANSUhEUgAA...",
},
],
};Dosya çıktı özellikleri
| Alan | Zorunlu | Notlar |
|---|---|---|
fileName | ✓ | Uygun dosya uzantısını ekleyin |
mimeType | ✓ | Doğru işleme için doğru MIME türü |
base64 | ✓\* | Base64 kodlanmış ikili içerik |
text | ✓\* | UTF-8 metin içerik (base64 alternatifi) |
lastModified | İsteğe bağlı | ISO tarih dizesi (varsayılan: geçerli zaman) |
\*Ya base64 YA DA text sağlayın, asla ikisini birden.
2.3 Yaygın çıktı kalıpları
// Generate a PDF report from data
const reportData = await fetchReportData();
// Create PDF content (using custom built function / endpoint)
const pdfBuffer = await generatePDF({
title: 'Monthly Report',
data: reportData,
template: 'standard'
});
return {
files: {
fileName: `monthly-report-${new Date().toISOString().slice(0,7)}.pdf`,
mimeType: 'application/pdf',
base64: pdfBuffer.toString('base64')
},
success: true,
message: `Generated report with ${reportData.length} entries`
}; // Export data as CSV using text shortcut
const customers = await fetchCustomers();
// Build CSV content
const csvHeader = 'Name,Email,Created,Status';
const csvRows = customers.map(c =>
`"${c.name}","${c.email}","${c.created}","${c.status}"`
);
const csvContent = [csvHeader, ...csvRows].join('\n');
return {
files: {
fileName: `customers-export-${new Date().toISOString().slice(0,10)}.csv`,
mimeType: 'text/csv',
text: csvContent // Use text for UTF-8 content
},
success: true,
exported: customers.length
}; // Download file from external API
const fileId = data.input.fileId;
try {
const response = await ld.request({
method: 'GET',
url: `https://api.example.com/files/${fileId}`,
headers: {
'Authorization': `Bearer ${data.auth.apiKey}`
},
responseType: 'stream'
});
// Get filename from response headers or API
const filename = response.headers['content-disposition']
?.match(/filename="(.+)"/)?.[1] || `file-${fileId}`;
return {
files: {
fileName: filename,
mimeType: response.headers['content-type'] || 'application/octet-stream',
base64: Buffer.from(response.buffer).toString('base64')
},
success: true,
message: `Downloaded ${filename}`
};
} catch (error) {
return {
success: false,
error: `Failed to download file: ${error.message}`
};
} // Process input files and return modified versions
const inputFiles = data.input.documents || [];
const outputFiles = [];
for (const file of inputFiles) {
try {
const buffer = Buffer.from(file.base64, 'base64');
// Process file (e.g., compress, convert, etc.)
const processedBuffer = await processFile(buffer, file.mimeType);
outputFiles.push({
fileName: `processed-${file.fileName}`,
mimeType: file.mimeType,
base64: processedBuffer.toString('base64')
});
} catch (error) {
ld.log(`Failed to process ${file.fileName}: ${error.message}`);
}
}
return {
files: outputFiles,
success: true,
processed: outputFiles.length,
message: `Processed ${outputFiles.length} of ${inputFiles.length} files`
};3. Tetikleyicilerde dosya çıktısı
Tetikleyiciler, dosya eki içeren olayları algıladıklarında veya tetikleyici verilerine dayalı dosyalar ürettiklerinde de dosya döndürebilir.
Temel fark: Doğrudan nesne döndüren aksiyonların aksine, tetikleyiciler bir olay dizisi döndürmelidir. Her olayın
id,timestampvedataözellikleri olmalı; dosyalardatanesnesinin içinde yer almalıdır.
3.1 Tetikleyicilerde dosya çıktıları ne zaman kullanılır
- E-posta ekleri: Gelen e-postalardaki ekleri iletme
- Dosya değişiklik olayları: İzlenen sistemlerden değiştirilmiş veya yeni dosyaları döndürme
- Üretilen bildirimler: Olaylar gerçekleştiğinde özet dosyaları veya raporlar oluşturma
- API webhook dosyaları: Webhook yüklerinden dosyaları işleme ve iletme
3.2 Tetikleyici dosya çıktı biçimi
Tetikleyiciler id, timestamp ve data özelliklerine sahip bir nesne dizisi döndürmelidir. Dosyalar data nesnesinin içinde yer alır:
// Required trigger format with files
return [
{
id: "msg_123", // Unique identifier for this event
timestamp: "2024-01-15T10:30:00Z", // Event timestamp
data: {
from: "sender@example.com",
subject: "Invoice #12345",
body: "Please find the invoice attached.",
messageId: "msg_123",
files: [
// Files go INSIDE data object
{
fileName: "invoice-12345.pdf",
mimeType: "application/pdf",
base64: "JVBERi0xLjQK...",
},
],
},
},
];Önemli: Aksiyonlardan farklı olarak tetikleyiciler bir olay dizisi döndürmelidir ve
filesüst düzeyde değil,datanesnesinin içinde olmalıdır.
3.3 Yaygın tetikleyici kalıpları
// Gmail trigger processing incoming emails
const emails = await fetchNewEmails();
const results = [];
for (const email of emails) {
const attachments = [];
// Process email attachments if any
if (email.attachments && email.attachments.length > 0) {
for (const attachment of email.attachments) {
// Download attachment content
const content = await downloadAttachment(attachment.id);
attachments.push({
fileName: attachment.filename,
mimeType: attachment.mimeType,
base64: content.toString('base64')
});
}
}
results.push({
id: email.id, // Required: unique event ID
timestamp: email.date, // Required: event timestamp
data: {
from: email.from,
subject: email.subject,
body: email.body,
receivedAt: email.date,
messageId: email.id,
threadId: email.threadId,
files: attachments // Files inside data object
}
});
}
return results; // Return array of trigger events // Monitor for new files in a directory
const newFiles = await checkForNewFiles(data.input.directory);
const results = [];
for (const file of newFiles) {
try {
// Download file content
const content = await downloadFile(file.path);
results.push({
id: file.id || file.path, // Required: unique file identifier
timestamp: file.lastModified, // Required: event timestamp
data: {
filePath: file.path,
fileName: file.name,
size: file.size,
modifiedAt: file.lastModified,
event: 'file_created',
files: [ // Files array inside data object
{
fileName: file.name,
mimeType: file.mimeType || 'application/octet-stream',
base64: content.toString('base64')
}
]
}
});
} catch (error) {
ld.log(`Failed to process file ${file.name}: ${error.message}`);
}
}
return results; // Return array of trigger events4. Platform kısıtlamaları ve limitler
| Kısıtlama | Limit |
|---|---|
| Aksiyon başına toplam dosya boyutu | 100 MB |
| Aksiyon başına maksimum dosya | 20 dosya |
| Tekil belgeler | ≤ 256 MB\* |
| Tekil görseller | ≤ 20 MB |
| Tekil elektronik tablolar | ≤ 100 MB |
| Tekil ses dosyaları | ≤ 200 MB\* |
| Tekil video dosyaları | ≤ 100 MB |
| Diğer dosya türleri | ≤ 256 MB\* |
| Aksiyon yürütme zaman aşımı | 2 dakika |
\*Hâlâ 100 MB toplam limitiyle sınırlıdır.
Doğrulama: Limitlerin aşılması, kodunuz çalışmadan önce bir hata fırlatır.
{
"error": "Total file size (120.0 MB) exceeds the action execution limit of 100.0 MB. Please use smaller files or reduce the number of files."
}4.1 Sandbox kitaplık kısıtlamaları
Özel aksiyon ve tetikleyici kodu güvenli bir sandbox ortamında çalışır.\ npm veya pip paketleri gibi harici kitaplıkları yükleyemez veya içe aktaramazsınız. Yalnızca sınırlı bir yerleşik JavaScript ve Node.js API kümesi kullanılabilir.\ Gelişmiş dosya işleme için (ör. PDF ayrıştırma, görsel manipülasyonu) harici API'leri veya hizmetleri kullanın ve bunları kodunuzdan çağırın.
5. En iyi uygulamalar
Dosya girişi en iyi uygulamaları
- Dosya türlerini erken doğrulayın: İşlemeden önce MIME türlerini kontrol edin
- Eksik dosyaları zarifçe işleyin: İsteğe bağlı dosya dizileri için
|| []kullanın - Dosya meta verisini günlüğe yazın: İçeriği açığa çıkarmadan sorunları ayıklamaya yardımcı olun
- Net hata mesajları sağlayın: Kullanıcılara tam olarak neyin yanlış gittiğini söyleyin
// Good validation pattern
const files = data.input.attachments || [];
if (files.length === 0) {
return { error: "Please attach at least one file to process." };
}
const allowedTypes = ["image/jpeg", "image/png", "application/pdf"];
for (const file of files) {
if (!allowedTypes.includes(file.mimeType)) {
return {
error: `File "${file.fileName}" has unsupported type ${
file.mimeType
}. Allowed: ${allowedTypes.join(", ")}`,
};
}
}Dosya çıktısı en iyi uygulamaları
- Anlamlı dosya adları kullanın: Tarih, kimlik veya açıklayıcı adlar ekleyin
- Doğru MIME türleri ayarlayın: Doğru dosya işleme ve önizlemeleri sağlar
- UTF-8 için text kısayolunu kullanın: Metin dosyaları için base64'ten daha verimlidir
- İşleme durumunu ekleyin: Kullanıcıların ne olduğunu anlamasına yardımcı olun
// Good output pattern
return {
files: {
fileName: `customer-report-${new Date().toISOString().slice(0, 10)}.pdf`,
mimeType: "application/pdf",
base64: reportBuffer.toString("base64"),
},
success: true,
recordsProcessed: customerData.length,
message: `Generated report with ${customerData.length} customer records`,
};Performans en iyi uygulamaları
- Mümkün olduğunda dosyaları paralel işleyin: Bağımsız işlemler için
Promise.all()kullanın - Tüm dosyaları belleğe yüklemekten kaçının: Büyük toplu işlemlerde birer birer işleyin
- İlerlemeyi günlüğe yazın: İşleme durumunu izlemek için
ld.log()kullanın - Hataları zarifçe işleyin: Biri başarısız olursa diğer dosyaları işlemeye devam edin
// Good error handling pattern
const results = [];
for (const file of files) {
try {
const result = await processFile(file);
results.push({ fileName: file.fileName, status: "success", result });
ld.log(`✓ Processed ${file.fileName}`);
} catch (error) {
results.push({
fileName: file.fileName,
status: "error",
error: error.message,
});
ld.log(`✗ Failed ${file.fileName}: ${error.message}`);
}
}6. Sorun giderme
| Sorun | Olası neden | Çözüm |
|---|---|---|
| "File not found" | Kullanıcı dosya eklemedi | Dosya girişini zorunlu yapın veya doğrulama ekleyin |
| Boyut limiti hatası | Dosyalar toplam 100 MB'ı aşıyor | Daha küçük veya daha az dosya isteyin |
| "Invalid file type" | Yanlış MIME türü | Kodunuzda file.mimeType doğrulayın |
| Boş dosya içeriği | Base64 kodlama sorunu | file.base64 değerinin geçerli olduğunu doğrulayın |
| Zaman aşımı hataları | Büyük dosyalar veya yavaş işleme | İşlemeyi optimize edin veya dosya boyutlarını küçültün |
| Bellek hataları | Çok fazla büyük dosya | Dosyaları paralel değil, sırayla işleyin |
Hata ayıklama yardımcısı
// Safe logging for file metadata (never logs content)
function logFileInfo(files) {
const fileInfo = Array.isArray(files) ? files : [files];
ld.log(
"File info:",
fileInfo.map((f) => ({
fileName: f.fileName,
mimeType: f.mimeType,
size: f.size,
hasBase64: !!f.base64,
hasText: !!f.text, // Only exists for outputs
}))
);
}SSS
Harici aksiyonun belge veya ikili varlıkları yüklemesi, indirmesi, dönüştürmesi veya döndürmesi gerektiğinde dosya desteğini kullanın. Aksiyon yalnızca metin veya meta veriye ihtiyaç duyuyorsa normal yapılandırılmış bir giriş genellikle daha basittir.
Dosya boyutunu, türünü, kodlamasını, giriş alanı yapılandırmasını ve harici API'nin multipart yükleme, URL, base64 veri veya başka bir biçim bekleyip beklemediğini kontrol edin.