Skip to main content

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:

  1. getting the file URL (from a field or using a default)
  2. using the RestApi to download the file
  3. persisting the downloaded file
  4. 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

  1. URL source: the action gets the file URL from the c_file_url field. If this field is empty, it uses a default URL.

  2. File download: the RestApi.downloadFile() method downloads the file and returns a response object containing:

    • statusCode - HTTP status code
    • downloadedFileRef - reference to the downloaded file
    • contentLength - size of the downloaded file
  3. 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.

  4. File persistence: the Files.persistFileRef() method saves the downloaded file to the system and returns an object with uploadedFileId.

  5. 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

  1. enter a file URL in the c_file_url field (e.g., https://docs.comind.work/img/logo.png or https://example.com/document.pdf)
  2. click the "Test Download Image" action button (or trigger the action from your existing action)
  3. 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.

Video demonstration