How to download a file by URL and save as attachment?
Sometimes you need to download a file from an external URL and attach it to your record. This could be useful for automatically downloading images, documents, or other files referenced by URLs stored in your app.
This guide shows you how to create an action that downloads a file from a URL and saves it as an attachment to your record.
Overview
The process involves:
- getting the file URL (from a field or using a default)
- using the RestApi to download the file
- persisting the downloaded file
- adding it to the record's attachments list
Implementation
In your actions/logic/index.ts
file, add the following action function and export it. You can either create a new action called test_download_image
or add this code to an existing action like add
or edit
:
import { entity } from "#typings";
import { Files, RestApi } from "@comind/api/server";
function test_download_image() {
// Default file URL if none is provided
const defaultImageToDownload = "https://accounts.comindwork.com/logo.png";
// Get the URL from a field (c_file_url) or use default
const fileUrl = entity.c_file_url || defaultImageToDownload;
// Extract filename from URL, fallback to default name
const fileName = fileUrl.split("/").pop() || "downloaded_file.png";
// Create REST client and download the file
RestApi.createClient(fileUrl);
RestApi.createRequest("", "GET");
// Optional:
// RestApi.addHeader('Authorization', 'Bearer ' + SOME_AUTH_TOKEN);
const res = RestApi.downloadFile();
// Check if download was successful
const isOk =
res?.statusCode === 200 && res?.downloadedFileRef && res?.contentLength > 0;
if (!isOk) {
throw `Failed to download file: ${fileUrl} / ${JSON.stringify(res)}`;
}
// Persist the downloaded file
const storedFile = Files.persistFileRef(res.downloadedFileRef);
// Initialize attachments list if it doesn't exist
entity.attachments__list ??= [];
// Add the file to attachments
entity.attachments__list.push({
file_uid: storedFile.uploadedFileId,
title: fileName,
});
}
export default {
test_download_image,
// ... other actions
} satisfies ActionLogic<typeof entity>;
How it works
-
URL source: the action gets the file URL from the
c_file_url
field. If this field is empty, it uses a default URL. -
File download: the
RestApi.downloadFile()
method downloads the file and returns a response object containing:statusCode
- HTTP status codedownloadedFileRef
- reference to the downloaded filecontentLength
- size of the downloaded file
-
Error handling: the action checks if the download was successful by verifying the status code is 200 and that file reference and content length are present.
-
File persistence: the
Files.persistFileRef()
method saves the downloaded file to the system and returns an object withuploadedFileId
. -
Attachment: the file is added to the record's attachments list with the extracted filename as the title.
Authorization
If the file URL requires authentication, you can add authorization headers before downloading:
RestApi.addHeader("Authorization", "Bearer " + SOME_AUTH_TOKEN);
This is useful when downloading files from:
- protected APIs that require API keys
- services that need bearer tokens
- endpoints requiring custom authentication headers
Field requirements
For this action to work, ensure your app has:
- a text field named
c_file_url
(or modify the field name in the code) - an attachments list field named
attachments__list
Error handling
The action includes basic error handling:
- throws an error if the download fails
- provides details about the failure including the URL and response
Customization options
You can customize this action by:
- Changing the URL source: modify
entity.c_file_url
to use a different field - Custom filename: instead of extracting from URL, you could use a separate field for the filename
- File validation: add checks for file type, size, or other criteria before downloading
- Multiple URLs: extend to download multiple files from a list of URLs
Example usage
- enter a file URL in the
c_file_url
field (e.g.,https://docs.comind.work/img/logo.png
orhttps://example.com/document.pdf
) - click the "Test Download Image" action button (or trigger the action from your existing action)
- the file will be downloaded and appear in the attachments list
This approach is particularly useful for:
- importing files from external systems
- automatically downloading referenced documents
- creating backups of external files
- bulk file imports from URL lists
Additional processing
Note that after downloading the file, you can also parse its content for further processing. This is especially useful for:
- Excel files: parse spreadsheet data and import rows into your app
- CSV files: process tabular data and create records automatically
- Text files: extract and analyze text content
- JSON/XML files: parse structured data and update related fields
- Images: extract metadata or perform image analysis
You can access the downloaded file content before persisting it, allowing you to read and process the file data as needed for your specific use case.